Step 7 Hilfe bei SCL (Schleifen-) Programmierung

Jan-Frederik

Level-1
Beiträge
27
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo in die Runde,

ich habe ein Problem, ich möchte/soll eine Schleife in SCL Programmieren bei der 32 Eingänge abgefragt werden und deren Zustandände anschließend in einen Datenbaustein geschrieben werden. Da ich ein neuling bezüglich SCL bin, bin ich für jede Hilfe dankbar :)

Grüße,

Jan-Frederik
 
Bei einer so allgemeinen Frage nenne ich mal als Stichwort AT-Sicht um die Eingänge in ein Array für die Schleife zu bekommen.
 
Hallo zusammen,

danke erst einmal für die schnellen Antworten ;)

Bis dato schreibe ich die Eingänge auf Lokaldaten in einer "Schrittkette", wie im Bild zu sehen.
Hat der Eingang eine 0, wird B#16#0 in die Lokaldaten oder dem Datenbaustein geschrieben,
Hat der Eingang eine 1, wird b#16#1 in die Lokaldaten oder dem Datenbaustein geschrieben.
Das LH bedeutet " Last High" und beinhaltet dann betragsmäßig die aktuell letzte anzahl der Eingänge die eine 1 haben. Siehe die rote 1 auf dem Bild.
Die roten Zahlen 2 und 3 dienen dazu, die komplette Länge in Byte und Integer wieder zu geben. Das soll heißen, wenn von den 32 Eingängen 10 logisch 1 sind, soll
in einem Weiteren Byte und Integer b#16#A bzw 10 stehen.
Slot_pg.PNG

In dem Datenbaustein soll das dann noch so aussehen wie folgt..
DB_Slot.PNG
Eingang1 ist 1 = Byte 1 = b#16#01
Eingang2 ist 1 = Byte 2 = b#16#02
Eingang3 ist 0 = Byte 3 = b#16#00
Eingang4 ist 0 = Byte 4 = b#16#00
Eingang5 ist 1 = Byte 5 = b#16#03
Eingang6 ist 0 = Byte 6 = b#16#00
Eingang7 ist 0 = Byte 7 = b#16#00
...

Ich weiß, das ist wirklich komplex aber ich hoffe, jemand kann mir helfen.
Danke im Voraus :)
 

Anhänge

  • Slot_pg.PNG
    Slot_pg.PNG
    15,2 KB · Aufrufe: 29
Ich weiß, das ist wirklich komplex aber ich hoffe, jemand kann mir helfen.
Danke im Voraus :)

Das ist überhaupt nicht komplex. In SCL ist das n 5 Zeiler
Die Anfangsarbeit wäre einfach. BoolArray auf deine Eingänge legen (Bei S7-1500 UDT mit Array), Sinnigerweise von [1..16] dann stimmts grad mit dem Index.
N Byte array, ebenfalls 1..16 über deine Bytes legen (man könnte dazu natürlich auch n Pointer basteln)

FOR Schleife Basteln in der du Arraymember des Boolarray abfragst und bei true entsprechend den Arraymember des Bytearrays abfüllst. Sinnigerweise grad mit dem Inhalt des Index (darum Array ab 1 und nicht ab 0)

mfG René
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo René,

