I Regler - bleibende Regelabweichung

Gast #1251296
Lesenswert?

Hallo Ihr,

ich steh mal wieder auf dem Schlauch.

Versuche gerade einen PI-Regler zu programmieren. Prinzipiell tuts auch.
Ich bekomme nur meine Regelabweichung nicht weg.

Wenn ich den I-Regler alleine betreibe, dann bleibt auch eine Differenz 
übrig.

Das ganze Regelt die Drehzahl eines Motors. Der Code sieht 
folgendermaßen aus. Vielleicht hab ich ja einen Dennkfehler drin:


global:  s32 y_I=0;
#define NMAX 3500
#define Kp 0
#define Ki 6  //schwingt bei 7 (besteht eigentlich aus TA*Ki TA ist 1ms)

w ist der Sollwert 0-100%
x ist der Istwert 0- 30.000 (U/min) im Moment nur bis 4000 U/min

u32 closed_loop_control(u32 w, u32 x)
{
 s32 y;  //neue Stellgröße
 s32 e;  //Regelabweichung

 s32 y_P;  //Stellgröße des P Anteils

  //w in Drehzahl umrechnen
   w = w * NMAX / 100; //Sollwert

   e = (s32) w - (s32) x; //Drehzahldifferenz zwischen Soll und Ist

   y_P = Kp * e;  //Proportionalwert

   y_I = Ki * (y_I + e); //alter I-Wert + aktuelle Regelabweichung
   y_I /= 10;  //Ki <1

   y = y_P + y_I;

   /* Rückrechnung auf % */
   y = y * 100 / NMAX;

   if (y > 100)
   {
      y = 100;
   }
    if (y < 1)
   {
      y = 0;
   }
 return((u32)y);
}

Grüße,
Michael
Gast #1251323
Lesenswert?

Etwas viel leere Rechnung im Code. Indem man die tatsaechliche Drehzahl 
aussen laesst, und mit dem Messwert rechnet, kann man die Skaliererei ( 
NMAX/100 ) weglassen.

usw.

Ich wuerd den code aml im simulator laufenlassen.
Gast #1251325
Lesenswert?

Hi
ich weiss zwar nicht, ob es das Problem löst aber:
1
   y_I = Ki * (y_I + e); //alter I-Wert + aktuelle Regelabweichung
ist nicht ganz korrekt. Du solltest eher eine statische Variable
errorsum haben:
1
static s32 errorsum;
2
errorsum += e;
3
if(errorsum > MAX_ERROR) errorsum = MAX_ERROR;
4
if(errorsum < MIN_ERROR) errorsum = MIN_ERROR;
5

6
y_I = Ki * errorsum;
7
..

Damit wird nur der Fehler mit Ki multipliziert. In deinem Code
steckt das ki in y_I drin und wird dann nochmal mit ki multipliziert.

Hab jetzt nicht genau auf die signed/unsigned Variablen in deinem Code
geachtet, aber das ist auch öfters ein Fehler.

Gruß
Gast #1251399
Lesenswert?

1
>   y_I = Ki * (y_I + e); //alter I-Wert + aktuelle Regelabweichung
>ist nicht ganz korrekt.

Würde ich so auch nicht machen, ist aber trotzdem (fast) korrekt.
Im alten Wert y_I ist ja die Summe aller vorheriger e's enthalten.
Allerdings darf man nicht alles erneut mit Ki multiplizieren:
1
y_I = y_I + Ki*e;

Ich würde mal debuggen, ob die Stellgröße überhaupt mal den Maximalwert 
erreicht, bzw. ob dieser Maximalwert y = 100 überhaupt in der Lage ist, 
den Motor auf Solldrehzahl zu bringen!
Gast #1251407
Lesenswert?

>Würde ich so auch nicht machen, ist aber trotzdem (fast) korrekt.
>Im alten Wert y_I ist ja die Summe aller vorheriger e's enthalten.

Naja, das Problem bei der ersten Lösung ist, dass im y_I die Summe
aller e's multipliziert mit ki drin ist und dann noch mal multipliziert
wird.

>Allerdings darf man nicht alles erneut mit Ki multiplizieren:
>y_I = y_I + Ki*e;

Ja so stimmts.
Gast #1252459
Lesenswert?

Danke für die Tipps.

PID geht inzwischen auch. Wie aus dem Lehrbuch, Überschwinger, 
Regelabweichung, langsam... nun alles eine Frage der richtigen 
Parameter.

Solldrehzahlabhängige Regelfaktoren hatte ich vor. Ohne das wirds nicht 
ordentlich gehen.

Merci!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren