Hi Leute,
ich befasse mich gerade mit folgendem Problem:
Ich habe hier einen kleinen 12V DC-Motor.
Den steuere ich mit einem Mikrocontroller über eine H-Brücke an, sodass
er in beide Richtungen drehen kann. Mittels einer PWM kann ich auch die
Drehzahl einstellen.
Bisher habe ich das jetzt so gemacht, dass ich die Spannung am Abgriff
eines Potis AD-gewandelt habe, und dann diesen Wert als Vorgabe für die
PWM genommen habe. Das geht natürlich; der Motor lässt sich von 0% bis
100% in der Drehzahl einstellen.
Das dumme ist nur, dass wenn der belastet wird, die Drehzahl natürlich
sinkt!
Ich habe mir jetzt überlegt, ob man das nicht irgendwie regeln kann. An
dem Motor ist ein Encoder angebracht, der liefert rechteckige Impulse
(um 90° verschoben). Damit lässt sich die Drehrichtung und die Drehzahl
bestimmen.
Also, ich habe mir überlegt: man schaut sich irgendwie das
Ausgangssignal vom Encoder an, bestimmt daraus die Drehzahl, und
vergrössert oder verkleinert danach den Tastgrad der PWM so, dass die
Drehzahl ihren Sollwert erreicht. Geht das? Könnt ihr mir einen Tipp
geben, wie ich das am besten anfange?
Ich verwende einen 8051 Controller, genauer einen AT89C4051.
Gruss
Rudolf G. schrieb:
> Also, ich habe mir überlegt: man schaut sich irgendwie das> Ausgangssignal vom Encoder an, bestimmt daraus die Drehzahl, und> vergrössert oder verkleinert danach den Tastgrad der PWM so, dass die> Drehzahl ihren Sollwert erreicht. Geht das?
ja, ganz genau so wird das gemacht
>Könnt ihr mir einen Tipp geben, wie ich das am besten anfange?> Ich verwende einen 8051 Controller, genauer einen AT89C4051.
entweder Impulse pro Zeit messen, oder die Impulsbreite und danach auf
die Drehzahl hochrechnen
Gruß
Christian
Hallo Christian,
sehr schön. Danke für deine schnelle Antwort!
Wenn ich jetzt die Impulsbreite kenne, wie kann ich dann daraus auf den
PWM-Tastgrad hochrechnen? Muss ich dazu die Kennlinie vom Motor
aufnehmen Tastgrad vs. Drehzahl und das dann in einer Tabelle ablegen?
Oder gibt es eine elegantere Methode`?
Du solltest Dich mit Regelungstechnik beschäftigen. Als Ansatz:
Deine Sollgröße ist die gewünschte Drehzahl, die Stellgröße die PWM und
die Führungsgröße ist die gemessene Drehzahl. Du kannst auch die
Drehzahl einfach durch die Pulsbreite ersetzen, dann gibst Du die
Pulsbreite vor. Für die Regelung der Drehzahl kannst Du einen
PID-Regler nehmen. Sourcecode findest Du ziemlich viel im Netz. Die
Reglerparameter (P, I und D) kannst Du nach der Methode nach
Ziegler-Nichols bestimmen.
Zur Vereinfachung habe ich Dir die Suchbegriffe für eine Suchmaschine
Deiner Wahl unterstrichen.
mfg, Stefan.
Hallo Rudolf,
'auf den PWM-Tastgrad hochrechnen' macht deine Drehzahlregelung.
Für den Istwert der Regelung musst du nur die Auflösung deines
Impulsgebers wissen, damit du auf die Drehzahl hochrechnen kannst.
Das mit deiner Tabelle würde theoretisch auch funktionieren, ist aber
viel zu aufwändig und funktioniert bei weitem nicht so gut wie eine
richtige Regelung.
Gerade wenn du schon einen Sensor hast bietet sich eine Regelung nahezu
an!
@Stefan
Vielen Dank. Ich suche mal hier im Forum nach den PID-Reglern.
Ich muss allerdings sagen, dass ich während meiner Ausbildung die
Regelungstechnik nur gestreift habe; wir haben lediglich kurz
angeschaut, wie man mit OpAmps Regler baut, und was die für Kennlinien
haben.
Aber ich denke, ihr könnt mir sicher Hilfestellung geben, beim bauen
eines digitalen Reglers auf einem Mikrocontroller, oder?
@Christian
Ja, wie bereits Stefan angedeutet hat, wird dann wohl eine PID-Regelung
die bessere Wahl sein. Die werde ich auch versuchen, zu imlementieren!
Rudolf G. schrieb:
> Ja, wie bereits Stefan angedeutet hat, wird dann wohl eine PID-Regelung> die bessere Wahl sein. Die werde ich auch versuchen, zu imlementieren!
Du kannst dir ja das Leben auch leicht machen und den Regler
schrittweise entwerfen.
Zuerst P-Regler, dann PI-Regler, wenn's immer noch genügt dann noch den
D-Anteil dazu.
Die Frage ist nur ob dein Antrieb wirklich so dynamisch sein muss, dass
du gleich einen PID-Regler brauchst.
Viel Erfolg und Spaß :-)
Gruß
Christian
@Christian
jaa, der Antrieb sollte schon einigermassen dynamisch sein. Ich will
halt ne einigermassen exakte, und vor allem konstante, einstellbare
Drehzahl. Und wenn die Last sich ändert, dann darf die Drehzahl nicht
allzu viel überschwingen.
Hast du vielleicht einen kleinen Code, wo ich ansatzweise mal sehen
kann, wie sowas implementiert wird?
Hier finde ich nur komplette PID-Regler, die mir auf den ersten Blick
schon etwas kompliziert ausschauen.
> Hier finde ich nur komplette PID-Regler, die mir auf> den ersten Blick schon etwas kompliziert ausschauen.
Also ich finde ja das ein PID Regler sehr einfach aussieht.
Das schwierige ist gerade das was man nicht sieht, also die
Bestimmung der Koeffizienten. Und ganz besonder wenn sich deine
Regelstrecke noch aendert.
Es ist daher leider absolut unumgaenglich das du dich ernsthaft mit
Regelungstechnik auseinandersetzt wenn du soetwas fuer dein System
implementieren willst und abschreiben ist bei Reglern normalerweise
nicht zielfuehrend.
Olaf
Hey, ich hab hier einen Thread gefunden, wo jemand das mit den Reglern
ein bisschne erklärt hat:
> 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.
Das kommt mir irgendwo her ja bekannt vor!
Also, hab ich kurz mein Visual Studio gestartet, und mir vorerst mal für
den PC eine Konsolenanwendung gebastelt, die das macht. Der Code sieht
wie folgt aus:
int drehzahl_ist = 0;
int drehzahl_soll = 20;
int regler_ausgang = 0;
int e;
int ealt = 0;
int esum = 0;
int p_ant = 1;
int i_ant = 1;
int d_ant = 1;
int p;
int i;
int d;
while(1)
{
e = drehzahl_soll - drehzahl_ist;
p = e * p_ant;
esum = esum + e;
i = esum * i_ant;
d = d_ant * (e - ealt);
ealt = e;
regler_ausgang = p + i + d;
}
und nun die Frage:
ist das korrekt so`? Wenn ich das auf den Mikrocontroller portiere,
werde ich dann natürlich in die Variable "drehzahl_ist" die mittels
Sensor ermittelte Drehzahl reinschreiben. In "drehzahl_soll" kommt ein
mittels Poti und ADC einstellbarer Wert. Und "regler_ausgang" ist
natürlich dann der Tastgrad meiner PWM.
Na, klappt's so?
Ach ja, ich muss hier noch anmerken, dass ich dann natürlich die
Konstanten "p_ant", "i_ant" und "d_ant" entsprechend auf den Motor
anpassen muss. Die legen ja den jeweiligen Anteil fest.
Im Prinzip ist das so richtig. Ich wuerde dir also empfehlen
einfach mal anzufagen und Erfahrungen zu sammeln. :-)
Es gibt noch ein paar Dinge du du bedenken solltest:
Notwendige Abtastfrequenz deines Eingangs damit keine Information
verloren geht.
Notwendige Frequenz mit der dein Regler laeuft. Die kannst du nicht
einfach so aendern weil das auch ein Regelparameter ist.
Maximalwerte fuer I-anteil.
Ueberlege dir vorher GENAU wie gross deine Eingangs und Ausgangsgroessen
werden und welche Zwischenwerte bei den Berechnungen des Reglers so
rauskommen. Du wirst dann uebrigens feststellen das man so einen Regler
zwar durchaus in einem 8Bit-Controller bauen kann, aber es doch eine
sehr dankbare Aufgabe fuer 16bit-Controller ist.
Und danach kannst du dich dann Sonderfaellen hingeben. Zum Beispiel der
Verwendung unterschiedlicher Reglerparameter bei bestimmten Drehzahlen
oder Lastsituationen.
Und es koennte auch einfacher sein erst einen I-Regler fuer den
Motorstrom zu bauen und dem dein Drehzahlregler zu ueberlagern. Oder du
linearisiert die Regelstrecke ueber ein Array falls du genug Platz im
Flashrom hast.
Und dann kommt als Zusatzboni so sachen wir Losbrechmoment beim
anfahren, Spiel in einem Getriebe, schwingungen im Antrieb wenn du
federnde Elemente in deiner Mechanik hast, Alterung, usw....
Regelungstechnik ist interessant, aber nicht einfach.
Olaf
Hallo Olaf,
danke für deine Ausführungen!
sehr interessant, die ganze Thematik.
Gibt es eine Faustregel, nach der ich die notwendige, minimale
Abtastfrequenz bestimmen kann?
Und:
Was ich noch feststelle ist, wenn ich für die P- I- und D-Anteile ganze
Zahlen grösser 1 verwemde, dann wird mein regler_ausgang sehr schnell
sehr gross. Aber die ganzen Variablen möchte ich eigentlich höchstens in
int-Werten speichern, und die haben bei meinem 8051 halt 16 Bits (und
nicht wie auf dem PC 32). Kann ich das ganze irgendwie sinnvoll
skalieren?
Weiter habe ich noch das Problem, dass mein Sollwert, den ich vorgebe,
eine Zahl zwischen 0 und 1023 ist (10 Bit ADC). Die PWM wird aber nur
über einen Wert zwischen 0 und 255 bestimmt! Auch die Drehzahl hat
wieder einen anderen Zahlenbereich. Wie kann ich denn das ganze
skalieren, dass am regler_ausgang nie mehr als 255 raus kommt? kann ich
das dem Regler irgendwie "sagen", sodass er "weiss", dass er gar nie
über 255 raus kommen kann?
Den Tip mit dem Schrittweisen entwickeln fand ich gut. Mach doch erst
mal einen P-Regler. Der ist sehr einfach.
1) Rechne die Differenz zwischen der Soll-Drehzahl und der Ist-Drehzahl
aus
2) der neue PWM-Wert ist die Differenz Mal einer Konstante (P)
Die Abtastfrequenz mußt Du möglichst konstant machen. Für einen Motor
würde ich zunächst mal 1kHz nehmen. Das sollte Dein 8051 locker
schaffen. Damit hast Du schonmal die Hälfte von einer verünftigen
Regelung. Beim P-Regler brauchst Du Dir auch keine Gedanken machen, daß
Wertebereiche überschritten werden. Es ist eben nur eine einfache
Multiplikation.
Du mußt Dich jetzt auch nicht mit den Grundlagen der Regelungstechnik
befassen, das ist verschwendete Zeit. Zumal die Mathematik ziemlich
abschreckend sein kann. Für einen PID-Regler kann man ziemlich einfach
die gute Regelparameter finden, mit Ziegler-Nichols.
mfg, Stefan.
Für Reglerfragen empfehle ich gerne diese Erklärung:
http://www.rn-wissen.de/index.php/Regelungstechnik
Bei einem Motor ist die Einstellung über die Erprobung
meist ausreichend.
Mein Tip: mach dir noch einen F/U-Wandler als Testgerät, dann
kannst du die Drehzahl als Spannung auf dem Oskar darstellen.
Damit sieht man das Regelverhalten wie in den Darstellungen.
gruß avr
Hallo,
vielen Dank für den interessanten Link. Und auch für deine Ausführungen,
Stefan.
Ich versuche das jetzt mal umzusetzen.
Allerdings taucht bei mir grade ne Frage auf.
Und zwar:
nehmen wir an, ich regle die Drehzahl auf 100 U/min.
Jetzt wird der Motor stark belastet; der Regler regelt das natürlich
aus, und alles ist okay. Nun verschwindet aber die Belastung wieder; der
Motor dreht jetzt halt ein bisschen schneller, sagen wir mit 150 U/min.
Jetzt will der Regler das ja auch ausregeln, aber dazu müsste er den
Motor noch bremsen können! Wie implementiere ich eine solche bremse am
besten?
Mir ist klar, dass ich den Motor bremsen kann, wenn ich beide Lowside-
oder Highside Mosfet einschalte. Aber wie detektiere ich einen solchen
Fall?
Da stehe ich momentan noch auf dem Schlauch. Ansonsten denke ich, habe
ich soweit begriffen, wie das ganze funktioniert.
Normalerweise braucht man keine Bremse.
Wenn man den Motor nicht mehr ansteuert wird die
Drehzahl automatisch durch die Mechanik kleiner.
Es wird ja etwas angetrieben und da entstehen Verluste.
>Den steuere ich mit einem Mikrocontroller über eine H-Brücke an, sodass>er in beide Richtungen drehen kann.
Damit hast Du auch eine Bremsfunktion. PWM -> 0: Motor steht!
> Mir ist klar, dass ich den Motor bremsen kann, wenn ich beide Lowside-> oder Highside Mosfet einschalte. Aber wie detektiere ich einen solchen> Fall?
Dazu solltest Du wirklich dich ein bischen mit Regelungstechnik
gefassen.
Das, was Du vorgibst (in deinem Fall den Wert für die PWM), nennt man
Stellgröße.
Wenn der Regler sagt, dass die Stellgröße negativ ist, dann heißt das in
Deinem Fall: "bremsen". Nicht alle Endstufen können diesen
Betriebsmodus, man nennt soetwas 4 Quadranten Regler.
Der Rest ist Regelungstechnik, d.h. dreht der Motor zu langsam oder zu
schnell dann kann der Regler ihn erst mit einer gewissen Verzögerung auf
die Soll-Drehzahl zurückregeln. Dies nennt man Einschwingverhalten und
hängt unter anderen von der Dämpfung und Motorlast ab.
Der Motor selbst kann ja auch nicht sofort von einer Drehzahl zur
anderen springen, sondern ändert seine Drehzahl kontinuierlich zur Last.
>Der Motor selbst kann ja auch nicht sofort von einer Drehzahl zur>anderen springen, sondern ändert seine Drehzahl kontinuierlich zur Last.
Das ist genau der Punkt an dem man etwas aufpassen sollte. Wenn der
Motor etwas größer ist(so ab 20W reicht schon), und man dann eine
direkte Drehrichtungsumkehr vorgibt können in abhängigkeit von der
Spannungsquelle schon ganz beachtliche Ströme fließen. Bei 12V und 20W
Motor könenn das schon mal leicht 60A werden. Damit hab ich mir schon n
paar Mosfets zerstört. Verhindern kann man das ua. mit einer
unterlagerten Stromregelung. Dann gibt der Drehzahlregler nicht direkt
die PWM für die Mosfets vor sondern den Sollwert für den Stromregler.
Und der Stromregler stellt dann die PWM. Das hat neben den
Sicherheitsfunktionen auch noch Regeleungstechnisch große Vorteile, da
man damit das dynamischere System direkt regeln kann und nicht erst den
Umweg über die Drehzahl machen muss.
Hmm, das mit der Bremse werde ich vorerst noch weg lassen.
Zuerst soll mein PID-Regler funktionieren! Das versuche ich grade zu
programmieren. Es geht so halbwegs.... ;-)
Ich meld' mich dann wieder.
Hallo, ist zwar in Basic...
Bascom Beispiel von "ELEKTOR"
Ein Permanent-Magnet soll mittels eines Elektromagneten genau so stark
angezogen werden, dass er in der Schwebe verharrt.
Die Stellgröße soll hier je nach System gedämpft wirken. Das Verhalten
des Reglers wird durch Differenzalgleichungen beschrieben.
Der P-Anteil ändert seine Größe proportional zur Regelabweichung
(Sollwert-Istwert). Dies wirkt nur auf die KP Verstärkung.
Das D-Glied eines Reglers ist ein Differenzierer, welcher immer mit dem
P-Anteil oder (I-Anteil) gemeinsam auftreten muss. Der D-Anteil entsteht
durch die Regelabweichung über die Zeit und wird mit der Nachstellzeit
multipliziert. Er ist nicht von der Regelabweichung abhängig, sondern
nur von der Änderungsgeschwindigkeit. Große Nachstellzeiten bewirken
große Änderungen der Stellgröße und bringen damit oft Unruhe in die
Regelung.
Ein Integralanteil wird dann verwendet, wenn die Regelabweichung
möglichst genau auf Null gebracht werden soll. Er wird hier nicht
verwendet, weil immer mit einer Regelabweichung gearbeitet wird und nur
die Regelverstärkung verändert wird.
'
'z.B. mega88
'Pin19 AD6 Sensor Eingng
'Pin10 PD6 Ausgang
'-----------------------------------------------------------------------
------------
' PD REGLER
'-----------------------------------------------------------------------
------------
' S1 At Pb3 = Up
' S2 At Pb4 = Down
$regfile = "mxxdef.dat"
$crystal = xxxxx
Dim N As Byte
Dim X As Integer
Dim Y As Single
Dim Z As Single
Dim Xold As Single
Dim Xp As Single
Dim Xi As Single
Dim Xd As Single
Dim P As Single
Dim I As Single
Dim D As Single
Config Adc = Single , Prescaler = 32 , Reference = Off ' AD-Wandler
starten
Start Adc
Config Timer0 = Pwm , Prescale = 1 , Compare A Pwm = Clear Down ,
Compare B Pwm = Clear Down
P = 0.1
D = 60
Do
If Pinb.3 = 0 Then P = P + 0.0002 'Taster SW1
If Pinb.4 = 0 Then P = P - 0.0002 'Taster SW2
X = 0
For N = 1 To 8
X = X + Getadc(6)
Next X
X = X / 8
If X < 512 Then X = 512 ' hier im Beispiel - nur der Bereich 512 bis
1023 ist für den Regler verwendbar
Xp = X - 512
Xp = Xp * P
Xd = X - Xold
Xold = X
Xd = Xd * D
Y = Xp + Xd
Y = Y / 2
If Y > 255 Then Y = 255
If Y < 0 Then Y = 0
Pwm0a = Int(y) 'Ausgang PWM
Loop
mfg
albert