ich habe hier eine 314 er auf dem Tisch. Vom Grundprinzip kann ich dir schon etwas folgen aber was ist jetzt ein Arraymember?
Entschuldigung für die dumme Frage aber ich bin ein absoluter beginner, was SCL angeht :(

MfG Jan-Frederik
 
Arramember ist eine indexierte Variable des Arrays.
Bei einem Array of bool
Code:
   VAR_INPUT 
      Inputs : Array[1..16] of Bool;
   END_VAR

Wäre #Inputs[3] ein Mitglied (member) des Arrays nämlich hier das 3.
Du könntest also eine For schleife basteln mit Index 1 bis 16.
Fragst dann den Member des grad aktiven Index ab ob er true ist. Wenn ja schreib den Index auf den Member des Bytearrays. Weil index ja da grade 3 hat wird also das 3. Byte mit dem inhalt der indexvariable beschrieben und schon hast du die funktion die du dir wünscht.

mfG René
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Jetzt kannst du z.B. mit
IF inputs[index] THEN
Abfragen ob der Input mit der gleich dem Index ist true ist
THEN
Weise dem Byte des byte arrays den Wert der aktuell in Index steht zu.
Die bytes stehen idealerweise dann natürlich auch als Array zur verfügung.

Code:
	IF Inputs[index] THEN
        Bytes[index] := INT_TO_BYTE(index);
    END_IF;

Gleichzeitig macht es natürlich sinn das entsprechende Byte gleich auf 0 zu setzen wenn die Bedingung nicht erfüllt ist. Wo und wie du das machst ist deine Sache.
 
Die Bytes müssen natürlich auch in einem Array deklariert sein. Da du ja 16 verschiedene Bytes dem entsprechenden eingang zuordnen willst. Ausserdem solltest du bedenken dass temp Variablen schon einen Inhalt haben können. Die Bytes müssen also zwingend irgendwo beschrieben werden. Alle! Nicht nur die welche du mit dem indexinhalt beschreibst.

mfg René
 
was klappt denn nicht?
so als kleines Beispiel wie man das machen könnte. Ist also kein Hexenwerk.
ist jetzt natürlich nur in Notepad zusammengetippt. Aber ungefähr so müsste es direkt übersetzbar sein.
Code:
FUNCTION "Sowasaberauch" : Void
VERSION : '0.1'
   VAR_INPUT 
      Inputs : Array[1..16] of Bool;
   END_VAR


   VAR_TEMP 
      Bytes : Array[1..16] of Byte;   
      index : Int;
   END_VAR




BEGIN
	FOR #index := 1 TO 16 DO
	    IF #Inputs[#index] THEN
	        #Bytes[#index] := INT_TO_BYTE(#index);
	    ELSE
	        #Bytes[#index] := 0;
	    END_IF;
	END_FOR;
END_FUNCTION
 
Jetzt funktioniert es, habe wohl zu früh die Flinte ins Korn geworfen:?

Vielen vielen Dank für deine Hilfe, das Kann man quasi direkt übersetzen, jetzt muss ich die Daten nur noch in einen DB bekommen, dann hab ich´s...

nochmals vielen Dank ;)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Sollte nicht eigentlich die Anzahl 1-Bits gezählt werden, sprich in #Bytes[#index] sollte die bisher gezählte Anzahl stehen und nicht einfach nur der Index?

Übrigens gibt es einen DWORD-Bitzähler schon fertig: FC99 BITSUM, der macht das Zählen über Bitschieben und -testen, da braucht man nicht soviel Adressrechnerei.

Harald
 
Sollte nicht eigentlich die Anzahl 1-Bits gezählt werden, sprich in #Bytes[#index] sollte die bisher gezählte Anzahl stehen und nicht einfach nur der Index?
Harald
Hatte ich auch so gelesen.

Code:
FUNCTION "Sowasaberauch" : Void
VERSION : '0.1'
   VAR_INPUT 
      Inputs : Array[1..16] of Bool;
   END_VAR


   VAR_TEMP 
      Bytes : Array[1..16] of Byte;   
      index[COLOR=#ff0000],_counter[/COLOR] : Int;
   END_VAR




BEGIN
        [COLOR=#ff0000]_counter:=0;[/COLOR]
	FOR #index := 1 TO 16 DO
	    IF #Inputs[#index] THEN
                #Bytes[#index] := INT_TO_BYTE([COLOR=#ff0000]_counter + 1[/COLOR]);
	    ELSE
	        #Bytes[#index] := 0;
	    END_IF;
	END_FOR;
END_FUNCTION

So in der Art.
 
Zurück
Oben