Forum: Mikrocontroller und Digitale Elektronik Probleme mit I-Anteil / Regler


von Willi (Gast)


Lesenswert?

Hi,

ich versuche gerade einen Motor in der Position zu regeln. Dazu möchte 
ich einen PI-Regler verwenden. Wenn ich die Regelung nur mit dem 
P-Anteil des Reglers laufen lasse, funktioniert das soweit schon ganz 
gut, es gibt leichte Überschwinger.

Nur sobald der I-Anteil dazu kommt, werden die Überschwinger größer und 
der Motor regelt sich nicht mehr ein.

Hier die Regelroutine:
1
void PID_Init(void);
2
void PID_Cyclic(int, int, PID_Einstellung*);   // Struktur PID_Einstellungen erzeugen
3
4
5
PID_Einstellung Regler1;              // Variable Regler1, je nach Bedarf erweitern
6
7
8
void PID_Init(void)                  // In der Init müssen die Reglereinstellungen gemacht werden
9
{
10
  Regler1.y=0;
11
  Regler1.Ta=2;
12
  Regler1.I=1;
13
  Regler1.D=0;
14
  Regler1.Kp=1;
15
  Regler1.esum=0;  
16
  Regler1.e=0;                  // Für weiteren Regler einfach Neue Variable erstellen
17
  Regler1.ealt=0;                  // und hier Werte mit Regler2.xx=0 einstellen
18
}
19
20
void PID_Cyclic (int x, int w, PID_Einstellung* PID)
21
{    
22
  PID->e = w - x;                             // aktuelle Regelabweichung bestimmen
23
  if ((PID->y < 100)&&(PID->y > 0))           // bei Übersteuertem stellglied Integration einfrieren
24
  {                                           // (Anti-Windup)
25
        PID->esum = PID->esum + PID->e;       // Summe der Regelabweichung aktualisieren  
26
   }
27
28
   else if ((PID->y > (-100))&&(PID->y < 0))  // bei Übersteuertem stellglied Integration einfrieren
29
  {                                           // (Anti-Windup)
30
        PID->esum = PID->esum + PID->e;                               // Summe der Regelabweichung aktualisieren  
31
   }
32
33
34
    PID->y = (PID->Kp*PID->e) + (PID->I*PID->Ta*PID->esum); // Reglergleichung
35
36
   stell = PID->y;
37
38
   if(stell >= 100)
39
   stell = 100;
40
  
41
   if(stell <= (-100))
42
   stell = (-100);
43
                                    
44
45
   if(stell <0)     //Motor Rechtslauf
46
   {
47
   OCR1A = (((stell * 16) / 10) +160 );   //Geschwindigkeit über PWM
48
   PORTB |= (1 << PB0);
49
   PORTB &= ~(1 << PB3);
50
   }
51
52
   else if(stell >0)   //Motor Linkslauf
53
   {
54
   OCR1A = (((stell * (-16)) / 10) + 160);  //Geschwindigkeit über PWM
55
   PORTB |= (1 << PB3);
56
   PORTB &= ~(1 << PB0);  
57
   }
58
59
   else                     //Motor Stillstand
60
   {
61
   PORTB &= ~(1 << PB3);
62
   PORTB &= ~(1 << PB0);
63
64
  }
65
}


Verstehe auch nicht wie der I-Anteil das überschwingen verhindern soll, 
da esum doch immer größer und somit die Geschwindigkeit auch bei kleiner 
werdender Regelabweichung nicht wirklich abnimmt.


Vielleicht hat jemand nen Tip für mich?


Gruß, Will

von OliverSo (Gast)


Lesenswert?

Wo ist denn der Code für den Regler her? Die Reglergelichung ist zwar 
richtig, aber nicht für reale digitale Implementierungen geeignet.

Der I-Anteil ist bei deinem Abtastregler von der Abtastrate abhängig. 
Wahrscheinlich ist da "1" schon viel zu groß, um noch ein stabiles 
Regelverhalten zu gewährleisten.

Die Abtastzeit finde ich jetzt nicht, aber wenn dein Regler z.B. mit 
1kHz läuft, läuft die Stellgröße bei einem I-Anteil von 1 schon bei 
einer Regelabweichung von 1 (kleiner geht beides ja nicht) innerhalb von 
0.1s in die Begrenzung. Das das schwingt, ist wohl klar.

Fazit: I-Regler (und D-Regler) brauchen mindestens Festkommaarithmetik, 
oder gleich floats.

Oliver

von Willi (Gast)


Lesenswert?

Hallo Oliver,

Danke für die schnelle Antwort. Also die Abtastrate beträgt 100Hz. Habe 
auch schon daran gedacht die Abtastvariable kleiner als 1 zu machen, 
jedoch sind beim Attiny25 nur noch 10% Speicher verfügbar und da wird 
das mit float und den GCC verdammt knapp.

