www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik digitale Regler


Autor: James d (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tag zusammen,

ich brauche euere hilfe, um meine Aufgabe zu lösen.  Ich bin Anfänger 
mit µC und will ein PID regler mit µC implementieren. ich schon Googlen 
und Foren über das Thema geschaut, aber ich habe noch einige 
Verständnissproblem, um das Algorithmus im code zu schreiben.
ich will nicht unbedingt, dass jemand alles zu mir schreibt, ich will 
auch lernen deswegen suche ich ein, der mir noch mal und simple das 
Ablaufplan des  Umscvhreiben des algo in code gibt oder eine gute 
beschreibung  ein pid regler c code.

bitte um Antwort

Autor: Scherbo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Übertragungsfkt des analogen Glieds -> Tustin -> Fertig ...

Ansonsten: 
http://www2.efi.fh-nuernberg.de/~karl/skripten/RT-...

Ab Seite 182 des Skripts, Kapitel "zeitdiskrete Regelungen"

Alles relativ simpel...

Autor: Billy der Bastler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: james d (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich will jetzt dieses Beispiel erweiter, um auf meine Aufgabe richtig zu 
lösen.



double PID_Berechnung (double x, double w)
{
e =w-x;                    // aktuelle Regelabweichung bestimmen
//---------------------------------------------------------------------- 
----------------------------
  if ((e >= AS)||(e <= (AS*(-1))))        // Betrag der Differenz prüfen
  {
//---------------------------------------------------------------------- 
----------------------------
  if ((y < 1023)&&(y > 0))            // bei Übersteuertem stellglied 
Integration einfrieren
    {                      // (Anti-Windup)
      esum = esum + e;            // Summe der Regelabweichung 
aktualisieren
    }
//---------------------------------------------------------------------- 
----------------------------
    y = (Kp*e)+(I*Ta*esum)+(D*((e-ealt))/Ta);  // Reglergleichung
                          // (I-Anteil bei der Initialisierung mit 
Abtastrate verrechnet)
    ealt = e;                  // Regelabweichung für nächste Abtastung 
merken
  }
//---------------------------------------------------------------------- 
----------------------------
  if (y > 1023)                  // Stellgröße auf 0..1023 begrenzen (10 
bit PWM)
    {
      y = 1023;
    }
  if (y < 1)
    {
      y = 0;
    }
//---------------------------------------------------------------------- 
----------------------------
  return y;
}

das umsetzen von einige Teil des Programm ist mir noch nicht klar.  Ich 
weiß zb, dass  ich ein function für die conversion der x(gemessene) 
Werten
durch ein Timer interrupt machen soll.  danach habe  das result diese 
Umwandlung in dem ADCDAT meines µc

die Frage ist folgendes:

kann ich eine fach in Main vor dem anruf von PID_Berechnung auch ein 
funktion zb ADCConfig ADCWandlung anrufen?  soll ich das Result der 
wandlung in X zuweisen in dieses unterprogramm?

2. wie wäre es mit w?

am Ausgangs möchte ich wieder ein analogwert habe wie wäre es

bitte um Hilfe?

Autor: B e r n d W. (smiley46)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo james d

Angenommen, Du möchtest eine Regelstrecke mit PT1-Verhalten regeln. Der 
Regler sollte innerhalb der Ansprechzeit T des PT1-Gliedes mindestens 10 
mal aufgerufen werden. Wird er weniger als ~20 mal aufgerufen, so hat 
das schon einen Einfluß auf die Regelparameter Ki und Kd.

Keine Ahnung, mit was Du programmierst, aber gcc für den AVR stellt 
meines Wissens kein double zur Verfügung, sondern maximal float. Falls 
es damit Geschwindigkeits- oder Platzprobleme geben sollte, wäre eine 
Umstellung auf int/long mit Festkomma-Berechnung anstatt float zu 
empfehlen.

Die Ansprechschwelle AS hab ich mal entfernt, die wirst Du 
wahrscheinlich nicht brauchen.
#define Ta   0.1   // 100 ms
#define Kp   5.35
#define Ki   0.12
#define Kd   3.75

float PID_Zyklisch(float x, float w);
float esum = 0;

int main()
{
  float ist, stell, soll=123;

  while(1)
  {
    // Das Timing besser mit einem Timer steuern
    delay_ms(100);  // Das Ta entspricht diesem Wert

    // aktuellen Istwert einlesen
    ist = ad_wandler(); 

    // Den PID-Regler so regelmäßig wie möglich aufrufen
    stell = PID_Zyklisch(ist, soll);

    // Das Stellglied auf den neuen Wert setzen
    PWM_Ausgang(stell);
  }
}

float 
PID_Zyklisch(float x, float w)
{
  float e, y;

  e = w-x;                   // Regelabweichung bestimmen

  // Betrag der Differenz prüfen
  if ((y>0) && (y<1023))     // Bei übersteuertem Stellglied
  {                          // einfrieren (Anti-Windup)
    esum = esum + e;         // Summe der Regelabweichung
  }

  // Reglergleichung
  y = Kp * e +               // P-Anteil
      Ki * Ta * esum +       // I-Anteil
      Kd * (e-ealt) / Ta;    // D-Anteil

  // Regelabweichung für nächste Abtastung merken
  ealt = e;                

  // Stellgröße begrenzen für 10 Bit PWM
  if (y < 0)      
    y = 0;
  if (y > 1023)
    y = 1023;

  return y;                 // Stellgröße zurückgeben
}

Autor: James d (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Bern w

 ich programmiere mit keil µvision4. ist das ok wenn ich int benutzt?
  und wie wäre es mit festkomma ?

noch eine Frage:
sie deklarieren variable  floa ist, stell, soll=23;

 Main(){
.....
...

ist=ad_wandler;

stell=PID_Zyklisch(ist soll)

}

warum bleibt w immer analog? dahte ich, dass w auch in main durch ein 
anadere kanal von ADC ein wert bekomm soll oder  ist 123 schon 
digitalwert?


 PWM_Ausgang(stell);  ist das mein DAC_ausgang ? denn ich will nach dem 
regelung den optokkopler mit dem analogwert steuern

auch gültig für ein der dei Gechichte kenn.

grüß

Autor: B e r n d W. (smiley46)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Festkomma
Float hat 6 relevante Stellen, deshalb sollte double in den seltensten 
Fällen notwendig sein. Der alte Keil hat sowiso von double auf float 
zurückgewandelt. Beim µVision 4 weiß ich das jedoch nicht.

Falls der Regler zyklisch in 1ms Intervallen aufgerufen werden soll, muß 
man die Geschwindigkeit des Reglers optimieren. Entweder nach Festkomma 
umstellen oder gleich in Assembler programmieren.

>PWM_Ausgang(stell);  ist das mein DAC_ausgang?
Falls Deinn Controller einen DAC hat, umso besser.

>soll
Das kommt auf Deine Anwendung an. Falls Du nur auf einen bestimmten Wrt 
regeln willst, genügt ein fest eingestellter Sollwert. Es wäre aber auch 
eine Tastatureingabe denkbar. Oder ein Anderer Eingang gibt den Sollwert 
vor.

Gruß Bernd

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.