Forum: Mikrocontroller und Digitale Elektronik PID-Regler mit anti-Windup


von skorpionx (Gast)


Lesenswert?

Ich brauche einen PID Regler. Hier habe ich etwas interessantes 
gefunden:
Beitrag "PID-Regler mit anti-Windup"

Ich habe den Regler übernommen. Nur den anti-windup habe ich geändert.
Bitte um Meinungen.

typedef struct
{
  int Ta;                      // Abtastzeit in ms
  int I;                      // Integralanteil
  int Kp;                     // Verstärkung
  int D;                      // Differenzieller Anteil
  int e;                      // Regelabweichung
  long esum;                  // Summe der Regelabweichungen
  int ealt;                   // Regelabweichung zum ZP z-1
  int y;
  int AS;                     // Ansprechschwelle
}PID_Einstellung;             // Struktur PID_Einstellungen erzeugen



void PID_Init(void);
void PID_Cyclic(int, int, PID_Einstellung*);



PID_Einstellung Regler1;     // Variable Regler1, je nach Bedarf 
erweitern


void mainx(void)
{
  int Ausgang, w,x;
  PID_Init();



  while(1)
  {
    PID_Cyclic(x,w,&Regler1);   // Parameter für Regler1 übergeben
  }
}



void PID_Init(void) // Init  Reglereinstellungen gemacht werden
{
  Regler1.AS=1;
  Regler1.y=0;
  Regler1.Ta=10;
  Regler1.I=100;
  Regler1.D=0;
  Regler1.Kp=1;
  Regler1.esum=0;
  Regler1.e=0;     // Für weiteren Regler einfach Neue Variable 
erstellen
  Regler1.ealt=0;       // und hier Werte mit Regler2.xx=0 einstellen
}




//Sonst summiert sich esum bis zum Überlauf auf.
void PID_Cyclic (int x, int w, PID_Einstellung* PID)
{
  int AS;
  AS=PID->AS;
  PID->e = w - x;                     // aktuelle Regelabweichung 
bestimmen

if ((PID->e >= AS)||((PID->e) <= (AS * (-1)))) // Betrag der Differenz 
prüfen
{
/*
   //Anti-Windup ALT
  if ((PID->y < 1023)&&(PID->y > 0))      // bei Übersteuertem 
stellglied Integration einfrieren
   {                                      // (Anti-Windup)
        PID->esum = PID->esum + PID->e;    // Summe der Regelabweichung 
aktualisieren
    }
*/

  //Anti-Windup NEU
  if(PID->y==1023)                       //Stellwert am Anschlag +
  {
      if(PID->e<0)                       //Richtung weg vom Anschlag +
        PID->esum = PID->esum + PID->e;
  } else if (PID->y==0)                  //Stellwert am Anschlag -
  {
      if(PID->e>0)                      //Richtung weg vom Anschlag -
        PID->esum = PID->esum + PID->e;
  } else                                //Stellwert nicht am  Anschlag
      PID->esum = PID->esum + PID->e;

  PID->y = 
(PID->Kp*PID->e)+(PID->I*PID->Ta*PID->esum)+(PID->D*((PID->e-PID->ealt)) 
/PID->Ta);     // Reglergleichung
  PID->ealt = PID->e;              /für nächste Abtastung merken

}

  if (PID->y > 1023)    // Stellgröße auf 0..1023 begrenzen (10 bit PWM)
   {
      PID->y = 1023;
    }
  if (PID->y < 1)
    {
      PID->y = 0;
    }
                           // Stellgröße zurückgeben
}

: Verschoben durch User
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.