[PID] D-Anteil und Richtung

#2797487
Lesenswert?

Bin gerade bei der Inbetriebnahme meines PID-Reglers, Algorithmus nach 
http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-introduction/
Der Regler funktioniert nicht schecht, jedoch habe ich eine Anomalie. 
Das Vorzeichen des D-Anteils schwankt bei jedem dritten Einlesen der 
Temperatur mit Neuberechnung des PWM-Wertes, und das selbst dann, wenn 
die Temperatur deutlich über der Solltemperatur liegt. Sollte der 
D-Anteil eigentlich nicht über die gesamte Zeit mit negativem Vorzeichen 
über die gesamte Abkühlphase nach unten zeigen?

Was meinen die Experten zu der Gewichtung von kp, ki und kd? Hab hier 
nur ein sehr kleines Modell mit LM75 als Temp.sensor und nem 
5W-Widestand als Heizung in 5mm Entfernung...


1
      //Compute all the working error variables
2
      // P:
3
      error = Setpoint - Input;
4
      
5
      // I:
6
      errSum += error;
7
      
8
      // D:
9
      dErr = (error - lastErr);
10

11
      p = error   * 0.4;    //Gewichtung zu gering?
12
      i = errSum  * 0.01;   //Gewichtung zu gering?
13
      d = dErr    * 0.4;    //Gewichtung zu gering?
14

15
      p *= actualPvalue;    //einstellbar über Benutzermenü 
16
      i *= actualIvalue; 
17
      d *= actualDvalue;
18

19

20
      kp = p;
21
      ki = i;
22
      if (ki > 150) ki = 150;
23
      if (ki < -150) ki = -150;
24
      kd = d;
25

26

27
      // Compute PID Output
28
      // Output = kp * error  +  
29
      //     ki * errSum +  
30
      //     kd * dErr;
31
      Output = kp + ki + kd;
32
      // Output = (unsigned int) Output;
33
      if (Output > 255 ) Output = 255;
34
      if (Output < 0)    Output = 0;
35
  
36
          OCR0A  =  Output;
37
          // OCR0A = 0x00;  
38
          if (!OCR0A)  TCCR0A &= ~(1 << COM0A1);  //Nadel unterdrücken
39
          else TCCR0A |= (1 << COM0A1);
40

41
  
42
       
43
      //Remember some variables for next time
44
      lastErr = error;
45
      lastTime = now;
Gast #2797504
Lesenswert?

Aaaaaaahhhhhhhh - float - aaaahhhhhhh. Sowas macht mal in Integer, oder 
Longint.
Schon mal was von Debuggen gehoert ? Ich schliess da jeweils das UART an 
und lese mir die Werte aus. Da kann man alles mitverfolgen.
#2797665
Lesenswert?

Joachim ... schrieb:
> Das Vorzeichen des D-Anteils schwankt bei jedem dritten Einlesen der
> Temperatur mit Neuberechnung des PWM-Wertes, und das selbst dann, wenn
> die Temperatur deutlich über der Solltemperatur liegt.

na und? Der D-Anteil hängt ja auch nicht von Temperatur-Solltemperatur 
ab, sondern von der Änderung dieses Werts.

Joachim ... schrieb:
> Jetzt habe ich drei Antworten bekommen von denen sich keine auf meine
> Fragen bezieht...

Was erwartest du bei einer unvollständigen Frage? :-)
Gast #2797668
Lesenswert?

>Sollte der D-Anteil eigentlich nicht über die gesamte Zeit mit negativem 
>Vorzeichen über die gesamte Abkühlphase nach unten zeigen?

Nein, da ist Dein Denkfehler. Dein D-Anteil hängt vom dErr ab. Und der 
hat nix mit der Soll-Ist-Differenz zu tun, sondern mit dem Meßfehler 
zwischen den Abtastungen. So interpretier ich Dein Programm. Schau Dir 
doch noch mal diese Zeilen an:

>dErr = (error - lastErr);

und

>lastErr = error;


Wenn Dein Abtastwert trotz gleicher Ist-Temperatur schwankt, so kann es 
positive D-Anteile geben.

Ist der Code abgekupfert oder selbst überlegt?
#2797957
Lesenswert?

>Wenn Dein Abtastwert trotz gleicher Ist-Temperatur schwankt, so kann es
>positive D-Anteile geben.
In diese Richtung ging meine Überlegung - aber ich war nicht sicher, 
zumal ich hier noch n paar Probs physikalischer Art habe und der 
"Fehler" dadurch verschleiert wird...


>Ist der Code abgekupfert oder selbst überlegt?
abgekupfert: 
http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-direction/
Gast #2798203
Lesenswert?

Wenn schon abgekupfert, so mach Dir noch ein paar Gedanken dazu. Alles 
läßt sich verbessern.

Eine Meßtoleranz darf auf den D-Anteil keinen Einfluß haben.
Ergo: Laß einen D-Anteil nur entstehen, wenn das Error-Delta größer als 
ein vorgegebener Grenzwert ist. Diesen Grenzwert legst Du fest. Am 
bestesten im Header (also nur an einer Stelle im Programm) als #define 
oder auch als eine Variable. Schon beruhigt sich die Regelung.

