Fehler bei ACTUATOR_3P bei Verwendung von Endkontakten

Begonnen von msSPS, 30. Januar 2012, 20:15:03

Vorheriges Thema - Nächstes Thema

0 Mitglieder und 1 Gast betrachten dieses Thema.

msSPS

Hallo,

ich habe mir die OSCAT-Bibliotheken angesehen, weil ich einen guten Baustein für 3-Punkt-Antriebe benötige.
Der ACTUATOR_3P war für mich in der Fassung 1.00 der building lib leider unbrauchbar, wenn man ihn mit Endschaltern verwenden will, weil meines Erachtens (außer ich stehe komplett auf dem Schlauch) einige Fehler im Quelltext enthalten sind. Auf mich wirkt es so, als sei der Baustein in Verbindung mit Endschaltern nie getestet worden, weil die Fehler eigentlich offensichtlich sind und bei mir bei meiner ersten Simulation mit CoDeSys sofort zum Vorschein kamen. Was mich aber stutzig macht ist das Versionsdatum von Januar 2010 und dass diese Fehler immer noch bestehen. Mache ich eventuell doch etwas falsch? Ich habe zuvor nie etwas mit SPS am Hut gehabt, habe mein "Wissen" in drei Tagen "ergoogelt" und das ist mein erstes Projekt, daher sind Fehler meinerseits absolut nicht ausgeschlaossen.

Ich habe hier die aktuelle Version mit meinen Kommentaren versehen, wo ich Fehler beseitigt habe. Meine Kommentare beginnen und enden alle mit ####
Diese hier von mir geänderte Version funktioniert tadellos, sowohl in der Simulation als auch in der Praxis.



(* check test input *)
IF TEST THEN
status := 103;
start := tx;
ARX := TRUE;
END_IF;

CASE status OF
0: (* power on setup *)
IF ARE AND NOT ARX THEN
IF SWITCH_AVAIL THEN (* #### Zum neuen Schritt 102 springen, falls Endschalter vorhanden #### *)
status := 102;
ELSE
status := 103;
END_IF;
start := tx;
ARX := TRUE;
END_IF;

100: (* normal operation *)
(* check for auto diagnostics *)
IF T_DIAG > T#0s AND tx > next_diag AND ARE AND NOT ARX THEN
status := 103;
start := tx;
ARX := TRUE;

(* check for auto calibration *)
ELSIF T_CAL > T#0s AND tx > next_cal AND ARE AND NOT ARX THEN
IF pos > BYTE#191 THEN   (* #### Geändert von 1/2 auf 3/4, damit Vorlauftemperaturen nicht übermäßig ansteigen - rein "kosmetisches Problem", kein Fehler #### *)
OUT1 := TRUE;
OUT2 := FALSE;
ramp.IN := 255;
ARX := TRUE;
ELSE
OUT1 := FALSE;
OUT2 := TRUE;
ramp.IN := 0;
ARX := TRUE;
END_IF;
status := 101;
start := tx;
ELSE
(* increment next_cal if not active *)
IF NOT(OUT1 OR OUT2) THEN next_cal := next_cal + (tx-last); END_IF;
(* set ramp generator to IN *)
ramp.IN := IN;
END_IF;

101: (* calibrate *)
IF tx - start < T_EXT THEN
next_cal := tx + T_CAL;
ELSIF SWITCH_AVAIL AND END_POS THEN
STATUS := 100;
ARX := FALSE;
ELSIF tx - start > T_EXT + T_RUN THEN
ERROR := SWITCH_AVAIL;
ARX := FALSE;
END_IF;

102: (* #### Modus 102 neu eingefügt, damit Antrieb am Anfang bei 0 steht, sonst liegt die Berechtung von TR völlig daneben, weil man nicht davon ausgehen kann, dass der Antrieb beim Start auf 0 steht #### *)
IF tx - start < T_EXT THEN
ERROR := FALSE;
ramp.TR := T_RUN;
ramp.TF := T_RUN;
OUT1 := FALSE;
OUT2 := TRUE;
ramp.IN := 0;
ELSIF SWITCH_AVAIL AND END_POS THEN
STATUS := 103;
start := tx;
ELSIF tx - start > T_EXT + T_RUN THEN
ERROR := SWITCH_AVAIL;
STATUS := 103;
start := tx;
END_IF;

103: (* diagnostics up*)
(* run up for T_ext *)
IF tx - start < T_EXT THEN
ERROR := FALSE;
ramp.TR := T_RUN;
ramp.TF := T_RUN;
OUT1 := TRUE;
OUT2 := FALSE;
ramp.IN := 255;
ELSIF SWITCH_AVAIL AND END_POS THEN
ramp.TR := tx - start;
STATUS := 104;
start := tx;  (* #### Zeile eingefügt, sonst kann status 104 nicht funktionieren, wurde hier wohl vergessen ####*)
ELSIF tx - start > T_EXT + T_RUN THEN
ERROR := SWITCH_AVAIL;
STATUS := 104;
start := tx;
END_IF;

104: (* diagnostics dn*)
IF tx - start < T_ext THEN
OUT1 := FALSE;
OUT2 := TRUE;
ramp.IN := 0;
next_diag := tx + T_DIAG;
ELSIF SWITCH_AVAIL AND END_POS THEN
ramp.TF := tx - start; (* #### Hier war früher ramp.TR gestanden, mit ramp.TF ersetzt #### *)
(* check if runtimes differ by more than 10% *)
IF DINT_TO_TIME(ABS(TIME_TO_DINT(ramp.TR) - TIME_TO_DINT(ramp.TF))*10) > T_RUN THEN error := TRUE; END_IF;
STATUS := 100;
ARX := FALSE;
next_cal := tx + T_CAL;
ELSIF tx - start > T_EXT + T_RUN THEN
ERROR := SWITCH_AVAIL;  (* #### Zwecks Konsistenz ersetzt - rein "kosmetisches" Problem, kein Fehler #### *)
STATUS := 100;
ARX := FALSE;
next_CAL := tx + T_CAL;
END_IF;
END_CASE;

(* internal flap simulation and output activation *)
ramp(OUT := POS);
IF STATUS = 100 THEN
OUT1 := ramp.UP;
OUT2 := ramp.DN;
END_IF;

(* adjust position if end switch is active *)
IF SWITCH_AVAIL AND END_POS THEN
POS := SEL(POS > 127, 0, 255);
next_cal := tx + T_CAL;
END_IF;

(* set last to tx for next cycle *)
last := tx;

msSPS

Habe gerade gesehen, der Fehler mit den Endschaltern ist bekannt.

Trotdem bitte auch die anderen Anmerkungen im Code beachten, wie fehlerhafte Laufzeitzuweisung und die Initialisierungssequenz, die bei Verwendung von Endschaltern Zu-Auf-Zu sein muss und nur ohne Endschalter Auf-Zu sein kann.

msSPS

Bis auf die schon entdeckten Fehler bei Endkontakten und Fehlerhafter Initialisierungssequenz habe ich beim genaueren Ansehen des Quellcodes auch noch Fehler beim Timerüberlauf gesehen.

Die Vergleiche "tx > next_diag" und "tx > next_cal" sind natürlich nicht resistent gegen Timerüberläufe.