TwinCat 2 - CX9020 - Absturz nach öffnen des WHILE-Loop?

assindia

Level-1
Beiträge
6
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich arbeite zur Zeit an einer Volumenbestimmung, die mit Hilfe einer Bürette und einem Liquid Sensor realisiert werden soll.

Dazu habe ich folgenden Code geschrieben. Jedoch stürzt der ganze Controller ab sobald ich in While gehe, oder zumindest das Signal Burette.Active kommt.

Zur Info: Den Satzmerker bTEST habe ich nur erstellt weil ich für die Testzwecke noch kein zweites Signal MeasurementActive bekomme.

Ich sehe darin keinen Fehler. :( Kann mir einer weiter helfen?

Danke :)


Code:

bSensor := LiquidVolumeIN.bLiquidsensor;
fVelocity := LiquidVolumeIN.nVelocityBurette; (* [ml/min] *)

(* Für Testaufbau *)
fbHoldMeasurement( SET := LiquidVolumeIN.bBuretteActive, RESET1 := ,
Q1 => bTEST );

WHILE LiquidVolumeIN.bBuretteActive AND (*LiquidVolumeIN.bMeasurementVolActive *)bTEST DO

fbR_TRIG( CLK := bSensor, (* trigger when LiquidSensor turn to TRUE *)
Q => bRisingEdge);

IF bRisingEdge THEN (* get first timestamp *)

fbGetSystemTime( timeLoDW => GetSystemTime1OUT.timeLoDW,
timeHiDW => GetSystemTime1OUT.timeHiDW );
bRisingEdge := FALSE;
END_IF;

fbF_TRIG( CLK := bSensor, (* trigger when LiquidSensor turn to FALSE *)
Q => bFallingEdge );

IF bFallingEdge THEN (* get second timestamp *)
fbGetSystemTime( timeLoDW => GetsystemTime2OUT.timeLoDW,
timeHiDW => GetSystemTime2OUT.timeHiDW );

nCurActiveSensorTimeLo := GetSystemTime2OUT.timeLoDW - GetSystemTime1OUT.timeLoDW;
nCurActiveSensorTimeHi := GetSystemTime2OUT.timeHiDW - GetSystemTime1OUT.timeHiDW;
nComActiveSensorTimeLo := nComActiveSensorTimeLo + nCurActiveSensorTimeLo;
nComActiveSensorTimeHi := nComActiveSensorTimeHi + nCurActiveSensorTimeHi;

bFallingEdge := FALSE;
END_IF;
END_WHILE;

IF NOT LiquidVolumeIN.bBuretteActive AND(* LiquidVolumeIN.bMeasurementVolActive*) bTEST AND nComActiveSensorTimeLo <> 0 THEN
fVolume := (fVelocity / 60000) * ((nComActiveSensorTimeHi *429496.7295) + (nComActiveSensorTimeLo / 10000)); (* calculation volume *)

nComActiveSensorTimeLo := 0;
nComActiveSensorTimeHi := 0;

LiquidVolumeOUT.fSampleVolume := fVolume;
LiquidVolumeOUT.bMeasurementComplete := TRUE;

(* Für Testaufbau *)
fbHoldMeasurement.RESET1 := LiquidVolumeOUT.bMeasurementComplete;
END_IF;
 
Hast du das gelesen? Ich sehe in deinem Beispiel keine Abbruch Bedingung, die muss in der Schleife sein....sonst...naja weißt schon was dann passiert ;)
[h=1]WHILE-Schleife[/h]Die WHILE-Schleife kann benutzt werden wie die FOR-Schleife, mit dem Unterschied, dass die Abbruchbedingung ein beliebiger boolscher Ausdruck sein kann. Das heißt, man gibt eine Bedingung an, die, wenn sie zutrifft, die Ausführung der Schleife zur Folge hat.
Syntax:
WHILE <Boolescher Ausdruck> DO
<Anweisungen>
END_WHILE;

Die <Anweisungen> werden solange wiederholt ausgeführt, solange <Boolescher_Ausdruck> TRUE ergibt. Wenn <Boolescher_Ausdruck> bereits bei der ersten Auswertung FALSE ist, dann werden die <Anweisungen> niemals ausgeführt. Wenn <Boolescher_Ausdruck> niemals den Wert FALSE annimmt, dann werden die <Anweisungen> endlos wiederholt, wodurch ein Laufzeitfehler entsteht.

Hinweis: Der Programmierer muss selbst dafür sorgen, dass keine Endlosschleife entsteht, indem er im Anweisungsteil der Schleife die Bedingung verändert, also zum Beispiel einen Zähler hoch- oder runterzählt.

Beispiel:
WHILE Zaehler<>0 DO
Var1 := Var1*2;
Zaehler := Zaehler-1;
END_WHILE

