Hallo,
kann sich villeicht jemand mal meine nachfolgende Realisierung eines
PI-Reglers in Festkommaarithmetik anschauen und mir sagen wo noch
Verbesserunsgpotentiale oder auch Fehler sind?
Der Regler geht als Stellwert an eine 8bit PWM.
Insb. hab ich jetzt durch die vielen 16bit Variablen das Problem das
mein Programmspeicher fast voll ist. Wo kann ich noch einsparen?
Und wie sollte die Grenze für den Anti Wind-up des I-Anteils gewählt
werden?
Gruss
1
#define KP 1
2
#define KI 0
3
#define TA 0.1 //Abtastzeit 100ms
4
5
6
7
8
uint8_tpi_regler(int16_tregelabweichung)
9
{
10
int16_tp_anteil,i_anteil,pi_regler_output;
11
12
staticint16_tregelabweichung_summe=0;
13
14
regelabweichung=regelabweichung/8;//vom Format S(11,4) zu S(14,1)
15
16
//Bestimmung P-ANTEIL
17
p_anteil=(p_factor*regelabweichung)/2;
18
19
//Bestimmung I-ANTEIL
20
regelabweichung_summe+=regelabweichung;
21
22
23
//Begrenzung I-Anteil
24
if(regelabweichung_summe<0)
25
{
26
regelabweichung_summe=0;
27
}
28
29
if(regelabweichung_summe>(255*2))//Regelabweichung Summe im Format S(14,1)
>>mein Programmspeicher fast voll ist.>> #define TA 0.1 wird in diesem Ausschnitt zwar nicht benutzt,
aber landet die falsche floating point lib in deinem Hex?
Wie kann ich heraus finden ob dadurch die floating point lib eingebunden
wird?
Der P-Anteil funktioniert mal soweit. Beim I-Anteil bin ich mir nicht so
sicher. Desweitern tue ich mir auch gerade schwer die Regelparameter zu
bestimmen.
Hallo,
hab das ganze nun nochmal etwas überarbeitet. Und versuche nun die
Regelparameter zu ermitteln... Komme aber einfach nicht weiter und weiss
auch nicht richtig woran es liegen könnte.
Bei einem KP von 1 (KI=0) kommt das ganze ins Schwingen. Könnte
vielleicht der ein oder andere Reglungstechnik Profi hierzu was sagen?
Bzw. mir einen Anhaltspunkt geben mit welchem KP ich Anfangs beginnen
sollte?
Angeschlossen ist ein kleiner Heizstab und als Sensor kommt ein DS18B20
zum Einsatz. Der Outputwert des Reglers wird direkt als Stellwert für
die 8bit PWM genutzt.
Der Regler soll alle 100ms aufgerufen werden.
Ist die Realisierung meines Reglers nun so korrekt?
hier mein vollständiger Sourcecode:
Meier schrieb:> Bei einem KP von 1 (KI=0) kommt das ganze ins Schwingen. Könnte> vielleicht der ein oder andere Reglungstechnik Profi hierzu was sagen?> Bzw. mir einen Anhaltspunkt geben mit welchem KP ich Anfangs beginnen> sollte?
Du hast ja immerhin schonmal eine ?Sprungantwort? von deinem Aufbau. Da
gibt es zum Beispiel ein Tangentenverfahren um die einzelnen Parameter
ermitteln zu können. Ausprobieren ist auch eine Möglichkeit. Auf der
Roboternetz seite zum Thema Regelungstechnik wird dazu auch was erzählt,
also wie man durch ausprobieren auf gute Werte für die einzelnen
Parameter kommt.
http://www.rn-wissen.de/index.php/Regelungstechnik#Dimensionierung_des_Reglers
"Dimensionierung durch Probieren (Empirisches Einstellen)" ist genau das
was du dir durchlesen solltest. Wo dein System eh schon ein wenig
schwingt kannst auch mal schauen ob du auf ein brauchbares Ergebnis mit
Hilfe von "Einstellung nach der Schwingungsmethode" kommst, wird dort
ebenfalls recht gut erklärt.
Mit etwas Voraussicht oder Glueck hat der Controller eine verfuegbare
serielle Schnittstelle, die auch einen Treiber furt RS232 ode so
angeflanscht hat. Dann braucht man nur noch ein kleines Protokoll, das
erlaubt die Parameter zur Laufzeit zu verstellen.
Ueber die gleiche Schnittstelle kann man sich dann auch Werte von
interesse geben lassen. Alternativ kann man sich einen 4/8 fach DAC
anflanschen und die Werte ueber den DAC ausgeben, zum mit dem Scope
zuschauen.
Ohne so einen Ansatz wird's schwierig.
@ Morz Kerl
Hallo,
sowas ähnliches zumindest hab ich vorgesehen ;)
Die Werte oben sind direkt vom Controller ausgegeben worden (die in der
angehängten Grafik). Die Regler Parameter ändere ich direkt über die ISP
Schnittstelle.
Ich hab nur das Problem das mein System eigentlich bei jedem Wert von KP
schwingt. Und ich weiss auch nicht so Recht wie ich jetzt weiter
vorgehen soll... da ich eigentlich das Faustformelverfahren nutzen
wollte :(
Desweitern wäre es mir zunächst einmal sehr wichtig ob mein
PI-Controller Code so richtig realisiert ist insb. das mit dem Anti
Windup..
Hi,
>DS18B20 und>#define TA ((uint16_t)(0.1*SCALING_FACTOR)) //Abtastzeit 100ms
passt so garnicht weil fast 1 Sekunde vergeht ehe du einen neuen Wert
hast.
Solange KI=0 ist sollte aber nichts falsches rauskommen. Das dein Regler
aber ohne KI schon schwingt ist nicht ok, er sollte sich eigentlich
abhängig von KP etws unterhald des Sollwertes einregeln.
Dein Ganzer Code sieht irgendwie recht komisch aus, aber es ist schon
recht spät und ich acker das jetzt nicht durch.
Viel Erfolg, Uwe
hi Uwe,
der DS18B20 ist auf 9bit konfiguriert und braucht zur messung daher max.
93,75 ms...
Ich weiss echt wo das Problem liegen könnte, warum das ganz direkt
anfängt zu schwingen... Von daher wäre ich echt sehr dankbar wenn noch
jemand genauer drüber schauen könnte :(
Ratlos
if(regelabweichung_summe>(255*2))//Regelabweichung Summe im Format S(14,1)
7
{
8
regelabweichung_summe=(255*2);
9
}
erscheint mir nicht logisch.
Warum soll die Summe der Regelabweichungen nicht auch negativ werden
können? Dein I-Regler kann auf die Art niemals in die negative Richtung
korrigieren, sondern muss warten, bis der P-Anteil unterschwingt, so
dass die Summe wieder positiv wird und der I-Anteil den restlichen
Fehler ausregeln kann.
Danke für den Hinweis!
War mir irgendwie garnicht aufgefallen!
Im Moment hänge ich an dem Problem das mein System eigentlich immer
schwingt ca. minimal +1 / -2.5 °C bei einem KI=0...
Woran kann das liegen?
Regelstrecke besteht aus meinem kleinen Heizungselement das in einer
Hülse steckt. Der Temperatursensor ist außen an der Hülse angebracht.
Btw.: Ist die Erzeugung meiner Abtastzeit TA korrekt?
WEnn's schwingt sind die Parameter noch zu hoch. Mach den I-Teil ganz
weg. Dann den P Teil kleiner. Wenn's dann immer noch schwingt ist eine
Verzoegerung drin. Dann nach Standard.
Ich wuerd auf eine Verzoegerung tippen.Das kann man nur mit einem ganz
kleinen I Teil wegmachen. Allenfalls mit vorwaerts Steuerung. Indem man
die Umwelt parameter mitmisst.
Meier schrieb:> Danke für den Hinweis!>> War mir irgendwie garnicht aufgefallen!>> Im Moment hänge ich an dem Problem das mein System eigentlich immer> schwingt ca. minimal +1 / -2.5 °C bei einem KI=0...
lass dir halt mal die ganzen Werte ausgeben.
regelabweichung, p-Anteil, i-anteil, etc.
Wenn ein reiner P Regler schwingt (und sonst alles korrekt ist) dann ist
das Kp zu groß.
> Regelstrecke besteht aus meinem kleinen Heizungselement das in einer> Hülse steckt. Der Temperatursensor ist außen an der Hülse angebracht.
Also quälend langsame Regelstrecke.
@Karl Heinz Buchegger
Wie kann ich eine Festkommaarithmetik den am besten bzw. am
geschicktesten implementieren? So das ich nicht so oft bzw. willkürlich
dividieren muss??
Es ging einfach darum das ich mir gemerkt hatte zuerst zu multiplizieren
und anschließend erst zu dividieren...
Hab gerade glaubig schonmal einen Fehler gefunden...
Kann es sein das das OCR1C nicht standardmässig mit 0xff initalisiert
wird? Hat das nämlich irgendwo hier mal gelesen...
Oder is das von AVR zu AVR nochmal unterschiedlich? Studiere mal jetzt
mal das Datenblatt...
Gruß
Hallo erneut,
also der primäre Fehler lag tatsächlich an dem nicht gesetzten TOP Wert
der PWM.... :(
Hab das ganze jetzt erneut laufen mit einem KP von 25.0 aufgezeichnet.
(Siehe Anhang).
Sieht das ganze jetzt normal aus für einen reinen P-Regler? (KP ist wohl
schon ein wenig zu hoch denk, daher die leichte Schwingung)
Ich möchte jetzt die Regelparameter nach der Schwingungsmethode von
Nichols Ziegler bestimmen. Muss die hierbei zu ermittelnde kritische
Schwingung genau mit gleicher Amplitude (bzw. symmetrisch) um den
Sollwert schwingen?
Bzw. wann weiß ich das das jetzt die kritische Schwingung ist? (wenn
sich danach die Amplitude der Schwingung aufschaukelt??)
Kann mir noch einer die Frage beantworten wie groß ich die Größen des
Anti Wind-up wählen soll?
Hier kam die Aussage auf das mein Quellcode komisch aussieht. Bitte ein
bisschen konkreter und mögliche Verbesserungsmöglichkeiten.
Ich hab das mit dem I-Anteil im negativen Bereichen jetzt noch
angepasst. Hier mein derzeitiger Stand vom PI-Regler.
Meier schrieb:> Ich möchte jetzt die Regelparameter nach der Schwingungsmethode von> Nichols Ziegler bestimmen. Muss die hierbei zu ermittelnde kritische> Schwingung genau mit gleicher Amplitude (bzw. symmetrisch) um den> Sollwert schwingen?
Nein.
Denn ein reiner P-Regler erreicht den Sollwert nicht.
Erst mit einem kleine I-Anteil ist das dann der Fall.
> Kann mir noch einer die Frage beantworten wie groß ich die Größen des> Anti Wind-up wählen soll?
Das sind alles Erfahrungswerte, die am jeweiligen Objekt bestimmt werden
müssen.
> Hier kam die Aussage auf das mein Quellcode komisch aussieht. Bitte ein> bisschen konkreter und mögliche Verbesserungsmöglichkeiten.
elends lange Variablennamen, wobei die Länge nichts zum Verständnis
beiträgt. Dafür dann als Ausgleich keine Leerezeichen, die das Auge beim
Lesen unterstützen würden einzelne Wörter zu erkennen. Dafür dann
haufenweise sinnlose Kommentare.
Der Code sieht meiner Meinung nach extrem in die Länge gezogen aus. Der
Anteil an unnützem White-Space ist übermässig hoch, ohne dass es was an
der Übersicht bringt.
zb
>> //Bestimmung P-ANTEIL> p_anteil=((int32_t)p_factor*regelabweichung)/2; //Berechnung im> Format S(24,7)
No, na. Links vom = steht p_anteil. Wozu brauch ich da noch einen
Kommentar "Bestimmung P-Anteil". Wenn da eine Zuweisung an die Variable
p_anteil erfolgt, dann wird hier wohl nicht die aktuelle Temperatur
gemessen werden.
Im Kommentar steht was vom "Format S(24,7)".
Nur leider ist im ganzen Programm kein einziger Hinweis darauf, was das
überhaupt sein soll. Daher: Dieser Kommentar ist ein 0-Kommentar. Er
erzählt mir nichts, was für das Verständnis relevant wäre.
1
uint8_tpi_regler(int16_tregelabweichung)
2
{
3
int16_tp_factor,i_factor;
4
5
int32_tp_anteil,i_anteil,pi_regler_output;
6
7
staticint16_tregelabweichung_summe=0;
Nach jeder Zeile eine Leerzeile einfügen bewirkt nur eines: Der Code
wird in die Länge gezogen. Übersicht bringt das keine. Ganz im
Gegenteil. Wenn ich beim Code-Lesen ständig hin und her scrollen muss,
verliert man meist ständig den Faden.
//Set COM1B1 and COM1B0 --> OC1B cleared on compare match and set when TCNT1=01; Set PWM1B --> Enable PWM B
7
TCCR1A=(1<<COM1B1)|(1<<PWM1B);
8
9
//Set Prescaler 8, ergibt 7812,5 Hz bei F_CPU=16 Mhz
10
TCCR1B=(1<<CS12);
11
12
}
Du darfst ruhig davon ausgehen, dass dein Leser ein wenig AVR
Programmieren kann. Das PB3 am Port B der OC1B Pin ist, das weiß man
nicht unbedingt auswendig, ist schon richtig. Aber das das Bitsetzen im
DDR Register den Pin auf Ausgang schaltet, das weiß wohl jeder. Wenn du
dir am Anfang der Funktion die angestrebte Konfiguration zusammenfasst,
dann macht das auch nicht so den Eindruck von Zersplitterung
Bzgl. der Schwingungsmethode von Nichols Ziegler:
Heisst das jetzt das ich solange KP erhöhe bis sich eine gleichförmige
Schwingung ergibt? Unabhängig von deren Amplitude und die Lage um den
Sollwert?
Gruß
Und nochmal zurückkommend auf das Format S(24,7):
Ich dachte eigentlich das die Angabe bei Festkommaarithmetik mit U(x,y)
für eine unsigned integer mit x Vorkommabits, y Nachkommabits und analog
für signed integer S(x,y) eine Art Konvention ist.
Dem ist wohl nicht so?! Gibt es eine andere gängigere Angabe diesbzgl.?
Gruß
Ina... was ist das Problem? Natuerlich haben wir eine Ahnung. Aber die
Poster sollen auch etwas lernen, etwas selbst debuggen. Die Technologien
wurden erklaert.
wo liegt dein Problem, das so schnell geloes werden muss.
Hallo,
das Anti-Windup sollt ja nur verhindern, dass deine Stellgröße ins
unendliche wächst(Theorie). In der Praxis wird die Stellgröße durch die
PWM begrenzt, ich glaube du hast da 8-bit. Dann sollte die Begrenzung
bei max. Stellgröße 255 liegen. Für eine ausreichend gute Regelung kann
man ruhig die volle Stellgröße fahren um den Idealfall den aperiodischen
Grenzfall zu erreichen. Das ganze hat also nichts mit Erfahrungswerten
zu tun. Z.B. kann ein Dead-Beat Regler in einen digitalen Regelschritt
eine Temperaturstrecke ausregeln.
Um Faustformeln anwenden zu können musst du auf alle Fälle eine
Sprungantwort auf die Stellgröße aufnehmen. Das kann so aussehen, dass
du z.B. 100% Stellgröße auf den Heizstab gibst und die
Temperaturerhöhung aufzeichnest. Das wird dann ein PT1 oder eher PT2
Verhalten geben, da sollte aber nichts schwingen!
Wie sieht denn dein Regelalgorithmus aus?
Es sollte nach dieser Formel gerechnet werden
yk=yk-1 + kr (xdk - (1-t/tn) * xdk-1) wobei xdk der Istwer ist.
Das ist der Stellungalgorithmus, wobei yk der Stellwert ist.
Hallo Carsten,
vielen Dank für deine Antwort!
Mein derzeit genutzter genutzter Code steht oben im Post vom
Datum: 28.09.2012 15:09.
Als Alogorithmus benutzte ich da: y=e*KP+KI*TA*e_summe (D-Anteil hab ich
keinen)
Bzgl. dem Anti Wind-up heisst das jetzt das ich die Begrenzung von
e_summme so einstellen soll das der alleine I-Anteil noch einen
Vollauschlag der Stellgröße herbeiführen kann in der Begrenzung?
Sprich maximal Wert PWM 255 --> e_summe_max= +/- 255/(TA*KI) ??