Immer noch Fragen zu PI-Regler

Gast #726661
Lesenswert?

Hallo Leute,
also ich habe schon vor paar Tagen ein paar Fragen zum Thema PI-Regler 
in C programmieren gehabt, siehe:
[[Beitrag "PI-Regler für GS-Motor"]]

Einiges ist mir noch überhaupt nicht klar.
Ich möchte einen Gleichstrommotor regeln.
Angetrieben wird dieser Motor mit PWM, ich hab es so realisiert, dass 
ich einen Timer mitlaufen lasse mit Reloadregister= FCE0. Bei bestimmten 
Ereignissen hab ich dann nen Signalwechsel an den Pins, die dann zum 
Motortreiben führen. Also am Anfang sag ich: P6 = 0, P7 = 1; wenn der 
Timerwert mit einem Registerwert CC30 übereinstimmt (compare mode), dann 
P6=1, P7 =0; wenn der Timer abgelaufen ist, dann wieder P6 =0, P7 =1 
usw.

Das heißt mein Signal hat eine Periode von FFFF-FCE0 und die Breite der 
pos. Periode ist Wert von CC30-FCE0.
Wenn die Breite des pos. Impulses  = Breite des neg. Impulses 
(FFFF-FCE0)/2 = 400dez , dann dreht sich der Motor nicht, denn der 
Effektivwert der Spannung = 0V. (falls das einer kritisch hinterfragen 
mag, das ist wirklich so, ich hab es schon ausprobiert).

Mit der Stellgröße des Reglers möchte ich Einfluß auf PWM nehmen, d.h. 
die Breite des pos. Impulses beeinflussen und zwar nur des pos. Imp. 
weil mein Motor sich nur in eine Richtung drehen muss.

Eingentlich müsste ich die Stellgröße auf 2^16 begrenzen, weil sich sich 
ja aus der Differenz zweier Registerinhalte berechnet, allerdings und 
jetzt kommt endlich die Frage: meine Stellgröße bewegt sich nur im 
Bereich zw. 400dez und 800dez, denn sonst würd sich der Motor ja in 
andere Richtung drehen. Also müsste ich die doch nur auf 1024 begrenzen, 
oder????
Später verwende ich sie in einer unsigned long int variable, also 
vielleicht doch auf 2^16 begrenzen???
Gast #726875
Lesenswert?

Alle. Die Rechnung hat einen Raum von 2^16, genannt Integer. Macht Sinn. 
Das Stellglied ist schon bei 400+400 am Anschlag. Du willst nur positiv 
aussteuern. Dann ist der Steuerbereich noch 400. Dann wuerde ich den 
Rechenbereich auch auf 128 * 400 begrenzen.

Man bildet den 2^16er Raum auf 400 ab und zaehlt noch 400 dazu. Nein ?

If (Rechnung > 128*400) then Rechnung:=128*400;
Stellglied:= 400+ Rechnung div 128;

Das div 128 ist dasselbe wie Rechtsschieben 7
Gast #729817
Lesenswert?

Wir erniedrigen den Wertebereich von kleiner 65535 auf 400, am 
Guenstigsten ist mit 128 dividieren. Eine Division mit 128 ist sieben 
Stellen nach rechts schieben. Damit wir nicht zuviel bekommen bBegrenzen 
wir zuerst auf 128*400. Alles was groesser ist wird auf 128*400 gesetzt. 
Nach der Division erhalten wir somit als maximum 400.

Nein ?
Gast #729825
Lesenswert?

Also 400dez ist ja (FFFF-FCE0)/2. Bei FCE0 fängt mein Timer an zu 
zählen.
Wenn der WErt des Timers den im CC1_C30 entspricht, gibt es nen 
Interrupt und nen Flankenwechsel.
Ich hab mir überlegt die Pulsbreite des PWM-Singales mit HIlfe von 
CC1_C30 zu steuern. Das heißt der Wert in diesem Register wird in 
Abhängigkeit der Stellgröße gesetzt. So wie ich es verstanden hab, ist 
die Stellgröße die Pulsbreite. Der Wert des CC1_c30 darf sich nur im 
Bereich zwischen FE6F und FFFF bewegen. Die Differenz beträgt dann genau 
400dez.
Also hab ich die Stellgröße so begrenzt:

//       Begrenzung des Stellenwertes auf die maximale Größe
1
if(pi_r.Stellwert<65135)  // Begrenzung nach unten, also auf FE60
2
{pi_r.Stellwert = 65135;} 
3

4
if(pi_r.Stellwert>65535)  // Begrenzung nach oben, also auf FFFF
5
{pi_r.Stellwert =65535;}

