Hallo Zusammen :)
ich muss von der Hochschule aus (Projekt) einen Temperaturregler mit
PID-Regelung programmieren (Entwicklungsumgebung TwinCAT 3 Beckhoff).
Allerdings habe ich von Regelungstechnik null Ahnung, da ich bisher nur
auf C, C++ und Python programmiert habe..
Ich habe eigentlich soweit alles programmiert, mein PID-Regler
funktioniert auch soweit (Funktionsblock FB_BasicPID). Nach langer
Internetrechere bin ich darauf zugestoßen, dass ich eine PWM
(Pulsweitenmodulation) anwenden muss.
Meine Frage wäre, wie definiere ich meine PWM und verbinde das mit dem
Ausgang meines PID-Reglers. Ich kann keine Max und Min Werte am Ausgang
festlegen, da sich dieswer Wert ständig ändert..
Nach der PID-Regelung muss ich nämlich mithilfe der PWM den
Solid-State-Relai steuern um die Heizung ein und ausschalten zu können,
damit ich meine Solltemperatur ereriche.
Wäre super, wenn mir jemand helfen könnte, da ich keine Ahnung habe, wie
ich das realisieren soll und ich gerade am verzweifeln bin.. :D
Vielen Dank schon mal :)
Mzo schrieb:> Ich kann keine Max und Min Werte am Ausgang> festlegen, da sich dieswer Wert ständig ändert..
Min und max ergibt sich ja schon durch die PWM (mögliche Pulsbreite
liegt im Bereich von 0%..100%), den Ausgang des PID Reglers musst du
eben in diesen Bereich skalieren und "clippen" (mehr als 100% geht
nicht, und deine Heizung kann auch nicht kühlen).
Da Heizungen in der Regel sehr träge sind, brauchst du mit der PWM
Frequenz auch nicht übertreiben (KHz sind hier sicher nicht angebracht).
Erstmal danke für deine Antwort :)
Okay verstehe, genau Kühlung habe ich nicht, ich muss nur die
Solltemperatur mit PID-Regelung erreichen und "halten" sozusagen.
Habe mal ein Bild hochgeladen, die markierten stellen sind Soll-&
Isttemperatur und der Ouptut vom PID-Regler.
Der Output steigt halt extrem, weil auch natürlich noch kein heizen
stattfindet.
Und wie genau muss ich diesen Wert dann skalieren und wie wende ich dann
die PWM hier an?
Solid-State Relais an einem PWM Ansteuersignal - warum?
Klar, PWM an sich sagt nichts über die Frequenz, und kann mir
vorstellen, dass man thermische Dinge über ein Relais regeln kann.
Trotzdem, macht mich das stutzig, ob das Konzept PWM->SS_Rleias wirklich
überdacht ist.
vor allem wegen diesem Satz
>Allerdings habe ich von Regelungstechnik null Ahnung, da ich bisher nur>auf C, C++ und Python programmiert habe..
Das sind einfach zwei verschiedene Lehrgebiete, die sich nicht
aussschließen.
Das wirkt, als ob Zusammenhänge nicht erfasst sind - daher auch die
Zweifel, ob das Konzept mit dem Relais und der PWM durchdacht ist.
Wie Joe F. schon schrieb, ist ein System mit Heizung relativ träge und
daher brauchst Du das Ganze nicht besonders aufwändig gestalten. Ich
würde das in etwa so machen:
1
VAR
2
uiPWMCount : UINT := 0;
3
uiPWMFrequency : UINT := 10000;
4
uiPWMDutyCycle : UINT := 0;
5
END_VAR
6
7
8
IF (uiPWMCount = 0) THEN
9
//Ausgang setzen
10
END_IF
11
12
IF (uiPWMCount = uiPWMDutyCycle) THEN
13
//Ausgang resetten
14
END_IF
15
16
uiPWMCount := uiPWMCount + 1;
17
18
IF (uiPWMCount = uiPWMFrequency) THEN
19
uiPWMCount := 0;
20
END_IF
uiPWMFrequncy legt die Frequenz der PWM fest. das sind 1 / Zykluszeit
der Task * uiPWMFrequency Hz.
uiPWMDutyCycle bestimmt den Duty-Cycle, wobei du diesen Wert auf 0 <=
uiPWMDutyCycle <= uiPWMFrequency begrenzen und natürlich skalieren
musst.
Das Ganze zyklisch aufrufen.
gl&hf!
Wenn das ganze mit Netzfrequenz läuft, kann man auch 50 Hz als PWM
Frequenz wählen (Mein Herd macht das mittlerweile auch so). Die
Zykluszeit für eine 8 Bit PWM ist dann bei etwa 5 Sekunden - träge genug
für eine Heizung.
Allerdings sagt mir
Mzo schrieb:> Entwicklungsumgebung TwinCAT 3 Beckhoff
gar nichts.
> Allerdings sagt mir> Mzo schrieb:>> Entwicklungsumgebung TwinCAT 3 Beckhoff> gar nichts.
Ist praktisch das Gleiche wie CODESYS, eine komplette IEC 61131-3
Entwicklungsumgebung+Laufzeitsystem für viele SPS. TC3 ist halt exclusiv
für Beckhoff-Steuerungen.
Matthias S. schrieb:> Wenn das ganze mit Netzfrequenz läuft, kann man auch 50 Hz als PWM> Frequenz wählen (Mein Herd macht das mittlerweile auch so). Die> Zykluszeit für eine 8 Bit PWM ist dann bei etwa 5 Sekunden - träge genug> für eine Heizung.
ist ne relaitv gute Idee, nur sollte man dann im Nulldurchgang schalten,
gibt weniger Verlust und weniger EMV Probleme. mti nem zero cross SSR
muss man nichts selber machen, und da es Halbleiter sind machen dem die
paar Schaltvorgänge nichts aus.
Mzo schrieb:> Und wie genau muss ich diesen Wert dann skalieren und wie wende ich dann> die PWM hier an?
du findest Minimum (0, bzw. Ausgabewert wenn Temperaturdifferenz Null
ist) und maximum deiner PID Ausgabe und skalierst das auf 0-100% bzw.
für ne 8bit PWM auf 0-255. fertig. Das maximum bestimmst du (da der I
term 0 ist) indem du dan PID Ausgabewert nimmst, bei dem du die beiden
Temperaturen so einstellst das du meinst dass 100% Heizen gut sind.
Alles darüber wird auf 100% abgeschnitten.
Matthias S. schrieb:> Allerdings sagt mir> Mzo schrieb:>> Entwicklungsumgebung TwinCAT 3 Beckhoff> gar nichts.
mir auch nicht. gibt es PWM Blöcke?
Mzo schrieb:> Ich habe eigentlich soweit alles programmiert, mein PID-Regler> funktioniert auch soweit (Funktionsblock FB_BasicPID).
Sicher dass er gut funktioniert? woran machst du das fest? du hast noch
garnicht die Ganze Regelschleife, sicher dass die PID nicht schwingt
oder langsam ist?
K. S. schrieb:> ist ne relaitv gute Idee, nur sollte man dann im Nulldurchgang schalten,> gibt weniger Verlust und weniger EMV Probleme.
In menem Herd benutze ich Triacs mit MOC3063, da ist der Nulldurchgang
gewährleistet. Der PWM Timer wird mit 50Hz vom Printtrafo getaktet.
Obwohl da im Worst Case etwa 2500W (ist nur ein Zweiflammer) geschaltet
werden, sind Netzstörungen nicht zu bemerken oder zu messen.
Wimre benutze ich allerdings nur einen CTC Count von 64, um die Zyklen
auf knapp über eine Sekunde zu bringen, wie das z.B. Induktionsherde
auch machen.
K. S. schrieb:> ist ne relaitv gute Idee, nur sollte man dann im Nulldurchgang schalten
Muss man sogar, denn ansonsten macht es einen Unterschied in der
Heizleistung, an welcher Stelle des Sinuses die PWM ihre on_time hat
(vorausgesetzt die Heizung wird überhaupt mit AC/Netzspannung
betrieben).
Alternative wäre Wellenpakete zu nehmen. Über 1 Sekunde hätte man so 50
Regelstufen.
Mzo schrieb:> Der Output steigt halt extrem, weil auch natürlich noch kein heizen> stattfindet.
Und weil auch kein Input-Signal von einem Sensor vorliegt.
> Und wie genau muss ich diesen Wert dann skalieren und wie wende ich dann> die PWM hier an?
Das ist die eigentliche Arbeit beim Abstimmen eines PID Reglers.
Der Output-Wert könnte z.B. direkt der PWM Wert sein, in deinem Beispiel
hier wären das 669% -> clipping auf 0..100 -> 100%
Wenn das zu viel ist und der Regler instabil ist, spielst du mit den
Koeffizienten rum (kleinere Kp, Tv).
Den Integralanteil hast du ja momentan bei 0, und damit würde ich es
auch erstmal belassen (für eine Temperaturregelung).
Um den Regler abzustimmen brauchst du aber die reale Hardware
(Sensor/Heizung), oder ein realistisches Modell davon (schwierig zu
machen...)
Guten Morgen zusammen,
vielen Dank für eure Hilfe und Antworten.
Jetzt habe ich bisschen Ahnung, wie ich das ganze angehen könnte.
Vielleicht schreibe ich kurz wie ich bisher programmiert habe, da viele
Fragen aufgetaucht sind.
den Sollwert und die PID-Werte (fKp,fTn,fTv) habe ich als globale
Variablen definiert. In einem Funktionsblock werden diese Werte dem
Funktionsblock FB_BasicPID übergeben. Den aktuellen Istwert zwacke ich
mit einem PT100 Temperatursensonr über die Klemme ab und übergebe diese
genauso dem Funktionsblock. Die Zykluszeit habe ich dem Task-Zyklus
angepasst (10000ms).
Im Main Programm rufe ich eigentlich nur den Funktionsblock auf, sprich
die komplette Implementierung findet momentan im Funktionsblock statt.
I-Anteil ist bei mir vorerst auf 0 definiert und schaltet sich erst im
Nachhinein zu (Bei +- 5°).
Wenn ich jetzt mein Programm starte ist der Output vom PID ca. bei 300
und steigt stetig in Sekundentakt (Normal weil noch kein heizen
stattfindet).
Mein Problem ist jetzt: Die Logik der PWM habe ich jetzt verstanden.
Auch den Code von Thomas S. (Danke dafür). Doch von welchem max. Wert
muss ich ausgehen um skallieren zz können, wenn ich keinen festen Wert
habe?
Kann ich da einfach 8bit oder 9bit PWM anwenden und 255 oder 512 als
max.Wert nehmen?
Mzo schrieb:> Kann ich da einfach 8bit oder 9bit PWM anwenden und 255 oder 512 als> max.Wert nehmen?
Genau. 128-bit, 64-bit würden auch schon reichen für eine Heizung.
Mzo schrieb:> Die Zykluszeit habe ich dem Task-Zyklus> angepasst (10000ms).
Den Wert 10000 habe ich mehr oder weniger willkürlich rein geschrieben.
Bei einer Taskzykluszeit von standardmäßig 20ms ergibt sich daraus eine
PWM-Zeit von 200 Sekunden bzw. 0,005Hz. Bist Du dir sicher, dass du eine
so niedrige Frequenz willst? Oder hast Du am Ende die Zykluszeit der
Task auf 10000ms gesetzt? Ich bin mir nicht ganz sicher ob Du weißt was
Du da einstellst.
> Mein Problem ist jetzt: Die Logik der PWM habe ich jetzt verstanden.> Auch den Code von Thomas S. (Danke dafür). Doch von welchem max. Wert> muss ich ausgehen um skallieren zz können, wenn ich keinen festen Wert> habe?
Da der Wert des Reglerausgangs immer weiter steigen wird ist der
Max-Wert wohl unendlich.
>> Kann ich da einfach 8bit oder 9bit PWM anwenden und 255 oder 512 als> max.Wert nehmen?
Klar, setze einfach uiPWMFrequency auf 255 oder 512 und gib deinen
Reglerwert (natürlich begrenzt) nach uiPWMDutyCycle über.
bei uiPWMFrequency = 512 und einer Task-Zykluszeit von 20ms gibt das
eine PWM-Zyklusdauer von 10,24sec bzw. eine Frequenz von ca. 0,1Hz. Das
sollte für eine Heizung passend dsein.
Joe F. schrieb:> Mzo schrieb:>> Kann ich da einfach 8bit oder 9bit PWM anwenden und 255 oder 512 als>> max.Wert nehmen?>> Genau. 128-bit, 64-bit würden auch schon reichen für eine Heizung.
Ich weiß ja nicht ob es nur einfach noch zu früh am Morgen ist oder du
hier Verwirrung stiften willst. doch Dein letzter Satz lässt mich fast
schon das berühmte Filmzitat aus dem Film "Billy Madison" zitieren.
@Mzo:
Mein Beispielcode enthält im übrigen einen (nicht gravierenden) Fehler.
Der sollte Dir eigentlich schon auffallen. Doch hier im Forum gibts
leider/gottseidank nur Hilfe zur Selbsthilfe (zumindest von mir).
Thomas S. schrieb:> Ich weiß ja nicht ob es nur einfach noch zu früh am Morgen ist
Trifft nicht zu.
> oder du> hier Verwirrung stiften willst.
Trifft auch nicht zu.
> doch Dein letzter Satz lässt mich fast> schon das berühmte Filmzitat aus dem Film "Billy Madison" zitieren.
So berühmt kann das Zitat nicht sein, denn ich habe keine Ahnung was du
mir sagen möchtest.
Wenn es darum geht, dass du nicht verstehst, was ich sagen wollte,
möchte ich es gerne präzisieren:
Die PWM-Auflösung kann für die dargestellte Regelungs-Aufgabe auch
deutlich kleiner als 8-bit sein.
Thomas S. schrieb:> Youtube-Video ""Everyone Is Now Dumber" - Billy Madison"
Ja, naja.
Ob das unbedingt die richtige Art ist einen auf einen kleinen Fehler
aufmerksam zu machen weiss ich ja nicht.
Ich halte es für eher unfreundlich und unverschämt.
Um es mit Billy Madisons Worten zu sagen:
"A simple 'wrong' would've done just fine"
Joe F. schrieb:> Ich halte es für eher unfreundlich und unverschämt.
Kann schon sein, wenn die eigene Dünnhäutigkeit Selbstironie und
Sarkasmus nicht zulässt. Willkommen in der Welt der Memes!
> Um es mit Billy Madisons Worten zu sagen:> "A simple 'wrong' would've done just fine"
q.e.d.
Thomas S. schrieb:> wenn die eigene Dünnhäutigkeit Selbstironie und> Sarkasmus nicht zulässt.
Da verwechselst du etwas.
Du dummes, kleines Sackgesicht. Dein Pimmel ist kleiner als der eines
Mückenmännchens und deine Mutter stinkt sogar auf Fotos.
Na? Wie ist es jetzt mit deiner Fähigkeit zur Selbstironie bestellt?
Joe F. schrieb:> Du dummes, kleines Sackgesicht. Dein Pimmel ist kleiner als der eines> Mückenmännchens und deine Mutter stinkt sogar auf Fotos.> Na? Wie ist es jetzt mit deiner Fähigkeit zur Selbstironie bestellt?
Eiche? Wildsau?
Thomas S. schrieb:> Eiche? Wildsau?
Hm, wenig originell, aber OK. Lass uns mit dem rumalbern aufhören, es
geht ja hier schließlich um technische Dinge.
Gelöschte Posts machen einen Thread immer sehr unansehnlich.
Joe F. schrieb:> Hm, wenig originell, aber OK.
Die Wahrheit ist meist wenig originell. Zumindest für den, der diese
nicht hören will.
> Lass uns mit dem rumalbern aufhören, es> geht ja hier schließlich um technische Dinge.> Gelöschte Posts machen einen Thread immer sehr unansehnlich.
100% ACK.
Kaum nicht reingeschaut gehts hier ja zu :O
Danke Thomas für den Ansatz,
wie gesagt ich bin in der Umgebung "Regelungstechnik" recht neu,
deswegen fallt es mir nicht so leicht zu programmieren momentan.
Ich werde auf jeden Fall mal versuchen, meine Werte zu skalieren und den
Code so umzusetzen wie du es beschrieben hast.
Danke nochmal :)
Hallo Zusammen,
mittlerweile bin ich jetzt soweit, dass soweit alles klappt. Ich kann
auch die Heizung über SSR kontrollieren und heizen.
Nur meine PWM funktioniert irgendwie nicht so wie es soll. Entweder
bekomme ich Dauersignal und das Ding heizt vollpower oder ich bekomme
gar kein Signal.
Thomas S. schrieb:> uiPWMDutyCycle bestimmt den Duty-Cycle, wobei du diesen Wert auf 0 <=> uiPWMDutyCycle <= uiPWMFrequency begrenzen und natürlich skalieren> musst.
wie genau meinst du das Thomas, hast du da evtl Codebeispiel für mich,
wenn ich von einer uiPWMFrequency = 255 ausgehe?
Grüße
Muzaffer
Muzaffer S. schrieb:> Nur meine PWM funktioniert irgendwie nicht so wie es soll. Entweder> bekomme ich Dauersignal und das Ding heizt vollpower oder ich bekomme> gar kein Signal.
Welche PWM Freqeunz hast du denn ?
Schneller als die 4 Sekunden die die Flickergrenze vorschreiben ?
Muzaffer S. schrieb:> uiPWMFrequency = 255
Was auch immer das für eine Frequenz ergibt.
Hi...
mal ganz von Vorne, hoffe das hilft dir:
Dein PID Regler besitzt als Eingangsgröße:
- Solltemperatur
die Temperatur die du erreichen möchtest
- Isttemperatur
die aktuell gemessene Temperatur
- MinStellwert
minimaler Stellwert den der Regler am Ausgang einnehmen sollte
(ich würde dir empfehlen den Regler so zu skalieren, dass der Ausgang
seinen Stellwert "prozentual" ausgibt, so bist du für alle
Eventualitäten gewappnet)
Hier also 0[%]
- MaxStellwert
maximaler Stellwert den der Regler am Ausgang einnehmen sollte
hier entweder 100[%] oder wenn deien Heizung etwas zu stark für deine
Anwendung ist könntest du mit diesem Parameter die Heitzung in ihrer
Ausgangsleistung begrenzen.
- P-Anteil
- I-Anteil
(D lassen wir mal weg weil ohnehin zu träge)
Diesen PI-Regler würde ich als eigenständigen Baustein in Codesys
Programmieren.
Die Bausteine aus der OSCAT Lib sind durchaus zu empfehlen, oft ist die
Skalierung und Anpassung aber mit sehr hohem Aufwand verbunden. Eine
Temperaturregelung mit PWM ist so träge, dass der Regler auch weitaus
unspektakülärer aussehen kann wie die Regler in der Lib.
Falls du den Regler mit ST schreiben willst hier mal ein Beispiel von
mir:
ariablen:
PI_out Output 0.0 Float REAL Standard Read/Write 0
P_part Local 0.0 Float REAL Standard None 0
P_Gain Input 0.0 Float REAL Standard Read/Write 0
output_value_ramp Local 0.0 Float REAL Standard Read/Write 0
output_value Local 0.0 Float REAL Standard None 0
Out_min Input 0.0 Float REAL Standard Read/Write 0
Out_max Input 0.0 Float REAL Standard Read/Write 0
limit_on_low Local 0 Decimal BOOL Standard None 0
limit_on_high Local 0 Decimal BOOL Standard None 0
I_Time Input 0.0 Float REAL Standard Read/Write 0
I_Reset Input 0 Decimal BOOL Standard Read/Write 0
I_Part_Zw_Summe Local 0.0 Float REAL Standard None 0
I_part Local 0.0 Float REAL Standard None 0
EnableOut Output 0 Decimal BOOL Standard Enable Output - System
Defined Parameter Read Only 0
EnableIn Input 1 Decimal BOOL Standard Enable Input - System
Defined Parameter Read Only 0
delta_input_last_cycle Local 0.0 Float REAL Standard None 0
delta_input Local 0.0 Float REAL Standard None 0
cycle_time Input 0.0 Float REAL Standard Read/Write 0
control_value Input 0.0 Float REAL Standard Read/Write 0
actaul_vaule Input 0.0 Float REAL Standard Read/Write 0
################PI-Control-light##########################
//Regeldifferenz berechnen
delta_input := (control_value - actaul_vaule);
//P-Regler beschreiben
P_part := delta_input * P_Gain;
//I_Regler beschreiben
if I_Time > 0 then
I_Part_Zw_Summe := ((((delta_input * P_Gain) + (delta_input_last_cycle
* P_Gain)) / 2.0) * (cycle_time / I_Time));
if not limit_on_low and (I_Part_Zw_Summe <0) then
I_part := I_part + I_Part_Zw_Summe;
elsif not limit_on_high and (I_Part_Zw_Summe >0) then
I_part := I_part + I_Part_Zw_Summe;
end_IF;
elsif I_Time <= 0.0 then
I_part := 0.0;
end_if;
//I_Regler zurück setzen
if I_Reset then
I_part := 0.0;
end_if;
output_value := P_part + I_part;
limit_on_low := 0;
limit_on_high := 0;
if output_value > Out_max then
output_value := Out_max;
limit_on_high := 1;
elsif output_value < Out_min then
output_value := Out_min;
limit_on_low := 1;
end_if;
PI_out := output_value;
//Regeldifferenz für nächsten Zyklus beschreiben
delta_input_last_cycle := delta_input;
Aus diesem Baustein sollte also ein REAL Wert rauskommen der Werte
zwischen 0 und 100% annehmen kann.
Danach geht's in den PWM Baustein:
Hier gibst du als Eingangsgröße ein "PWM-Duty_Cycle" an:
Dieser Duty Cycle gibt die Geamte PWM Zeit an, also wie lange die
Impulszeit des Heizens bei 100% sein soll:
Als gutes Beispiel wären hier z.B. 10Sekunden möglich:
Ist der Stellwert aus dem PID Regler 10% würde das bedeuten, die Heizung
ist 1Sek. an, 9 Sek. aus.
Diesen Baustein zu Programmieren ist auch relativ einfach wenn du die
Aufrufzeit des Bausteins weist.
Bespiele für Codesys hätte ich bei Bedarf.
Das war schon :-)
Soo, Hallo nochmal,
Tut mir leid für die späte Rückmeldung, war ziemlich angeschlagen und
lag im Krankenhaus..
Hanna schrieb:> Falls du den Regler mit ST schreiben willst hier mal ein Beispiel von> mir:
Vielen Dank für deine Hilfe ich glaube ich muss mein Programm auch so
umsetzen, da ich die freie Bibliothek FB_BasicPID von Twincat benutzt
habe, hat soweit geklappt, nur ich brauch unbedingt eine PWM, damit ich
den Solid State bedienen kann für die Temperaturerhöhung, doch dieses FB
hat keine Stellwerte und ich tu mich extrem schwer für die PWM des
Output zu skallieren.
Hanna schrieb:> (D lassen wir mal weg weil ohnehin zu träge)
Also mir wurde aber vorgeschrieben im Projekt, dass ich auch D-Anteil
beachten soll. Ich gebe also zur Regelung kP, ki und kd über.
Wie muss ich dann den D-Anteil im Code bachten?
Noch eine Frage, soll ich den PID-Regler und PWM jeweils in einem
Funktionsblock oder Programm implementieren und im Main dann einfach
aufrufen?
Vielen Dank schon mal im Voraus :) :)