Eigene PID zur Lehrzweck

klementine

Level-1
Beiträge
8
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Tag,

Ich versuche einen einfachen PID-Controller zur Lehrzweck zu entwickeln und stoße auf unerkläriche Fehler.
Hier http://en.wikipedia.org/wiki/PID_controller ist eine super Beschreibung die man so auch sofort einsetzen kann.

In C auf der Atmel-Mega8 war es kein Problem. Es läuft auf anhieb und ich kann damit ein DC-Motor mit Potti auf Position regeln... Hier der Pseudo-Code. Auch aus der Wiki. (Kp, Ki, Kd müssen natürlich vorab ermittelt werden)
previous_error = 0
integral = 0
start:
error = setpoint - measured_value
integral = integral + error*dt
derivative = (error - previous_error)/dt
output = Kp*error + Ki*integral + Kd*derivative
previous_error = error
wait(dt)
goto start​

Der gleiche Code in TIA (SCL) spuckt nur unlogische bzw. nicht nachvollziehbare Ergebnisse aus. Diese Algorithmus MUSS nacheinander berechnet werden aber ich habe dasGefühl der PLC versucht es auf einmal.....
Hat jemand hier schon mal Erfahrung mit eigene PID-Conroller oder wie diese in TIA bzw PLC entwickelt werden kann

Vorab mein Dank für Ihre Hile und Frohe Ostern

Klementine
 
Naja, um dir zu helfen dein Problem mit SCL zu lösen, wäre es sicher hilfreich deinen SCL Code zu sehen...

Die SPS arbeitet den Code auch nacheinander ab. Der größte Unterschied zu normalen µC oder anderen Hochsprachen-Anwendungen ist, dass eine SPS Programm idR IMMER zyklisch abläuft.
D.h. :
1) der Rücksprung in den du ein deinem Pseudo-Code hast und der auch auf dem Atmel gebraucht wird, ist auf einer SPS tödlich
2) die Verzögerung des Programms funktioniert so auch nicht. Bei vielen SPSen ist die Zykluszeit fest vorgegeben (konfigurierbar). Kann dein Code in dieser Zeit nicht abgearbeitet werden (weil verzögert) gibt das Fehler. Um bei Siemens SPSen einen isochronen Zyklus zu bekommen solltest du mit Weckalarmen arbeiten. Diese rufen deinen Code dann genau alle x-Millisekunden (+- Jitter) auf.


PS:
Hast du den Code auf dem Atmel wirklich nach dem Pseudocode umgesetzt? Ich hätte das ganze mit einem zeitgesteuerten Interupt gelöst, der Blockiert den Controler nicht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
jo, das ganze in einen Weckalarm aufrufen, z.B. OB35. aber ohne das Wait und Goto. dt ist dann die Aufrufzeit vom OB35.

Gruß.

PS: Lehrzwecke schön und gut... aber ein PID-Regler ohne Antiwindup ist Käse... sollte man zumindest drauf hinweisen.
 
Zuletzt bearbeitet:
Guten Tag zusammen.

in C habe ich gar keine Warteschleifen.
Sie haben recht mit dem Timer.
Dieser Test gilt nur zum Vergleich, um die Arbeitsweise des PLCs zu verstehen. Anbei der Code...

//================ C-Code==================================
while(1)
{​
error = getPotti() - getEncoder();
integral = integral + error*dt;
derivative = (error - previous_error)/dt
output = Kp*error + Ki*integral + Kd*derivative
previous_error = error
if (output >= 255) output = 255;
else if (output <= 0) output = 0;​
}​

//================ PLC-Code aus TIA V11 ========================
Input
setpoint Real ... 0.0
measured_value Real ... 0.0
Kp Real ... 0.0
Ki Real ... 0.0
Kd Real ... 0.0

Output
output Real ... 0.0

Static
error Real ... 0.0
previous_error Real ... 0.0
integral Real ... 0.0
dt Real ... 0.010
derivative Real ... 0.0


IF "GlobalVar".First_Time_Call THEN
#previous_error := 0.0;
#integral := 0.0;
"GlobalVar".First_Time_Call := FALSE;
END_IF;

#error := #setpoint - #measured_value;
#integral := #integral + #error*#dt;
#derivative := (#error - #previous_error)/#dt;
#output := #Kp*#error + #Ki*#integral + #Kd*#derivative;
#previous_error := #error;
IF #output >= 27648.0 THEN #output := 27648; END_IF;
IF #output <= 0.0 THEN #output := 0.0; END_IF;


dt ist gleich 10ms da der FB in OB38 aufgerufen wird.
Ich bin mir nicht sicher was ich falsch mache aber dieser Code funktioniert nicht mit unser 314C

Gruß
Klementine
 
Zurück
Oben