Hallo Zusammen,
ich arbeite gerade an einem Projekt an der Hochschule. Die
Aufgabenstellung ist einen PID-Temperaturregler für einen
Lötbarkeitstester zu programmieren mit den Vorgaben (kurzgefasst):
- Sollwert Lot: 240°
- Maximale Heiztemperatur der Heizpatrone: 500°
Habe eigentlich schon alles soweit programmiert und getestet (inklusive
Anti-Windup,PWM-Regelausgangsteuerung...). Ich habe eine
Temperaturdifferenz von ungefähr +-2°C.
Hier ist mein Code:
1 | // SystemTaskAbfrage, Umwandlung der Zykluszeit und Zuweisung der Zykluszeit in die Variable 'cycle_time'
|
2 | fbGetCurTaskIdx();
|
3 | udint_zclock := _TaskInfo[fbGetCurTaskIdx.index].CycleTime/10000;
|
4 | int_zclock:= UDINT_TO_INT(udint_zclock);
|
5 | real_zclock:= INT_TO_LREAL(int_zclock)*0.01;
|
6 | cycle_time := real_zclock; // = 0.1
|
7 |
|
8 | // Nach Abfrage aktuelle Temperaturwerte von MAIN übernehmen
|
9 | Solltemp := MAIN.setpoint;
|
10 | Akttemp := MAIN.actual_value;
|
11 |
|
12 | // Regeldifferenz berechnen (Solltemperatur - Isttemperatur)
|
13 | error := (Solltemp - Akttemp);
|
14 |
|
15 | // P-Regler beschreiben (Regeldifferenz * Verstärkung kP)
|
16 | P_part := error * GVL_VAR.kP;
|
17 |
|
18 | // I-Regler beschreiben
|
19 | IF GVL_VAR.kI > 0 THEN
|
20 | I_Part_Zw_Summe := (delta_error_last_cycle * (cycle_time / GVL_VAR.kI));
|
21 |
|
22 | IF NOT limit_on_low AND (I_Part_Zw_Summe <0) THEN
|
23 | I_part := I_part + I_Part_Zw_Summe;
|
24 | ELSIF NOT limit_on_high AND (I_Part_Zw_Summe >0) THEN
|
25 | I_part := I_part + I_Part_Zw_Summe;
|
26 | END_IF;
|
27 |
|
28 | IF I_part > Out_max THEN
|
29 | I_part := Out_max;
|
30 | ELSIF I_part < Out_min THEN
|
31 | I_part := Out_min;
|
32 | END_IF;
|
33 |
|
34 | ELSIF GVL_VAR.kI <= 0.0 THEN
|
35 | I_part := 0.0;
|
36 | END_IF;
|
37 |
|
38 | // Manuelles Zurücksetzen des Integrators
|
39 | if I_Reset then
|
40 | I_part := 0.0;
|
41 | END_IF;
|
42 |
|
43 | // D-Regler beschreiben
|
44 | diff_anteil := (error - delta_error_last_cycle) / cycle_time;
|
45 | D_part := diff_anteil * GVL_VAR.kD;
|
46 |
|
47 | // Regleroutput berechnen (P+I+D)
|
48 | output_value := P_part + I_part; //+ D_part;
|
49 |
|
50 | // Merkbits zur Anti-Windup-Maßnahme beim Integrator
|
51 | limit_on_low := FALSE;
|
52 | limit_on_high := FALSE;
|
53 |
|
54 | // Reglerausgang zwischen den Werten Min und Max skallieren (wird benötigt für die PWM)
|
55 | IF output_value > Out_max THEN
|
56 | output_value := Out_max;
|
57 | limit_on_high := TRUE;
|
58 | ELSIF output_value < Out_min THEN
|
59 | output_value := Out_min;
|
60 | limit_on_low := TRUE;
|
61 | END_IF;
|
62 |
|
63 | // Skalierter Reglerausgang
|
64 | PID_out := output_value;
|
65 |
|
66 | // Regeldifferenz für nächsten Zyklus beschreiben
|
67 | delta_error_last_cycle := error;
|
Mein Problem ist nun: In meiner Regelung bewirkt der D-Anteil garnichts,
heisst, D ist bei mir immer 0, da sich (error - delta_error_last_cycle)
nie ändert und immer 0 ist.
Ist mein Regler soweit richtig programmiert? Denn an sich komme ich ja
auf die gewünschte Solltemperatur mit +-2°C. Was mich aber stört ist,
dass der D-Regler nichts bewirkt..
Grüße
Muzaffer
PS.: Variablendeklaration habe ich jetzt erst mal nicht mit reingepackt.