Hallo zusammen! Ich bin gerade dabei mit einem PI-Regler eine Stromregelung für einen Gleichstrommotor aufzubauen. Benutze einen Atmega16 mit extern 4MHz Quarz. Im Anhang das Programm (so wie es jetzt ist sicherlich unsinnig) . Ich lese über den ADC eine "Stromwert" ein und regle über PWM den Motor. Ich habe folgendes Problem: Bei einer digitalen Regelung ist es sinnvoll eine hohe Abtastfrequenz zu nehmen. Fausformel T_ab < 0.1 - 0.2 * T_summe Es ist doch aber nur sinnvoll so schnell abzutasten wie meine PWM Timer neue Werte generieren kann also hier 15.625 KHz, sonst rechne ich zwar einen neuen Stellwert aus aber es tut sich nichts am Ausgang. Den PWM Timer und den Regelinterrupt Timer hab ich auf einander abgestimmt, so dass ich immer zum selben Zeitpunkt die Strommessung (beim Durchschnittswert, ist eine Dreiecksspannung) machen kann. T_summe ist für den einfachsten Fall die Motorzeitkonstante, die ich mit dem PI-Regler kompensieren will - hier 20µs * 0.2 = 4µs Abtastzeit??? Könnt ihr mir Tipps geben wie man den zeitlichen Ablauf von einer Regelung in den Griff bekommt? Oder würdet ihr das Problem ganz anders angehen?
warum tust du nicht einfach, den overflow-interrupt deines pwm timers nutzen, um eine adc-wandlung zu starten? ist diese fertig, rechnest du gleich mit dem resultat deinen neuen stellwert aus...
Wär auch ne Möglichkeit. Ich wollte aber bewußt nicht da meinen Strom messen, wo mein PWM von low nach high wechselt. Der Stromverlauf an der Stelle hat ziemliche Spitzen. Denkst du, dass der Code ansonsten passt. Wie könnt ich die Reglereinstellungen hinbekommen? Bisher hab ich den Regler als kontinuierlich ausgelegt und mit dem Betragsoptimum die Motorzeitkonstante kompensiert. Der reine P-Regler funktioniert einigermaßen, der PI-Regler nicht. Hast du ne Idee wie man die richtige Abtastzeit wählt?
Bei meinem Vorschlag dachte ich, du nutzt die PWM mit up/down Rampe, da hättest an besagtem Zeitpunkt den exakten Mittelwert anliegen... Hast du ne Idee wie man die richtige Abtastzeit wählt? Nun, wenn du quasi-kontinuierlich willst, dann sollte es zehnmal schneller sein, als der schnellste Teil der Strecke. Ich finde das aber unsinn, da du ja hier mit einer bestimmten PWM Frequenz arbeitest. Deshalb meine ich es reicht, einmal pro PWM-Periode abzutasten. Es ist Unsinn, Werte zu ermitteln, die nicht verwendet werden. volatile int32_t error_sum = 0; volatile uint16_t K_R = 5; ..+ (0.25 K_R error_sum);... Ich glaube, das geht nicht: o.25 als (u)int ist wohl Null.... Warum nimmst du nicht einfach ne Differenzengleichung zur Errechnung des neuen Stellwertes?? ist einfacher... PS:..tante L_a : R_a = 20us mit ... 20µsek halte ich für sehr klein.. aber möglich...
Kannst du mir das mit der PWM up/down Rampe kurz erklären. Das ist genau was ich suche, da ich den Strom (Mittelwert) möglichst genau messen will. Das mit der Abtastzeit hab ich mir schon gedacht, einmal pro PWM reicht. Das mit "int Stellwert" werd ich ändern. Ist das nicht eine Differenzengleichung? Oder meinst du besser: Stellwert = K_R * erorr + K_I T_abtast error_sum 100µH Motor-Induktivität ist ziemlich klein wurde aber so gemessen.
Gucke mal im Datenblatt des mega16 auf Seite103, die Abbildung47. Diese Betriebsart des Timers in PWM-Mode solltest du dazu wählen. Dann geht das so. Eine Differenzengleichung sieht zB so aus: y(k) - y(k-1) = delta_y(k) = a0*e(k) + a1*e(k-1) + .. - b1*y(k-1) - b2*y(k-2) - ... y : Ausgangsgröße (hier Tastverhältnis) e : Eingangsgröße (hier Regeldifferenz) b1, b2,... a0, a1, ... Koeffizienten. Die Koeffienten bestimmen jetzt das Verhalten. Für PI-Verhalten ergibt sich: Ta Ta a0 = KR [------ + ----] Ta: Abtastzeit T 2*Ti Ti: Integrationszeitkonstante KR: Reglerverstärkung Ta Ta a1 = KR [------ - ----] T 2*Ti b1 = b2 = 0
Ah, du hast den phase correct PWM Mode gemeint. Hab ich erst falsch verstanden. Steht ja auch drin - für Motor Anwendungen. Mit diesem Modus und dem Overflow Interrupt funktioniert's schon besser. Den Regler muss ich erste noch in Code umsetzten. Was bedeutet bei den Koeffizienten das T? Und ist mit Ti die Nachstellzeit des gesamten PI-Reglers gemeint oder nur der Zeitfaktor für den I-Regler. Kann ich in der Differenzengleichung die Regelparameter für den kontinuierlichen Fall auslegen? zB. Betragsoptimum?
Ja, das T ist gleich Ta, die Abtastzeit. Dadurch beginnt die eckige Klammer mit [ 1+ ... ] bzw [ 1- .. ]. War ein Umstellungsfehler von mir. Ti, ist die Integrationszeitkonstante. Siehe Anhang.(Die Tustin, Diff-quot.formeln müssen hier allerdings mit 1/s =.. losgehen. Das Ergebnis stimmt aber)
Achja: Solange du oft genug abtastest, gegenüber der Streckendynamik, kannst du das als quasi-kontinuierliches System auslegen... ca Ta < 10 T_min_strecke
Hi, Holger, habe ich richtig verstanden? PWM steuert Motor an, irgendwo von der Welle wird das Ist-Signal angegriffen und mit Sollwert verglichen? Einerseits möchtest Du die hohe PWM-Schaltfrequenz, andererseits ist der AD-Wandler zu langsam? Wenn die Abstastfrequenz deutlich höher ist als die höchste wichtige Freqenz bei der Änderung des Soll-Wertes, dann kannst Du ja schon mal bauen und berichtenm, was bei mir noch in der Pipeline liegt: Benutze den Komparator. Wie? Mit dem PID-Regler erzeugst Du erst mal eine Sollspannung (Ausgangspin, RC-Tiefpaß, AD-Wandler) und gibst die auf den Komparator. Sowie den Ist-Wert auf den anderen Eingang des Komparators. Jetzt kannst Du Deinen Schalttransistor so schnell schalten, wie Du den Interrupt des Komparators in ein Ausgangsignal umsetzen kannst. Ich vermute, mindestens zwei Größenordnungen schneller als mit AD-Wandler. Ciao Wolfgang Horn
Zuerst sollte man die Geschwindigkeit des Systems kennen. Was ist die Bandbreite der Strecke? Das Wesentliche geschieht eh in dieser Bandbreite. Am Besten läaast man die Regelung synchron zu einem Timer laufen. Den kann man nachher etwas verstellen. Wenn's nicht gerade ein Scheibenläufer ist, haben Motoren Bandbreiten in den Hz. Sinnvollerweise hat man den PWM aus akustischen Gründen oberhalb 20kHz. Nun kann man mit 20k+ abtasten, bringt aber wenig. Wichtig ist viel eher ein halbweg venünfiges Modell der Strecke zu haben. Ein PID, ist schon das Minimum wenn man nichts anderes hat. R
@Wolfgang: Was Du vorhast vesteh ich nicht ganz. Ich will eine ziemlich simple PI, später dann PID Regelung aufbauen, und wollte wissen wie man auf eine geeignete Abtastzeit kommt, muss erstmal nicht die schnellste Variante sein soll einfach nur mal funktionieren. @Rene: Auch deine Meinung ist, dass Abtastenfrequenzen > der PWM-Freqenz nutzlos sind. Ich verwende einen Scheibenläufermotor mit sehr kleiner Motorzeitkonstante (100µH und 5 Ohm -> 20µs Motorzeitkonstante) Ist diese Motorzeitkonstante gleichzeitig meine Streckenzeitkonstante oder muss ich da noch meine PWM Zeit dazuzählen? @Matthias: Was bedeutet genügend oft gegenüber der Streckendynamik? Ist mit Streckendynamik (Streckenzeitkonstante) auch die Zeit für PWM gemeint oder nur die Motordynamik. Kannst du mir für meinen Fall eine konkrete Abtastzeit sagen, so dass ich meinen Regeler für's Kontinuierliche auslegen kann?
Ein (DC)Motor hat grundsätzlich PT2N Verhalten: Also zwei (reelle) Zeitkonstanten: eine Mechanische und eine Elektrische: Ua => Ia : PT1 mit Zeit Te Ia => n : PT1 mit Zeit Tm Da meist gilt: Te<<Tm, wird Te oft weggelassen und der Motor als PT1 mit Tm dargestellt. Das heißt bei dir, du kannst die 20µsek weglassen und als P-Verhalten annehmen, solange du "weit" unter 1/20µs=50kHz bleibst. Die Tm liegt gewöhnlich in der Größenordnung von einer Sekunde. Somit wären (für den Drehzahlregler) Abtastzeiten von 50..100Millisekunden vollkommen ausreichend(für quasikontinuierliche Regelung). Wie groß allerdings die mechanische Zeitkonstante Tm bei deinem Motor ist, weiß ich nicht. Willst du allerdings einen Kaskadenregler bauen(unterlagerter Ankerstromkreis), so musst du diese Zeitkonstante Te beachten: Liegt die PWM-Periodendauer in der Größenordnung von Te, so musst du mit dieser Zeit rechnen. Liegt die PWM-Periodendauer weit (zehnfach..) über Te, so ist Te vernachlässigbar klein, weil bei der nächsten PWM-Periode der "Einschwingvorgang" von Te ja lange zuende ist..
Holger, unter Zeitkonstante der Strecke meinet ich nicht die Wicklung des Scheibenläufers. eher die Zeitkonstante des Motores, Welle, Lager & Last. Nimm ein Schwungrad von x kg an, das hat ein Massenträgheitsmoment von y kgm^2. Wenn ich nun auf dieses System einen AC gebe, beschleunigt das System auf eine Seite, bremst ab, beschleunigt auf die andere Seite usw. Vom Drehwinkel her ist das System integrierend. dh fuer Frequenz gegen null wird der Drehwinkel unendlich. Auf die Drehzahl bezogen ist das System ein Tiefpass. Die Ansteuerfrequenz, bei der nur noch 1/wurzel2 der DC Drehzahl erreicht wird, ist die charakteristische Frequenz der Strecke. rene
Hi, Holger, Du: [i]Was Du vorhast vesteh ich nicht ganz. Ich will eine ziemlich simple PI, später dann PID Regelung aufbauen, und wollte wissen wie man auf eine geeignete Abtastzeit kommt, muss erstmal nicht die schnellste Variante sein soll einfach nur mal funktionieren.[/i] "Nur funktionieren"? O.k., dafür ist mein Vorschlag zu kompliziert, taugt nur für schnelle PWNM. Mein Vorschlag detailliert: Angenommene Aufgabe: Position eines Fahrzeugs soll eingestellt werden, sagen wir mal Zielfahrt - je näher am ziel, desto langsamer. Treiber: Der Motor wird mit PWM angesteuert mit Freilaufdiode. Die Schaltfrequenz muß deutlich über der Hörschwelle liegen, z.B. 20 kHz, entsprechend 50us. Regelschaltung: Eine Regelung von PWM-Puls zu Puls wäre möglich, sie soll den Strom durch den Motor stellen in Abhängigkeit einer weiteren Reglegröße, beispielsweise Positionsmesser für Zielfahrt. Für Puls-zu-Puls-Regelung muß der AD-Wandler schnell genug sein, 50us, und ebenso die PID-Berechnung. Der AD-Wandler der Atmega aber bei "maximum Resolution" nur 15 kiloSamples/s. Abhilfe: Ein zusätzlicher Regelkreis! Reelkreis I, der äußere: Mißt Annäherung an das Ziel und Sollwert für Gschwindigkeit bzw. Strom durch den Motor. Abtastrate: Gering, vielleicht 20/s. Der Regelkreis I bestimmt, wie schnell der Motor drehen soll, wieviel Strom er aufnehmen soll. Regelkreis II, der innere, Zweipunktregelung mit Komparator des Atmega: Dieser vergleicht den Vorgabewert für Strom mit dem Ist-Wert, Stromfühler wandelt Ist-Strom im Ist-Spannung am Komparator. Ist der Ist-Wert kleiner, macht er den Treibertransistor auf, sonst wieder zu. Der Regelkreis II bekommt seine Vorgabe für den Soll-Strom vom Regelkreis I. Und zwar in Form einer Spannung zum Vergleich am Komparator mit Ist-Wert. Verbesserung gegenüber ersten Beitrag: Erzeugung der Soll-Spannung am Komparator durch PWM-Signal und Tiefpaß durh RC-Glied. Die Grenzfrequenz des Regelkreises I bemißt sich an der Trägheit des zu steuernden Fahrzeugs, also wohl im 1/10-Sekunden-Bereich, die Grenzfrequenz von Regelkreis II liegt oberhalb der Hörschwelle. Ich habe so etwas vor für einen Akkulader mit Step-Down-Regler oberhalb der Hörschwelle, aber andere Dinge sind mir wichtiger. Ciao Wolfgang Horn
Nach einer längern Pause hab ich hier einen neuen Versuch: Anhang Hab die Regelung jetzt mit einer Differenzengleichung umgesetzt und stell meine Parameter mit dem ADC und Potis ein. Funktioniert soweit ganz gut. Hab jetzt nur noch 2 Probleme: 1)Wie erkenn ich , dass ich eine vernünfige Einstellung gewählt habe? Stromsprung draufgeben und Sprungantwort aufzeichnen wird wohl schwierig? 2)Wenn ich für eine längere Zeit meine Motorspannung ausschalte und somit mein Sollwert w konstant unter dem Istwert liegt wird meine Stellgröße y schnell sehr groß. Wenn ich dann die Motorspannung wieder anschalte ergibt sich ein sehr hoher Strom der den entstandenen error wieder klein machen will. Wie kann ich y sinnvoll begrenzen? (Auskommentierter Bereich im Code) @Matthias: Eine Kaskadenregelung ist genau das was ich machen will. Ist eine vernünftige Stromregelung überhaupt zu realisieren. Denn auch im "eingeschwungen Zustand" zappelt meine Stellgröße ziemlich. Liegt dass an der Strommessung -> Strom vorher glätten? Je besser meine Stromreglung, desto besser ist das für meine Drehzahlregelung???
1) Ja. Sprungantwort aufnehmen, und nach gewählten Kriterien prüfen. 2) Das Problem was du hier hast, ist ein "Überlaufen" des I-Anteils, wenn du die Ausgangsgröße aus irgendwelchen Gründen festhältst: //falls Sollwert w lange Zeit zu klein ist wird y zu groß!!! if (((y)<1000) && ((y)>-1000)) y = y; else if ((y)>=1000) y = 1000; else if ((y)<=-1000) (wobei das Quellcode besser hinschreibbar ist) Die Lösung nennt sich "Anti-Wind-Up". Das bedeutet, dass du den I-Anteil des Regler solange festhalten musst, solange irgendwas in irgendwelchen Aussteuergrenzen feststeckt... Weiterhin ist es möglich, die Sollgröße w (Sollstrom) nicht direkt zu nehmen, sondern hier noch eine Begrenzung, etc.. einzubauen. So wirds auch gemacht. Somit kann der Motornennstrom (oder welcher auch immer) nicht überschritten werden...
Hab mir die Sprungantwort jetzt mal genauer angeschaut. Das Problem hierbei ist, dass wenn der Sollwert-Sprung kommt meine Regelung eine ziemliche Verzögerung hat (Totzeit), bis sie reagiert. Diese dauert ca. 2ms! (Zeit die vergeht um einmal den Regelinterrupt zu durchlaufen und neuen Stellwert auszugeben). Wie kann ich den Ablauf des Interrupts beschleunigen und somit meine Abtastzeit verkleinern? Ich denke das es an der AD Wandlung liegt. Wie lange sollte eine AD Wandlung im Free-running Modus dauern? Gemessen am Oszi bei mit ca. 220µs! Kann eigentlich nicht sein, denn bei 4MHz und 32 Vorteiler -> 125kHz ADC Frequenz und 13 Zyklen pro Messung -> 106µs um ein Ergebnis auszugeben. Wie ist die schnellste Methode einen AD Kanal auszulesen?
An der AD-Wandlung liegt's nicht. Die dauert bei mit nur so lange weil ich das Ergebnis in eine float Variable geschrieben hab. Wenn man sämtliche float Variablen aus der Regel ISR nimmt geht's erheblich schneller. Jetz dauert ein durchlauf nur noch 220µs.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.