Oder hab ich da nen Denkfehler??
Gast #729848
Lesenswert?

<Dh den Regelbereich von irgendwas kleiner 65k (400*128) erniedrigt man
auf 400 und addiert diese zu 0xFE60 fuer das Stellglied.>

Worauf bezieht sich diese Aussage? Was sie an mich gerichtet?
Gast #729870
Lesenswert?

Also meine Regler-Funktion schaut jetzt so aus:
1
unsigned long int Regeln (unsigned long int Istdrehzahl)
2
{
3

4
pi_r.Istwert=Istdrehzahl;
5
pi_r.Regelabweichung = pi_r.Sollwert-pi_r.Istwert;             // e=w-x
6
pi_r.I_Anteil = pi_r.I_Anteil+pi_r.Regelabweichung;            // esum=esum+e
7

8

9
//         Reglergleichung  mit Antiwindup
10

11
if (Begrenzung==1)
12
{
13
pi_r.Stellwert = Kp*pi_r.Regelabweichung;  // ohne Integralanteil
14
}
15
else
16
{
17
pi_r.Stellwert = Kp*pi_r.Regelabweichung + (Ki*pi_r.I_Anteil)/100;  //y=....
18
}
19

20

21
//       Begrenzung des Stellenwertes auf die maximale Größe
22

23
if(pi_r.Stellwert<65135)    // Begrenzung nach unten, also auf FE60
24
{
25
  pi_r.Stellwert = 65135;
26
  Begrenzung = 1;       // Rergler läuft in der Begrenzung
27
 
28
} 
29

30
if(pi_r.Stellwert>65535)    // Begrenzung nach oben, also auf FFFF
31
{
32
  pi_r.Stellwert =65535;
33
  Begrenzung = 1;        // Regler läuft in der Begrenzung
34
}
35

36

37

38
  
39
  return pi_r.Stellwert;                    // Übergabe Stellgröße
40
}

wär nett, wenn ihr noch mal drüber schauen könntet.
Gast #729892
Lesenswert?

Einige Unguenstigkeiten.
-Die Begrenzung wird nie aufgehoben.
-die div 100 ist nicht gut, mach 128.

Nee das wird nichts. Bei welchem Fehler beginnt sich die Stellgroesse zu 
bewegen ?

Mach :
pi_r.Stellwert= 0xFE60 + Kp*pi_r.Regelabweichung;
..

Begrenzung =0;

if(pi_r.Stellwert<0xFE60)    // Begrenzung nach unten, also auf FE60
{
  pi_r.Stellwert = 0xFE60;
  Begrenzung = 1;       // Rergler läuft in der Begrenzung
}

if(pi_r.Stellwert>0xFFFF)    // Begrenzung nach oben, also auf FFFF
{
  pi_r.Stellwert =0xFFFF;
  Begrenzung = 1;        // Regler läuft in der Begrenzung
}
Gast #729933
Lesenswert?

also die Begrenzung hab ich aufgehoben, da hattest du völlig Recht.
Die Division durch 100 hat eigenlich andere Bewandnis und zwar ist das 
meine Ta von 0.01. Ich dividiere duch 100, weil ich beim Multiplizieren 
der int mit  Zahlen < 0 schlechte Karten hab.

<Mach :
pi_r.Stellwert= 0xFE60 + Kp*pi_r.Regelabweichung;
..>

Wo kommt deiner Meinung nach dieser Therm hin? Und wieso soll ich nach 
unten bis FE60 begrenzen? Ich meine, es ist bis FE6F!!
Gast #729941
Lesenswert?

Dein Antiwindup ist Mist. Man läßt den Integralanteil nicht schlagartig 
komplett weg, wenn man in der Begrenzung ist (woraufhin dann keine 
Begrenzung mehr da ist, also wieder rein, wieder raus, wieder rein...), 
sondern begrenzt ihn.
1
if (!Begrenzung)
2
    pi_r.I_Anteil = pi_r.I_Anteil+pi_r.Regelabweichung;  // esum=esum+e

Die andere if-Abfrage und die Formel ohne I-Anteil muß raus.
Gast #729973
Lesenswert?

Meine Punkte.
-Kostanten so schreiben wie sie sind. HexKonstanten in Hex.
-Die Regel Berechnung und das Stellglied trennen. Lieber der 
Uebersichtlichkeit halber nochmals eine zusaetzliche Zeile. In dem Falle 
die Regelung zwischen 0 und irgendwas rechnen, dann auf 
Herunterskalieren auf die 0 bis 400 und dann zum Wert FE6F hinzuzaehlen. 
Ich denke dieser Wert ist sowieso dynamisch, dh Temperatur- und 
allenfalls Betriebsdspannungsabhaengig.
(Firma: 4CKnowLedge) Persönliche Seite #730018
Lesenswert?

