TIA Operand nicht definiert

Credofire

Level-1
Beiträge
640
Reaktionspunkte
35
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute

ich wollte etwas mit der Zykluszeit experimentieren mit dem RUNTIME Baustein. Soweit so gut.
Nun will ich mir aber die Werte in einem Array abspeichern 1-100 Werte. Nun sagt mir aber das Programm, dass mein Operand nicht definiert ist?
Ich habe extra ein DB angelegt wo nur dieses Array drin ist.

Problem_ZyklusDB.png Problem_Zyklus_SCL.png

Nun hab ich keine Ahnung warum das Program mir sagt, das der Operand nicht definiert ist?

Kann mir bitte jemand das Brett vorm Kopf nehmen?
 
Vermutlich mußt Du schreiben
Code:
"Zyklus".Cicle[#Zyklusnummer] := "Merker_glob".Main_OB.Zyklus_ms;
Allerdings macht es kaum Sinn, in einer Schleife 500 mal nacheinander den selben Wert in die selbe Variable zu schreiben...

Harald
 
REAL für "Zyklus".Cicle[#Zyklusnummer] ist vermutlich das nächste Problem.
Hab' jetzt nicht nachgeschaut, aber die Zykluszeit ist doch bestimmt DINT, oder?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich will ja auch nicht 500 mal den gleichen Wert schreiben. Nur an dieser Stelle bin ich noch nicht ;)
Das ist mein nächster Schritt. Aber falls ich nicht darauf komme, werd ich nochmal nachfragen ;) Ich möchte die Zyklusszeiten interessenhalber mal beobachten so genau wie möglich wenns geht.

Das RUNTIME gibt die Zykluszeit als LReal Wert in Sekunde aus. Ich habe es schon in Real gewandelt um Speicherplatz zu sparen.
 
Wenn Dir eine Auflösung von 10µs reicht könntest Du in INT wandeln und noch mehr Speicherplatz sparen.
Und wenn Du Dich wie bei Siemens classic auf das Speichern nur des letzten sowie des längsten und kürzesten Wertes beschränkst brauchst Du nur 6 oder 12 Bytes anstatt 2000 Bytes. Wozu soll das Speichern der letzten 500 Zykluszeiten gut sein? Die gesamt vielleicht 5 bis 30 letzten Sekunden kannst Du im Grunde eh' nur bei einem CPU-STOP auswerten.

Harald
 
RUNTIME ist ohnehin kein präzises Werkzeug. Mir ist bei einer CPU 1214 aufgefallen, dass zwei komplett leere RUNTIME-Messungen sehr unterschiedliche Bearbeitungszeiten ergeben.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Zykluszeitverlauf is nur nice to know. Es geht mir im Moment eher um mal hinter die FOR TO Schleife zu steigen. Im Moment bekomme ich es nicht hin, dass es mir die 500 Werte hintereinander in das Array schreibt. Der Code sieht folgender maßen aus im Moment:
Code:
IF #i < 500 THEN
    
    FOR #i := 1 TO 500 BY 1 DO
        // Statement section FOR
        #Zyklusnummer := #i;
        "Zyklus".Cicle[#Zyklusnummer] := "Merker_glob".Main_OB.Zyklus_ms;
        // #Zyklusnummer := #Zyklusnummer + 1;
        
    END_FOR;
    #i := #i + 1;
ELSE
    #i := 1;
END_IF;
Ich versuche mich Schritt für Schritt in SCL einzuarbeiten und hänge halt im Moment an dieser Stelle fest.

Für Tips wäre ich sehr dankbar.
 
Code:
IF #i < 500 THEN
    
    FOR #i := 1 TO 500 BY 1 DO
        // Statement section FOR
        #Zyklusnummer := #i;
        "Zyklus".Cicle[#Zyklusnummer] := "Merker_glob".Main_OB.Zyklus_ms;
        // #Zyklusnummer := #Zyklusnummer + 1;
        
    END_FOR;
    #i := #i + 1;
ELSE
    #i := 1;
END_IF;


Die SPS händelt das hochzählen von #i selber. Den Vergleich und das hochzählen brauchst du nicht manuell zu machen.


FOR #i := 1 TO 500 BY 1 DO
// Statement section FOR
#Zyklusnummer := #i;
"Zyklus".Cicle[#Zyklusnummer] := "Merker_glob".Main_OB.Zyklus_ms;
END_FOR;

Die Variable #Zyklusnummer könnte man im Prinzip auch noch rausnehmen und durch #i ersetzen.
 
Code:
IF #i < 500 THEN
    
    FOR #i := 1 TO 500 BY 1 DO
        // Statement section FOR
        #Zyklusnummer := #i;
        "Zyklus".Cicle[#Zyklusnummer] := "Merker_glob".Main_OB.Zyklus_ms;
        // #Zyklusnummer := #Zyklusnummer + 1;
        
    END_FOR;
    #i := #i + 1;
ELSE
    #i := 1;
END_IF;


Die SPS händelt das hochzählen von #i selber. Den Vergleich und das hochzählen brauchst du nicht manuell zu machen.


FOR #i := 1 TO 500 BY 1 DO
// Statement section FOR
#Zyklusnummer := #i;
"Zyklus".Cicle[#Zyklusnummer] := "Merker_glob".Main_OB.Zyklus_ms;
END_FOR;

Die Variable #Zyklusnummer könnte man im Prinzip auch noch rausnehmen und durch #i ersetzen.

OK, danke. Ich habe das jetzt mal so bereinigt wie du geschrieben hast und auch Zyklusnummer durch i ersetzt.
Allerdings schreibt er mir in alle 500 Werte immernoch den selben Wert.
Ich hätte gedacht, dadurch das ich das i gleichzeitig als Arraynummer nehme würde es mir die Werte fortlaufend in das Array schreiben. Aber da irre ich mich offensichtlich.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn Du in jedem OB1-Zyklus einen Wert in ein Array schreiben willst, dann kannst Du dafür keine FOR-Schleife benutzen sondern brauchst lediglich einen Index-Zähler, der in jedem Zyklus um 1 erhöht wird.

Eine FOR-Schleife wird immer sofort komplett mit allen Durchläufen abgearbeitet. Und das ggf. in jedem OB1-Zyklus wieder.
Die FOR-Schleife könntest Du z.B. benutzen, wenn Du auf einmal alle 500 Speicherplätze löschen willst.

Harald
 
Genau,

mit der FOR Schleife hast du halt das Problem, dass in allen 500 Variablen das gleiche drin stehen wird.
Die For Schleife wird ja nicht verlassen, bis diese abgearbeitet wurde. Sinnvoller wäre es schon, wie Harald
es beschreibt. In jedem Zyklus eine Variable loggen und den Index um +1 erhöhen. Das ganze bis 500 erreicht wurde.
 
Credo, zu deiner Frage, warum überall das gleiche drin steht:

Du kommst in die For Schleife rein. Der Index steht auf 1 und die Zykluszeit liegt bei 10ms

Jetzt schreibst du in den Index[1] 10 rein, der Index wird um +1 erhöht und das ganze beginnt wieder
bis du bei Index[500] = 10 angekommen bist. Wichtig für dich ist, dass die FOR Schleife nicht verlassen wird,
bis dein Index TO 500 erreicht ist.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn Du in jedem OB1-Zyklus einen Wert in ein Array schreiben willst, dann kannst Du dafür keine FOR-Schleife benutzen sondern brauchst lediglich einen Index-Zähler, der in jedem Zyklus um 1 erhöht wird.

Wenn Dein Cicle-Array als [0..499] deklariert ist:
Code:
#Zyklusnummer := (#Zyklusnummer + 1) MOD 500;
"Zyklus".Cicle[#Zyklusnummer] := "Merker_glob".Main_OB.Zyklus_ms;

Wenn Dein Cicle-Array als [1..500] deklariert ist:
Code:
#Zyklusnummer := (#Zyklusnummer MOD 500) + 1;
"Zyklus".Cicle[#Zyklusnummer] := "Merker_glob".Main_OB.Zyklus_ms;

PS: #Zyklusnummer (bzw. die Variable, die sich die Zyklusnummer merken soll) darf keine TEMP-Variable sein, weil sie sich ja etwas bis zum nächsten Zyklus merken muß.

btw: der Variablenname "Main_OB.Zyklus_ms" ist irreführend, wenn er tatsächlich nicht eine Zeit in Millisekunden sondern eine Zeit in Sekunden enthält.

Harald
 
Zuletzt bearbeitet:
Vielen Dank an alle!
Ich bin davon ausgegangen, das die FOR Schleife nur 1 mal Pro Zyklus aufgerufen wird, also im ersten Zyklus ist der Index i = 1 dann im nächsten Zyklus ist i=2 usw.

@Harald
der Variablenname "Main_OB.Zyklus_ms" ist schon das umgerechnte auf Millisekunden.
 
Zurück
Oben