Im Prinzip ist bei einer Temperaturregelung ein D-Anteil nicht die beste 
Wahl. Die Strecken haben im allgemeinen eine zu große Trägheit, als daß 
ein D-Anteil Sinn macht. P- und I-Anteile sind wichtig. I relativ 
gefährlich, wenn er zu schnell und zu weit wachsen kann.

Have fun.
#2798404
Lesenswert?

>I relativ gefährlich, wenn er zu schnell und zu weit wachsen kann.
Hihi. Ds ist auch meine Erfahrung. Ich habe ne Menge bei diesem Projekt 
gelernt u. aufgefrischt aber wohl noch nicht alle physik. Zusammenhänge 
meines Aufbaus genau durchforscht. Möglicherweise steckt auch noch der 
ein oder andere Rundungsfehler mit drinne der für Ungenauigkeiten sorgt. 
Im Mom. jedenfalls pendelt der Regler noch bei 60°C um +-2°C.
Angehängte Dateien:
#2798889
Lesenswert?

Nee, de Regler ist gerade im ausgeregelten Zustand, die Anteile kp, ki 
u. kd sind im Moment des fotografierens zufällig bei 0 bzw ki = 5 
(entsp. 5/255 PWM-Wert). Ich habe mehrere LCD-Bilder angelegt, bei einem 
kann ich per Drehgeber die P-, I- und D-Verstärkung einstellen und per 
Scrollbalken anzeigen.
Ursprünglich ging es mir nur um das Verständis des PID-Regelvorganges, 
mittlerweile macht aber das ganze komfortable und verschwenderische 
Drumrum (float-Variablen!) den Schwerpunkt der Software aus. Manchmal 
wedelt der Schwanz halt mit dem Hund.
#2800490
Lesenswert?

@  Joachim ... (joachim_01)

>Nee, de Regler ist gerade im ausgeregelten Zustand, die Anteile kp, ki
>u. kd sind im Moment des fotografierens zufällig bei 0 bzw ki = 5
>(entsp. 5/255 PWM-Wert).

Deine selbstgestrickte Verwednung der Begriffe ki, kp und kd ist 
irreführend. Denn diese Namen beschreiben die Koeefizienten im Regler, 
mit denen der PID Anteil jeweils gewichtet wird, NICHT die Eregbnisse 
dieser Gewichtung mit dem Fehlerterm!
1
     //Compute all the working error variables
2
      // P:
3
      error = Setpoint - Input;
4
      
5
      // I:
6
      errSum += error;
7
      
8
      // D:
9
      dErr = (error - lastErr);
10

11
      // Koeffizienten der Regelung
12

13
      kp=  0.4;      
14
      ki=  0.01;
15
      kd=  0.4;
16

17
      p = error   * *kp;    //Gewichtung zu gering?
18
      i = errSum  * ki;   //Gewichtung zu gering?
19
      d = dErr    * kd;    //Gewichtung zu gering?
20

21
      kp *= actualPvalue;    //einstellbar über Benutzermenü 
22
      ki *= actualIvalue; 
23
      kd *= actualDvalue;
24

25
      if (i > 150) i = 150;
26
      if (i < -150) i = -150;
27

28
      // Compute PID Output
29
      // Output = kp * error  +  
30
      //     ki * errSum +  
31
      //     kd * dErr;
32
      Output = p +i +d;
#2800754
Lesenswert?

Du hast recht. Jetzt, wo ich das alles aus der Distanz so sehe...  Auch 
actualPvalue ist nicht der echte Wert, ich habe ihn über mehrere 
Menüebenen weitergereicht und den Namen beibehalten, in Wahrheit ist er 
nur ein Beiwert. Das Prob war, daß an dem Projekt gleich mehrere neue 
Themen auf mich zukamen, wenig AVR-Erfahrung, nen Touch-Display das es 
zu erforschen galt, mehrere unterschiedliche Temp-Sensoren LM75, PT-100, 
NTC, NTC + OP-Reglerschaltung  Sensoren hab ich ausprobiert. Irgendwann 
kam es dann zu Schlampereien, Überblickverlust und 'leichten' 
Denkfehlern... Mangel an Disziplin?
#2800863
Lesenswert?

> Laß einen D-Anteil nur entstehen, wenn das Error-Delta
> größer als ein vorgegebener Grenzwert ist

Dann leg Dir lieber einen Ringbuffer an mit z.B. 10 Werten. Den D-Anteil 
gewinnst Du aus der Differenz zwischen dem neuesten und dem ältesten 
Wert dividiert durch 10. Das bringt Ruhe in die Regelung und erhöht die 
Auflösung. Die Temperaturwerte stammen ja ursprünglich aus dem 
AD-Wandler und hatten dort eine relativ geringe Auflösung. Bei den 
meisten Temperaturregelungen reicht es, die Regelung ein mal pro Sekunde 
aufzurufen. Dann kann man das auch problemlos in float rechnen.

D = (Tbuf[neu] - Tbuf[alt]) / BUFFSIZE;

Die Ringbuffer sollte so ausgelegt sein, dass er sich in ca. 20-30% der 
Zeitkonstante Deiner Regelstrecke komplett füllt, ansonsten wird der 
D-Anteil träge. Anstatt durch BUFFSIZE zu dividieren, kann auch Kd 
angepasst werden.

Du bringst die Begriffe etwas durcheinander, bei Kp, Ki und Kd handelt 
es sich um die Regelparameter:

#define KP 0.4
#define KI 0.01
#define KD 0.4

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