PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Drehzahl regeln bzw. konstant halten



MrWebLover
19.08.2005, 13:51
Hi @ all,

ich hab da mal ne Frage, die bei euch bestimmt auch schon aufgetreten ist.
Ich möchte eine Regelung für einen Motor implementieren.
Details:
Ich habe einen Motor, der mit 8Bit PWM angesteuert wird.
Am motor ist ein Geber (IR), welcher mir pro Umdrehung einen Impuls
liefert. Mittels ICP bekomme ich einen Wert der zwischen 62500
(16MHz/256) und eben 'nahe' Null liegt. Sprich bei 1200rpm = 20rps bekomme ich einen Wert von 3125.
Nun lege ich fest maximal erlaubte Drehzahl bspw 1200. minimal logischer
weise 0. Nun möchte ich via einer Sollwertvorgabe von 0-255 den Motor
regeln und eben auch konstant halten. Sprich bei einem Wert von 128
sollte der Motor ca. 600 rpm machen und diese auch bei Belastungen halten.
(Nachregeln). Ich hab da schon einiges Versucht, aber noch nix vernüftiges
hinbekommen. Auch PID Regelung hab ich schon versucht, aber ohne Erfolg ...
Hat von euch vielleicht einer sowas schonmal relasiert mittels AVR und avr-gcc ???

Ich bin für jede Idee dankbar und hoffe auf euch !
Vielen Dank an alle die versuchen zu helfen im vorraus ...

Gruß
Torsten

MrWebLover
20.08.2005, 19:02
Na, es gibt unter euch doch bestimmt einige, die so etwas auch für ihren Roboter implementiert haben oder ?

Ich bin euch für jeden Tip dankbar !

Gruß
Torsten

Rage_Empire
20.08.2005, 19:48
such mal im forum unter regler. das ist das, was du vermutlich brauchst.

Volly42
21.08.2005, 08:58
Hallo.

Eigentlich ist die Anordnung so einfach, daß ein PI oder PID-Regler nach ein bißchen probieren mit den Parametern sauber funktionieren sollte.

1. Wie sieht denn Dein Regler aus: Code...?

2. Wann wird der Regler aufgerufen...?

3. Was funktioniert denn eigentlich nicht beim PID?

Gruss
Volly42

MrWebLover
21.08.2005, 12:43
Ok,

erstmal danke für die Antwort(en).

Zu Rage_Empire: Ich habe nicht nur das Forum sondern das ganze INet nach
diesem Thema durchsucht. Also diskrete Regler etc etc etc ...

Zu Volly42:
Ja, das dachte ich eigentlich auch, daß das so funktionieren müsste ....

Hier der PID Code, welcher in einer konstanten Zeit
aufgerufen wird. Sprich für die integration bzw.
differentation wird ein delta t von 1 angenommen,
was ok ist, solange die Abtastzeit konstant ist.
Die Abtastzeit ist hier mit der Zeit zu vergleichen,
die zwischen zwei Aufrufen der PID Funktion liegt.
Als Zeitwert des Aufrufs hab ich schon verschiedene geteste.
10/50/100ms etc. ...

Detailiert :
Zu 2. : Der Regler wird kontinuierlich alle 100ms od. 10ms aufgerufen
Zu 3. : Gute Frage .... Er schwingt eher, bzw. braucht seeehr lange bis der
'auf' macht um vollgas zu geben. Sieht nicht so aus, als daß
er eine Drehzahl hält. Also eben nicht so regelt wie er das sollte

Zu 1. : Ok, hier nun der Sourcecode mit einigen Info's :
Vielleicht hast Du ja hierzu noch eine Ideee ....

Gruß Torsten

---------------

Kp = Verstärkungsfaktor des P Anteils (0-?)
Ki = Verstärkungsfaktor des I Anteils (0-?)
Kd = Verstärkungsfaktor des D Anteils (0-?)
sollwert = 0-255 // 0 = Stillstand / 255 = max. zulässige Drehzahl
istwert = 0-255 // Wird aus dem istwertcnt berechnet, dieser wird durch ICP gespeichert
Y = ist als signed int 32 Bit deklariert
soll und istwert sind jeweils unsigned char (8Bit)

......
// Hier wird nun der Zählwerd der Drehzahlmessung in ein en Wert
// umgerechnet, der dem sollwert entspricht, also 0 - 255

// Zuerst prüfen, ob der Timer1 übergeleufen ist = 0 Umdrehungen pro Sekunde = stillstand
if (istwertcnt >= 62500)
{
istwert = 0;
}
else if (istwertcnt > 50000)
{
// Hier ebenso, nur, wenn der Sollwert auf 0 ist, wird dies auch dem istwert zugeschrieben
// wenn er auch noch minimal
if (sollwert == 0)
istwert = 0;
else
istwert = 1;
}
else
{
istwert = (257 - (istwertcnt/244));
}


// Ermitteln des Fehlersignals
Error = sollwert - istwert;
Error_sum += Error;

if (Error_sum > 32767)
Error_sum = 32767;

if (Error_sum < -32767)
Error_sum = -32767;

// P Anteil - berechnen
Y = Kp * Error;

// I Anteil - berechnen
Y += Ki * Error_sum;

// D Anteil
Y += Kd * (istwert - istwert_alt);
istwert_alt = istwert;

// Begrenzung der Ausgangspegel (auf 16Bit uint)
if (Y < 0)
Y = 0;

if (Y > 0xFFFF)
Y = 0xFFFF;

// PWM ausgeben
OCR2 = (Y>>8);
......

MrWebLover
21.08.2005, 22:03
Hi @ all,

ich hab das Problem gelöst. Der Regler arbeitet nun einwandfrei.
Das Problem lag bei mir selbst, bzw. ich hatte einen Denkfehler
bei der istwert Berechnung. Nun errechne ich den soll- bzw.
istwert als rps (Rounds per Second) und das funktioniert sehr gut.

Danke an alle, die versucht haben zu helfen.

Gruß
Torsten