Kartoffel wrote:
> ok, und was macht das Ding dann, wenn ich mich in der
> Begrenzung befinde? Wie errechnet sich dann der I-Anteil??

bin zwar kein mechatroniker aber hab trotzdem einen PID Regler 
gecoded...

Also, wenn du in der Begrenzung bist tut der gar nichts mehr (der I 
Anteil).

Allerdings könnte ich dir ein wenig support geben wenn du meinen Code 
aus der Codesammlung verwenden würdest... ^^

lg
Gast #730593
Lesenswert?

@ JÜrgen G. und alle anderen:
Also laut deiner Aussage stimmt ja dann die Aussage des "mechatronikers" 
nicht und mann kann den I-Anteil in der Begrenzung schon weg lassen 
oder?
Wenn nicht, also dann weiß ich überhaupt nicht, wie ich den Windup 
verhindern kann....
Gast #730620
Lesenswert?

sodala, ich hab ein paar Änderungen vorgenommen und poste den Code jetzt 
noch mal, das mit dem Windup ist auch berücksichtigt.
1
//*************************************************************************************
2
//                    Variablen
3
//*************************************************************************************
4

5
//double Ta=0.01
6
//unsigned long int Stellwert_old = 0;
7
bit Begrenzung;
8

9

10

11

12
//*************************************************************************************
13
//                    Prototypen
14
//*************************************************************************************
15
unsigned long int Regeln (unsigned long int Istdrehzahl); // Funktion zum Aufrufen des Reglers
16
void PI_Init(void); // Reglerinitialisierung
17

18

19

20
//*************************************************************************************
21
//                     Funktionen
22
//*************************************************************************************
23
void PI_Init(void)
24
{         
25
pi_r.Kp = 18;
26
pi_r.Ki = 60;
27
Begrenzung=0;
28
pi_r.I_Anteil=0;
29
pi_r.Regelabweichung = 0;
30

31
}
32

33

34

35
unsigned long int Regeln (unsigned long int Istdrehzahl)
36
{
37
  pi_r.Istwert=Istdrehzahl;  
38
  pi_r.Regelabweichung = pi_r.Sollwert-pi_r.Istwert;             // e=w-x
39

40
  //         Antiwindup
41

42
  if (Begrenzung!=1)
43
  {
44
    pi_r.I_Anteil = pi_r.I_Anteil+pi_r.Regelabweichung;            // esum=esum+e
45

46
  }
47

48
  pi_r.Stellwert = pi_r.Kp*pi_r.Regelabweichung + (pi_r.Ki*pi_r.I_Anteil)/100;  //y=....
49

50
  //       Begrenzung des Stellenwertes auf die maximale Größe
51

52
  if(pi_r.Stellwert<65135)    // Begrenzung nach unten, also auf FE60
53
  {
54
    pi_r.Stellwert = 65135;
55
    Begrenzung = 1;       // Rergler läuft in der Begrenzung
56
 
57
  } 
58

59
  else if(pi_r.Stellwert>65535)    // Begrenzung nach oben, also auf FFFF
60
  {  
61
    pi_r.Stellwert =65535;
62
    Begrenzung = 1;           // Regler läuft in der Begrenzung
63
  }
64

65
  else
66
  {
67
    Begrenzung =0;
68
  }
69

70
  return pi_r.Stellwert;                    // Übergabe Stellgröße
71
}

Ich meine, jetzt passt es einigermaßen...das mit dem Skallieren kommt 
no.
Allerdings hab ich jetzt ne Warnung beim Aufrufen der Fkt. PI_Init.
Ich ruf sie in main vor der Endlosschleife auf. Hab es auch schon 
probiert, die Fkt. als extern zu deklarieren, dat geht au net...:-(
Gast #731497
Lesenswert?

Weiter im Text.
Ach übrigens, das mit der Fkt. PI_Init hab ich behoben.
Also : Der Stellwert.
Was sagt er mir denn genau bei einem PWM-Singal. Zur Erinnerung: ich 
bewege mich in einem Bereich zwischen 400 und 800 (Pulsbreite). Bei 400 
steht der Motor, bei 800 dreht er voll auf.
Also ich berechne mich meiner Reglergleichung den Stellwert. Also ich 
hab da noch Probleme zu verstehen was der genau darstellt. Ist das eine 
Zahl im Bereich zwischen 400 und 800? Die Pulsbreite steuer ich ja mit 
einem Register. Muss dann der neu errechnete Reglerstellwert in dieses 
Register reingeschrieben werden?????

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