www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Kurze Frage zum PI- Regler


Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich bin dabei mich in den PI- Regler einzuarbeiten.
Ich habe eine blöde Frage zu der Stellgröße (y) ich möchte dass der 
Regler ein
Wert zwischen 0 und 255 ausgibt.
Für y habe ich den Datentyp int genommen, wenn jetzt der Regler aber 
runter
regelt läuft der Wert in den negativen Bereich und um das zu vermeiden 
habe
ich den begrenzt.

        if(y1<0)   {y=0;  } else {y=y1;}
  if(y1>255) {y=255;} else {y=y1;}

Das funktioniert aber nicht, sobald die Variable y1 im negativem Bereich 
ist,
springt der y auf 255 anstatt auf 0.

Wo ran liegt das was mache ich falsch?

Autor: hugo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was hast du denn für ein Datentyp für y1 genommen? char ? dann kann y1 
nicht <0 oder >255 werden!
Ohne Quelltest kann man nicht viel zum fehler sagen

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uint16_t ReadChannel(uint8_t mux);

        uint16_t w;
  uint16_t x;
  uint16_t e;
  uint16_t esum;
  uint16_t Kp=1;
  uint16_t Ki=1;
  uint16_t Kd;
  uint16_t y;
  uint16_t yi;
  uint16_t y1;

ISR (TIMER1_COMPA_vect)
{
  esum = esum + e;
  yi = Ki * esum;
}

int main (void)
{
  //Initialisierung des LCD Displays 4 Bit Mode
  LCD_Init();

  //Löschen des Displays
  LCD_Clear();

  //Initialisierung von TIMER1
  TCCR1B |= (1 << CS12 | 1 << WGM12 | 1 << CS10);
  TCCR1A = 0b00000000;
  TIMSK |= (1 << OCIE1A);
  OCR1A = 15624;

        //Initialisierung von TIMER2 (PWM OC2)
  DDRD |= (1<<7)|(1<<4);
  TCCR2 |= (1<<WGM20|1<<COM21|1<<COM20|1<<CS20|1<<CS21|1<<CS20);
  DDRD |= (1<<7);

        //Globale Interrupts freischalten
  sei();
__________________________________________________________________
  do
  {
  w = ReadChannel(1);
  x = ReadChannel(7);
  e = w - x;
  y1 = Kp * e + yi; //yi im Interrupt


  if(y1<0)   {y=0;  } else {y=y1;}
  if(y1>255) {y=255;} else {y=y1;}
  OCR2 = y ;
  //Ausgabe eines Textes auf dem LCD Display
  LCD_Print(0,0,"Soll  = %i          ",w);
  LCD_Print(1,0,"Ist   = %i          ",x);
  LCD_Print(2,0,"Diff  = %i          ",e);
  LCD_Print(3,0,"Stell = %i %i       ",y,y1);

    }
  while(1);

}
ende
    +
noch die ADC Funktion aber die Funktioniert ja.

So das ist mein Quelltext.

@hugo

y1 ist auch uint_16t

Autor: Jochen S. (schiffner)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dein yl ist ein uint16_t (unsigned int), der kann doch gar nicht negativ 
werden (wie schon gesagt), probier mal int16_t