Die WHILE- und die REPEAT-Schleife sind in gewissem Sinne mächtiger als die FOR-Schleife, da man nicht bereits vor der Ausführung der Schleife, die Anzahl der Schleifendurchläufe wissen muss. In manchen Fällen wird man also nur mit diesen beiden Schleifenarten arbeiten können. Wenn jedoch die Anzahl der Schleifendurchläufe klar ist, dann ist eine FOR- Schleife zu bevorzugen, da sie keine endlosen Schleifen ermöglicht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi Feldbus,

danke schon einmal für die schnelle antwort.

Meiner Meinung nach habe ich eine Abbruchbedingung. Nämlich durch das von außen zugeführte Signal BuretteActive. Denn wenn die Bürette nicht mehr Aktiv ist kann auch keine Probe mehr gezogen werden. Sprich der Liquid Sensor kann nicht mehr ansprechen und dann kann die Berechnugn des Volumen beginnen.

Der Controller stürzt auch nicht nach einer gewissen Zeit ab sondern sofort. Ich kann im Online-Modus nicht einmal Wahrnehmen das das Signal BuretteActive TRUE wird. :confused:

Oder muss die Abbruchbedingung in dem Loop enthalten sein?
 
Du programmierst hier eine SPS und schreibst kein normales PC-Programm.
Das SPS-Programm an sich wird schon in einer Dauerschleife ausgeführt, dabei überwacht es seine eigene Laufzeit. Wenn du nun eine While-Schleife programmierst, geht dein Programm dorthinein, kommt aber nie wieder an der Stelle vorbei, wo deine Inputs eingelesen werden. D.h., selbst wenn deine Abbruchbedingung anspringt, bekommt das Programm das überhaupt nicht mit und auch die Impulse selbst werden nicht mehr eingelesen. Weiterhin kommt nach Zeit X deine Zykluszeitüberwachung und meckert, denn das keine Eingänge mehr gelesen und keine Ausgänge mehr geschrieben werden soll ja nie passieren, das ist der Supergau bei der SPS! Mit so einer While-Schleife muß man also in der Regel sehr vorsichtig umgehen, damit kann man mal ein paar Runden drehen, um in einem Array einen Wert zu suchen, aber immer die Zykluszeit im Auge behalten.

In deinem Fall mußt du also gänzlich anders vorgehen.

Ist es so, dass der Sensor Impulse ausgibt?
Dann einfach eine Flanke auf den Impuls und diese Impulse zählen. Dazu braucht es keine While-Schleife, weil ja das Haupt-Programm der SPS ohnehin eine Schleife ist.
Die Impulse dürfen natürlich nicht schneller als die halbe Zykluszeit kommen, sonst bekommt die SPS einen Teil der Impulse nicht mit (Shannon-Theorem)
 
Zuletzt bearbeitet:
Wie soll von außen ein Signal kommen, wenn Dein Programm in einer Schleife festhängt und keine Eingänge liest?
Daß eine SPS zyklisch arbeitet und arbeiten muß ist Dir bekannt?

Gibt es bei Deinem Zielsystem eine Diagnose? Ich vermute STOP wegen Zykluszeitüberschreitung.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Abbruchbedingung sollte kein Externes Signal sein da die While Schleife nicht mehr auf einkommende Signale reagieren kann. Es muss also irgendwas in der while Schleife sein, also eine Berechnung zum Beispiel oder das ende einer Kopierfunktion. Externe Signale werden ja erst mit Start der neuen Task upgedatet. Eine Schleife bleibt in einer Task so das ein Ergebnis nach der Schleife sofort zur Verfügung steht. Solltest du auf ein Ergebnis oder Ereigniss außerhalb der Schleife warten klappt das nicht. Die Schleife greift nicht mehr darauf zu.
Sowas geht zum Beispiel:
i:=0;
WHILE i<100 DO
i := i+1;
END_WHILE

Sowas nicht, Sollte i kleiner 100 sein bleibt das Programm in der While Schleife und es ist Schluß:
i := i+1;
WHILE i<100 DO
;
END_WHILE
Eine whlie Schleife kannst du auch durch Exit verlassen, auch das ist möglich. Das Beispiel macht nicht allzuviel Sinn, so spontan ist mir nichts besseres eingefallen....
i := i+1;
WHILE i<100 DO
If i>=100 then;
Exit;
END_IF
END_WHILE
 
AH.
Klar jetzt ergibt es Sinn.
War wohl noch zu sehr beim PC Programm. :rolleyes:

Problem gelöst.

Hab die WHILE Schleife komplett entfernt.
Durch die beiden Bedingungen: BuretteActive und MeasurementActive habe ich die Möglichkeit gesondert in die Volumenmessung zu gehen.

Wieso ich da nicht eher drauf gekommen bin. -.-

DANKE!
 
Zurück
Oben