Hallo,
versuch gerade eine Art Quarzofen zu bauen. Dabei möchte ich über ein
Heizelement einen kleinen Alu-Block welcher eine Vertiefung für die
Quarze hat aufheizen und dabei die Temperatur regeln.
Das Heizelement möchte ich gerne mit Hilfe eines Atmega8535 Ports (8
bit) über eine D/A Wandler (R 2R) und einen MOSFET Regeln.
Die Temperatur bekomme ich von einem DS1620 (Auflösung von 0,5°C)und
wandle sie in eine Floatzahl.
Jetzt mein Problem habe leider keine genaue Vorstellung wie ich den
Regler in C implementieren soll und wie ich Kp, Ki, Ta und eventuell Kd
einstellen soll.
Meine Stellgröße liegt im Bereich zwischen 0 (Heizung aus) und 255
(Heizung voll angesteuert).
Als Ergebnis soll der eingeschwungene Regler die Heizung gerade so
ansteuern, dass gerade die Energie wieder zugeführt wird, welche
Verloren geht.
Vielleicht hat ja jemand eine Idee für die Implementierung.
Vielen Dank im Voraus
Gruß Flo
Salü!
Also erst mal... Warum ein D/A Wandler? Das begreife ich nicht ganz...
Du willst doch wohl nicht den MOSFET mit einem Analogsignal ansteueren
oder? Da nimmste ein PWM! Sonst kannst Du auswählen, wer heizen soll,
das Heizelement oder der MOSFET! ;-)
Zur Implementierung in C: Naja, ein PID Regler ist eigentlich ziemlich
straight-forward:
P-Regler: Nimm den Temperaturfehler, multipliziere ihn mit dem
"P-Anteil" und gib das zum Ausgang.
I-Regler: Nimm den Temperaturfehler, integriere ihn über die Zeit (also
aufsummieren), multipliziere das mit dem "I-Anteil" und gib das zum
Ausgang.
D-Regler: Nimm den Temperaturfehler, differentiere ihn (also jeweils den
Unterschied zweier aufeinanderfolgender Samples berechnen),
multipliziere das mit dem "D-Anteil" und gib das zum Ausgang.
PID-Regler: Summiere die drei Ausgänge und dann WIRKLICH zum Ausgang.
:-)
Einstellen der Werte am besten mit probieren. I würde ich eh gleich
weglassen.
noch etwas,
Ich würde den D-Anteil weglassen und nicht den I-Anteil sonst bleibt dir
immer eine bleibende Regelabweichung stehen. Temperaturregelung ist eh
eine träge Angelegenheit da hilft dir der D-Anteil nur wenig.
Regler digital realisieren, geht (so hab ich das mal gelernt) über die
Z-Transformation. Man kriegt einen Ausdruck für s abhängig von z. Dann
den Ausdruck für s in die Übertragungsfunktion (im Laplace-Bereich) des
Reglers einsetzen. Nach z-Potenzen sortieren, Zurücktransformieren in
den Zeitbereich gibt eine Differenzengleichung, mit welcher der neue
Ausgabewert aus den zurückliegenden Abtastwerten berechnet werden kann.
Schwierigster Teil an der Sache ist wohl eher die Zwischenspeicherung
von Abtastwerten resourcensparend in nem Ringbuffer oder ähnlichem.
Für die Theorie über die z-Transformation empfiehlt es sich natürlich in
einem Mathebuch nachzuschlagen. Die Umrechnung von Laplace in
z-Transformierte ist bestimmt in den ein oder anderen
Regelungstechnik-Büchern genauer beschrieben.
MOSFET als Heizelement ist glaub ich nicht so trivial, weil dadurch die
Strecke nichtlinear wird. Heizelement über PWM angesteuert ist da schon
besser.
Ein PI Regler ist da sicher ausreichend, da bei der kleinen Masse und
thermisch eng gekoppelter Heizung von einer Regelstrecke erster Ordnung
(fast ohne Verzugszeit) ausgegangen werden kann.
Außerdem kommt es ja nicht wie z.B. bei einer Motorregelung auf eine
kurze Einschwingzeit des Systems an, man wartet halt ein paar Minuten
länger bis Stabilität erreicht ist.
Hallo MISZOU,
leider komme ich nicht ganz dahinter wie genau die application note
"AVR221"
funktionieren soll. Gibt es igendwie fertige Funktionen und Dateien wie
InitPID()?
Gruß Flo
flo
ne dein algorithmus kann nicht stimmen... wo ist bei dir der unterschied
zwischen dem P- und dem I- Anteil? der wird ja genau gleich berechnet...
Hier kurz und einfach erklärt, müsste für diese einfache anwendung
reichen...
http://de.wikipedia.org/wiki/Regler#PID-Regler
Hallo Michael,
der I-Anteil wird doch anders berechnet.
u_i += Ki*Abweichung; bedeutet ja eigentlich u_i = u_i + Ki*Abweichung,
aber dann sollte vielleicht u_i auch als static float deklariert werden,
oder?
Also wenn das ganze einen praktischen Nutzen haben soll so wuerde ich
den Regler analog aufbauen. Einfach weil kleiner und eleganter.
Ausser natuerlich du machst das aus akademischen Interesse. Dann hast du
natuerlich jetzt die Moeglichkeit viel zu lernen.
Dazu mal ein paar Tips.
1. Die Idee den Mosfet gleich als Heizelement zu verwenden bietet
sich an. Zumal man den Quarz vermutlich gleich an die Rueckwand
anloeten kann.
2. Achte darauf das die maximale Heizleistung deiner Schaltung nur
etwas ueber dem liegt was du brauchst. Wenn du also deinen Quarz
auf 60Grad regeln willst dann wuerde ich die Schaltung so auslegen
das du im Gehaeuse(!) maximal 80Grad bei 100%ED erreichen kannst.
Das macht deine Regelung einfacher!
3. Achte darauf deinen Temperaturfuehler moeglichst nahe am Heizelement
zu plazieren. Wenn du die Regelung mal laufen hast kannst du ja
mal ausprobieren was passiert wenn du den Fuehler weiter entfernst.
:-)
4. Du musst deinen Quarzofen ja in ein Gehaeuse bauen um ihn gegen
die Umgebung zu isolieren. Je besser die Isolierung ist um so
weniger Energie brauchst du spaeter. Aber eine sehr gute
Isolierung macht wiederum die Regelung komplizierter.
Olaf
Ich will auch noch mal was zum I-Anteil sagen. .-)
Wenn man eine relativ langsame Strecke hat dann hat der I-Anteil zu
begin, also nach dem einschalten viel Zeit zu wachsen. Bei einem
analogen
Regler wird dies dadurch begrenzt das aus einem Operationsverstaerker
nunmal nicht mehr rauskommen kann als wie seine Versorgungsspannung.
Bei einem digitalen Regler jedoch haengt der maximal Wert von der
Registerbreite ab. Man sollte daher dafuer sorgen das der Wert nicht
ueber ueber alle Massen wachsen kann.
Es waeren aber auch noch andere Loesungsansaetze denkbar. ZumBeispiel
den I-Anteil erst zuschalten wenn die Regelabweichung schon keiner ist.
Olaf
Oder ein sog. "Anti-Windup". Also den I-Anteil einfach in der Grösse
begrenzen.
Öh.... ich hab mich schon lange nicht mehr mit Reglern beschäftigt, aber
so aus dem Bauch raus, würde ich den I-Anteil noch eher als den D-Anteil
weglassen.
Denn der kleine Regelfehler, der am Schluss übrig bleibt, der... naja,
ok, das muss man halt schauen, ob der ok ist.
Aber ein D-Anteil kann gerade bei einer Temperaturregelung sehr helfen,
wenn grosse Störeinflüsse zu erwarten sind und die Strecke sehr träge
ist. Denn er reagiert einfach früher. Ich musste mal einen
Wasserkreislauf mit PID regeln. Und da konnte man wunderschön sehen, wie
der D-Anteil arbeitete. Wasser ist noch zu heiss, aber weil viel Wärme
abgeführt wird, fällt die Temp gewaltig. Ohne D-Anteil. Der Regler ist
zufrieden, und erst wenn es schon zu kalt ist, wacht er mal auf und
fängt an, das Heizelement zu heizen. Bis das dann schön warm war....
naja.... Und Vice Versa. Schwingen.
D-Anteil: Es ist noch zu heiss, aber dennoch fängt er an zu heizen. Und
fängt die Flüssigkeit schön brav bei der Solltemperatur ab.
Ach ja, wegen dem Laplace, Z-Trafo etcet...
Ich will nicht arrogant tönen, ganz ehrlich nicht: Aber aufgrund der
Fragestellung würde ich schon bei einem PID-Regler bleiben und einem
empirischen Ansatz bleiben und mich nicht an Laplace, Z-Zeugs etc wagen.
Das wird mathematisch ziemlich komplex und vor allem abstrakt. Beim PID
kannst Du Dir alles sehr schön bildlich vorstellen und weisst, was Du
tust.
Hi,
prinzipiell passt der Code oben scho. Ich persönlich würde folgende
Dinge anders machen:
-Keine float, sondern normierte Ganzzahlen. (P-Anteil 2Byte, I-Anteil
4Byte) -> is viel schneller
- wie Olaf schon erwähnt hat I-Anteil unbedingt begrenzen. Es kann
passieren das sich der I-Anteil sehr stark auf- bzw. abbaut. Bei einem
VZ-Änderung muß der I-Anteil erst seinen "Speicher" wieder auf- oder
abbauen und das kann dauern. Also sinnvolle Grenze wählen.
- Mit dem D-Anteil wäre ich persönlich vorsichtig. War bei mir noch nie
nötig.
- Ich würde mir Gedanken über einen Vorsteueranteil machen. Physikalisch
kannst Du Dir das so vorstellen. Wenn deine Zieltemeratur erreicht ist,
mußt Du (wie du oben auch schon gesagt hast) die Energie zuführen, die
von deiner Streck abgegeben wird. Diese ist theoretisch immer Gleich. ->
Vorsteueranteil der bei einer gewissen Temperatur immer sofort auf den
Regelausgang wirkt.
-Auf Z-Ebene würde ich verzichten. Dazu ist das Problem zu trivial um
nicht im realen Zeitbereich gelöst zu werden.
cu
Hi, habe mir auch mal Gedanken wegen PID-Reglern mit µC gemacht und bin
aud das Buch 'Mikroprozessoren und Mikrorechner', ISBN 3-486-24431-0
gestoßen.
Den Teil für den PID-Regler habe ich in ein pdf verfrachtet und mal
gepostet. Vielleicht hilft's ja jemanden. So ganz einfach ist die Sache
jedenfalls nicht, wenn man's ordentlich machen will!
Hallo,
ich misch mal mit...
Also die Formel für den PID-Regler sieht wie folgt aus:
u(t) = Kp ( e(t) + 1/Tn * Integral(e(t) * dt) +Tv * e'(t) )
wobei u(t ) die Stellgröße, e(t) die Regeldifferenz, KR die
Reglerverstärkung, TN die Nachstellzeit
und TV die Vorhaltzeit ist. (siehe 1 seite vom pdf über mir)
So, das wollen wir in einer zeitdiskreten Form haben. Da nen Rechner nur
diskrete Werte rechnen kann...
Also wird aus:
Integral(e(t) * dt) => Summe(e(k) ) * delta t // Fläche unter einer
Kurve
und e'(t) => (e(k) - e(k-1) ) / delta t // Steilheit einer
Kurve...
wenn man das in die ürsprüngliche Gleichung setzt und bisschen hin und
her rechnet (die unendliche Summe z.B. muss man eleminieren) kommt man
auf:
u(k) = u(k-1) * Kr ( ( (1+Tv)/delta t) * e(k) - (1- delta t /Tn +
2*Tv/delta t) * e(k-1) + Tv/delta t *e(k-2) )
Diese obige Formel haut man in eine Programmierzeile. Danach speichert
man noch u(k-1), e(k-1), e(k-2) für die nächste Rechnung...
Achja:
Kr = Kp ; Tn = Kr/Ki ; Tv = Kd/Kr
Tn = -26 und Tv = 0.16 sind gute richtwerte...
Viel Spaß damit...wer nachlesen will kann sich das obige pdf durchlesen
:)
Ciao
Christoph
Zu den Formeln auf der Seite von Roboternetz, kann mir da jemand
erklären wie man vom "Differenzengleichung für den zeitdiskreten
PID-Regler" zum "PID Stellungs-Algorithmus" kommt???
Ich steh da grad auf dem Schlauch.
Danke,
Thomas
Das Problem bei der Differenzengleichung für den zeitdiskreten
PID-Regler ist ja die Summe. Man müsste also die Summe immer wieder neu
berechnen bzw. wird auch mit der Zeit ziemlich groß. Um diese Problem zu
umgehen macht man folgendes:
Man betrachtet die Gleichung für einen Zeitpunnkt früher, also y(k-1).
Der D-Anteil wird also zu:
(e(k-1) - e(k-2))/Ta
Die Summe beim I-Anteil wird jetzt von i=0 bis k-1 gezählt.
Der P-Anteil wird einfach zu y(k-1)...
Nun kommt der Trick: Man subtrahiert diese Gleichung von der Gl. für
y(k).
Also: y(k) - y(k-1)
Was passiert bei der Summe? Folgendes:
Die Summe bei y(k) sieht explizit so aus: e0 + e1+ e2 + ...+e(k)
Die Summe bei y(k-1) hat ein Glied weniger: e0 + e1+ ...+e(k-1)
subrahiert man beide bleibt von den zwei großen Summen nur noch das
Glied e(k) übrig! Und ist damit für den Rechner geeignet...
Gruß
Christoph
Hallo,
also ich habe das so gelöst:
//-------- Motor Regelung ------------ //
int MotorRegelung(int *MotorStellwert, int *mmpsDeltaSum, int mmpsSet,
bool *dir, int *mmpsDeltaBefore, int mmpsAct)
{
// um
// mmps
int mmpsDelta;
// control
float Kp = 0.08; // Proportional 0.3
float Ki = 0.3; // Integral 1.4
float Kd = 0.005; // Differenziel 0.015
float Ta = 0.02;
mmpsDelta = mmpsSet - mmpsAct;
*mmpsDeltaSum += mmpsDelta;
*MotorStellwert = (Kp * mmpsDelta) + (Ki Ta *mmpsDeltaSum) + (Kd *
(mmpsDelta - *mmpsDeltaBefore) / Ta);
*mmpsDeltaBefore = mmpsDelta;
if(mmpsSet == 0 && abs(mmpsAct) < 3) // alles auf null wenn Sollwert
= 0
{
*MotorStellwert = 0;
}
if(*MotorStellwert >= 0) // Richtung umschalten, Vorzeichen muss
außerhalb der Funktion gesetzt werden :-))
{
*dir = 0;
}
else
{
*dir = 1;
}
return ((mmpsAct));
}
Der Motor treibt ein Antriebsrad. Die Geschwindigkeit messe ich mit
einem Encoder und durch Umrechnung mit dem Raddurchmesser. Das ganze
dann natürlich nur alle Ta=0.2 Sekunden in der Void() Schleife aufrufen.
Dann sollte auch die Geschwindigkeit des Vorschubs stimmen/richtig
skaliert sein. Die Regelabweichung (mmpsDelta) und die Summe der
Regelabweichung über Zeit (mmpsDeltaSum) muss für den jeweils nächsten
Durchlauf außerhalb der Funktion gespeichert werden, daher die Pointer
(*).
Viel Spaß :-)
Gruß
Ferdinand Rudolph
Am Ausgang steuer ich ein Motorboard an, dieses kann nichts mit
negativen Motorstellwerten anfangen (die Funktion abs() verwenden) und
hat dafür einen extra Digitaleingang (hier mit der Variablen "dir"
angesteuert). Jetzt aber.
Ferdinand schrieb:> Am Ausgang steuer ich ein Motorboard an, dieses kann nichts mit> negativen Motorstellwerten anfangen (die Funktion abs() verwenden) und> hat dafür einen extra Digitaleingang (hier mit der Variablen "dir"> angesteuert). Jetzt aber.
^NAch 12 Jahren gräbst Du diese Threadleiche aus? Gehts noch?
Farbenblind und die rote Warnung nicht gesehen? Dringendes "ich kanns
aber auch"?
Ferdinand schrieb:> also ich habe das so gelöst:> ...> Viel Spaß :-)
Da der ursprüngliche Beitrag geschlagene 11,5 Jahre her ist, hat der TO
wohl seinen Spaß bereits gehabt ;-)