Was kann ich da noch tun, außer nem anderen Controller zu nehmen?

von Olaf (Gast)


Lesenswert?

> und da wird das mit float und den GCC verdammt knapp.

Ich halte es fuer ziemlichen Unsinn wegen so einem einfachen Problem
gleich mit Fliesskommazahlen rumhampeln zu wollen.


> Was kann ich da noch tun, außer nem anderen Controller zu nehmen?

Verschiebe dein Binaerkomma einfach um ein paar Stellen.
Man benoetigt meist nur Parameter und Ausgangsgroessen mit 8Bit. In so 
einem Falle wuerde ich mit 16Bit rechnen und vor der Ausgabe einfach 
etwas nach rechts schieben.

Es zahlt sich aber aus bei Reglern mit 16Bit Prozessoren zu arbeiten. 
Mit ein Grund warum ich R8C fuer besser als AVR halte. .-)

Olaf

von Karl H. (kbuchegg)


Lesenswert?

Willi wrote:
> Hallo Oliver,
>
> Danke für die schnelle Antwort. Also die Abtastrate beträgt 100Hz. Habe
> auch schon daran gedacht die Abtastvariable kleiner als 1 zu machen,
> jedoch sind beim Attiny25 nur noch 10% Speicher verfügbar und da wird
> das mit float und den GCC verdammt knapp.
>
> Was kann ich da noch tun, außer nem anderen Controller zu nehmen?

zb. indem du den integralen Anteil
   PID->I*PID->Ta*PID->esum
noch durch 10 dividierst (*). Dann entspricht ein I Wert von 1
real einem Wert von 0.1. Du hast dadurch eine Kommastelle gewonnen.



(*) in der Praxis wird man nicht 10 nehmen, sondern eine 2-er
Potenz, damit die Division für den µC trivial wird.

von OliverSo (Gast)


Lesenswert?

Weil float viel Platz braucht, schrieb ich ja auch:
>I-Regler (und D-Regler) brauchen mindestens Festkommaarithmetik,

Du machst z.B. einen Schwingversuch nach Ziegler und Nichols, bestimmst 
daraus die analogen I- und P-Parameter, verrechnest die mit dem 
Verstärkungsfaktor deiner Hardware, und bekommst dann z.B. raus, daß 
sich dein I-Regleranteil bei einer Regler-Rechenregelabweichung von 1 um 
0,05/s Reglerausgabewert erhöhen muß. (Hoffentlich ist deine PWM 
linear...)

Um jetzt bei 100 Hz 0.05/s zu bekommen, musst du den I-Anteil mindestens 
mit den Faktor 20 skalieren. Jetzt noch Rundungseffekte berücksichtigen, 
die Stufung der Einstellwerte berücksichtigen (willst du auch 0.045 
Einstellen können, oder sogar 0.0495), sowie die Wertebereiche der 
Variablen im Blick behalten, und schon bist du fertig :-)


@Olaf

Das auch 8-bit Prozessoren mit 16-bit-Integern rechnen können, weisst du 
aber schon, oder? Und bei 100Hz Abtastrate rechnet sogar ein Tiny mit 
128bit, wenn es sein muß :-)

Oliver

von Willi (Gast)


Lesenswert?

Danke für die Tips,

das mit dem verschieben der Kommastelle klappt, der Regler läuft um 
einiges besser. Jedoch sind immer noch ganz schöne Schwinger drin und ab 
drei Kommastellen merkt man auch keine Verbesserung mehr..


Vielleicht kann ich durch ändern der Abtastrate deas Reglers noch 
einiges rausholen, was meint ihr? Die 100Hz sind ja nicht wirklich 
schnel, vielleicht mal 1kHz versuchen.

Vielleicht auch ne andere PWM-Frequenz?

von OliverSo (Gast)


Lesenswert?

Nachtrag: Die Hardwareverstärkung steckt im P-Anteil auch drin, die 
brauchst du nicht mit reinzurechnen.

Was auch geht, ist, zunächst mal den Skalierungsfaktor richtig groß zu 
wählen. Bei einer max. Stellgröße von 100 und einer geschätzten max. 
Regerabweichung von auch 100 (wild geraten :-) kommst du mit 16-bit 
Intergern mal gerade bis 3, was nicht viel ist. Als 32 bit long, da ist 
dann satt Platz, Faktor 1000 oder 10000, oder besser 4096 oder 
8192,(dann dividiert es sich leichter), und dann ausprobieren.

Oliver

von Willi (Gast)


Lesenswert?

So,

also mit der Änderung der Abtastrate läuft das ganze schon sehr gut.

Würde gerne die Variablen mit long int nutzen, leider reicht der 
Speicher des Controllers dafür nicht aus.

von klausy (Gast)


Lesenswert?

