Forum: Mikrocontroller und Digitale Elektronik digitale Regler


von James d (Gast)


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

von Scherbo (Gast)


Lesenswert?

Übertragungsfkt des analogen Glieds -> Tustin -> Fertig ...

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

Ab Seite 182 des Skripts, Kapitel "zeitdiskrete Regelungen"

Alles relativ simpel...

von Billy der Bastler (Gast)


Lesenswert?


von james d (Gast)


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?

von B e r n d W. (smiley46)


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.
1
#define Ta   0.1   // 100 ms
2
#define Kp   5.35
3
#define Ki   0.12
4
#define Kd   3.75
5
6
float PID_Zyklisch(float x, float w);
7
float esum = 0;
8
9
int main()
10
{
11
  float ist, stell, soll=123;
12
13
  while(1)
14
  {
15
    // Das Timing besser mit einem Timer steuern
16
    delay_ms(100);  // Das Ta entspricht diesem Wert
17
18
    // aktuellen Istwert einlesen
19
    ist = ad_wandler(); 
20
21
    // Den PID-Regler so regelmäßig wie möglich aufrufen
22
    stell = PID_Zyklisch(ist, soll);
23
24
    // Das Stellglied auf den neuen Wert setzen
25
    PWM_Ausgang(stell);
26
  }
27
}
28
29
float 
30
PID_Zyklisch(float x, float w)
31
{
32
  float e, y;
33
34
  e = w-x;                   // Regelabweichung bestimmen
35
36
  // Betrag der Differenz prüfen
37
  if ((y>0) && (y<1023))     // Bei übersteuertem Stellglied
38
  {                          // einfrieren (Anti-Windup)
39
    esum = esum + e;         // Summe der Regelabweichung
40
  }
41
42
  // Reglergleichung
43
  y = Kp * e +               // P-Anteil
44
      Ki * Ta * esum +       // I-Anteil
45
      Kd * (e-ealt) / Ta;    // D-Anteil
46
47
  // Regelabweichung für nächste Abtastung merken
48
  ealt = e;                
49
50
  // Stellgröße begrenzen für 10 Bit PWM
51
  if (y < 0)      
52
    y = 0;
53
  if (y > 1023)
54
    y = 1023;
55
56
  return y;                 // Stellgröße zurückgeben
57
}

von James d (Gast)


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üß

von B e r n d W. (smiley46)


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

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.