Autor: name (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich würde aus persönlicher erfahrung behaupten, dass du das mit der 
auflösung nur schwer stabil hinkommst. angenommen dein soll ist 128, 
deine maximal mögliche regelabweichung 50 und schon kann dein P nur noch 
2 sein ohne über deinen maximalwert 255 rauszuschießen. so ungefähr: 128 
+ (2*50) = 228

wenn du extrem grob auflöst und richtig gut aufpasst beim skalieren 
deiner werte geht es vielleicht irgendwie.

die andere frage ist wofür du den I-Anteil brauchst, bzw. ob du den 
wirklich brauchst und nicht vielleicht mir einer minimalen 
regelabweichung leben kannst. würde es dir zumindest wesentlich 
einfacher machen und dein system wäre stabiler.

schönen abend noch!

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist komisch aber der Wert läuft in den negativen Bereich über.

Autor: Tupf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du solltest die variablen in der interrupt funktion auch zu volatile 
definieren.

Bis dann ...

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Regler ist eine reine Übungsaufgabe, der leider noch nicht 
funktioniert.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Tupf

wie meinst du das? kannst du es näher erklären? Ich bin noch ein 
ziemlicher Anfänger.

Autor: Tupf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gehe bitte in das GCC Forum. Das Forum kannst du links in der Spalte 
anklicken. Dann suche im Betreff nach volatile. Da gibt es hunderte von 
Erklaerungen.

Viel Spass ...

Autor: Waldo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich würde erstmal grundsätzlich den PI-Regler formulieren:

y(t) = k*( e(t)+1/Ti*int(e(t)) )

oder

y(t) = k*e(t) + int(k/Ti*e(t))

Als Abtastregler und in erster Näherung:

y = k*e + e_int

mit

e_int = e_int + T * k/Ti*e

Damit das ganze nicht überläuft, muss man jede Einzelrechnung auf 
Überlauf prüfen:

e_int < min: e_int = min
e_int > max: e_int = max

y = k*e + e_int

y < min: y = min
y > max: y = max

So läuft der Regler nicht über und kommt auch sofort aus der Begrenzung 
heraus, wenn e(t) das Vorzeichen wechselt.

e(t) muss vorzeichenbehaftet laufen, wie alle Werte, die im Regler 
verarbeitet werden. Ich würde anfangen und alles mit int16 rechnen.
Dann kann man den Ausgang auf 0 bis 255 begrenzen und als unit8 
ausgeben.

Gruss

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich danke euch allen, ich habe mein Regler jetzt am laufen.

Als Datentyp habe ich jetzt wirklich den int genommen und damit 
funktioniert es.

Und das e und esum habe ich begrenzt.
Außerdem habe ich in die Formel das Ta rein genommen, was vorher 
eigentlich
auch nicht kritisch war, weil die Abtastzeit 1 sek betrug.

Jetzt frage ich mich, was ist wenn die Abtastzeit kürzer werden soll?
Den Interrupt kann ich ja verkürzen wie ich möchte, die Zeit muss ich 
aber auch in meine Rechnung einbeziehen, versteht der Kontroller auch 
Kommazahlen?
z.B. 0.2 sek welchen Datentyp muss ich dafür nehmen float?

Autor: Walter Selg (waldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
es ändert sich die Berechnung des Integrals:

e_sum = e_sum + Ta * k/Ti*e

wenn also die Abtastzeit kleiner wird, muss das Integral pro Abtastpunkt 
weniger stark anwachsen. Der Faktor für das Integral wird also kleiner:

e_sum = e_sum + kI* e

mit

kI = Ta * k/Ti

und der Reglerausgang (Stellgrösse)

y = k*e + e_sum

Gruss Waldo

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das verstehe ich jetzt aber nicht.

Was ist den jetzt Ti?

Autor: Walter Selg (waldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ein PI-Regler wird in der Regel folgendermaßen formuliert:

y(t) = k*( e(t)+1/Ti*int(e(t)) )

Es gibt die Reglerverstärkung k und die Integrationszeitkonstante Ti oft 
auch als Nachstellzeit bezeichnet. Die Reglerverstärkung bewertet die 
Summe aus P-Anteil und I-Anteil, ist also die Gesamtverstärkung.

Das Integral sollte also wie folgt berechnet werden:

yI = yI + Ta * k/Ti * e

mit

Ta ... Abtastzeit
Ti ... Integrationszeit bzw. Nachstellzeit
k  ... Reglerverstärkung

Der Reglerausgang:

y = k * e + yI

Also muss in der Interruptroutine nicht einfach die Regelabweichung 
aufsummiert werden. Das hat den Nachteil, dass die Begrenzung schwer zu 
machen ist. Es ist besser yI in der Interruptroutine zu rechnen und die 
Begrenzung zu machen:

yI = yI + Ta *k/Ti * e

yI > max: yI = max
yI < min: yI = min

Die Konstante Ta * k/Ti kann im Voraus berechnet werden, um Zeit zu 
sparen.

Gruss

Autor: Thilo M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du hier schon mal geschaut?
Beitrag "PID-Regler mit anti-Windup"

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.