benutzt du jetzt den PI Regler für die Drehzahl- oder die 
Endlagenregelung?

von Willi (Gast)


Lesenswert?

Für die Endlagenregelung....

von Gast (Gast)


Lesenswert?

Das Thema liest sich so, als ob Willi sein Regler durch Try and error 
auslegen will. Dabei gibt es doch einfache und leicht anzuwendene 
Verfahren wie das schon angesprochene Verfahren von Ziegler und Nichols, 
um seine Regler halbwegs vernünftig auszulegen.

von Olaf (Gast)


Lesenswert?

> Das Thema liest sich so, als ob Willi sein Regler durch Try and error
> auslegen will.

In dem Falle kann der Thread noch ein paar Jahre dauern. :-)

> Verfahren wie das schon angesprochene Verfahren von Ziegler und Nichols,
> um seine Regler halbwegs vernünftig auszulegen.

Dazu wuerde ich auf jedenfall raten um erstmal ein paar nicht ganz so 
boese Basiswerte zu haben. Danach wird man immer noch etwas nach Gefuehl 
dran drehen muessen.

Olaf

von He Ro (Gast)


Lesenswert?

> Für die Endlagenregelung....

Für die Endlagenregelung kannst du dir den I-Anteil eigentlich auch 
sparen, da die Strecke bereits I-Anteil hat (der Motor integriert ja die 
anliegende Spannung auf zu einer Position)

Aber wie auch immer du möchtest...

MfG, Heiko

von klausy (Gast)


Lesenswert?

nen Lageregler ist immer ein reiner P-Regler! Normalerweise baut man 
eine Kaskadenregelung auf, also: Lage-> Drehzahl-> Strom -> 
Stellglied(PWM)
Wenn jetzt dein Lageregler eine Differenz zwischen ist und soll hat 
würde der I-Anteil aufaddiert werden-> (Drehzahlregler soll mehr 
Drehzahl machen...)
Wenn jetzt die Endlage erreicht ist soll die Drehzahl Null sein, aber 
dein I-Anteil hat doch einen Wert größer Null. -> Also fährt er übers 
Ziel hinaus,  der Regler merkt daß er zu weit ist und subtrahiert so 
lange den I-Anteil bis er neg. wird -> Der Antrieb fährt Rückwärts -> 
und dann wieder von vorne...
Ein schwingungsfähiges System!
In nem Bodedigramm sieht man ja auch das die Phase dieses Gesamtsystems 
bei -180° liegt, also auf der Stabilitätsgrenze.
Denk mal drüber nach!

von OliverSo (Gast)


Lesenswert?

>da die Strecke bereits I-Anteil hat

Nö, hat sie nicht. Wenn du auf die Strecke eine Störgröße drauf gibst, 
bleibt bei einem P-Regler eine bleibende Regelabweichung.

Oliver

von klausy (Gast)


Lesenswert?

>Nö, hat sie nicht...
Was is denn dann bitte das Intergral der Drehzahl? Wohl die Lage oder!?

von OliverSo (Gast)


Lesenswert?

>(der Motor integriert ja die anliegende Spannung auf zu einer Position)

Tut er nicht. Die anliegende Spannung ergibt einen Strom durch den 
Motor, daraus ergibt sich ein Drehmoment. Diese aufintegriert ergibt 
eine Drehzahl, die wiederum aufintegriert eine Position ergibt.

Nach deiner Argumentation wäre da ja schon ein I²-Verhalten eingebaut - 
ist es aber nicht. Die Stellgröße ist trotzdem beim P-Regler rein 
proportional zur Regelabweichung, und eine konstante Regelgröße ergibt 
eine konstante Änderung der Position. Nix I-Anteil.

Olver.

von klausy (Gast)


Lesenswert?

RICHTIG!!!!!!!!!!!!!!!!!!!!!!!!!!!!

von OliverSo (Gast)


Lesenswert?

Friedensangebot: Die Strecke hat natürlich integrierendes Verhalten. 
Sogar gleich doppelt. Wenn wir uns auf die Formulierung: "Ein 
zusätzlicher I-Anteil im Regler führt nur zu Stabilitätsproblemen" 
einigen können, passts doch, oder?

Oliver

von Willi (Gast)


Lesenswert?

So Leute, vielen Dank!

Hab den I-Anteil wieder entfernt, Parameter beim P-Regler etwas 
angepasst und mal die PWM Frequenz etwas erhöht, damit der Motor nicht 
so quietscht.

Läuft supi, vielen Dank! Und gelernt hab ich auch noch was.


Gruß Will

von Klausy (Gast)


Lesenswert?

>Wenn wir uns auf die Formulierung: "Ein
>zusätzlicher I-Anteil im Regler führt nur zu Stabilitätsproblemen"
>einigen können, passts doch, oder?

OK!

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
Noch kein Account? Hier anmelden.