Step 7 SCL ARRAY of UDT schreiben (FC -> FB -> DB)

Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn du ohnehin nur Konstanten an die Function übergibst, und in der FC auch nur Konstanten in das ARRAY einträgst, warum dann überhaupt der Aufwand mit der FC? Schreibe doch deine Werte direkt in die Bytes. Du kannst in der Deklaration des FB auch symbolische Konstanten anlegen und diese statt "B#16#00" und "B#16#01" verwenden. In einer FOR-Schleife würdest du dann überall die selben Werte rein schreiben?
Hi, nein da wird in Abhängigkeit bestimmter Bedingungen ein Status geschrieben. Der Code oben war nur ein Auszug .
 
Moin!

Wie PN/DP und Dagobert angemerkt haben: Warum ein extra FC?
Vorgabe
Bei PN/DP möchte ich ergänzen das jeder Bausteinaufruf auch Zykluszeit "frisst"! Wir mussten schon die Verschachtelungstiefe / Bausteinaufrufe reduzieren Aufgrund zu hoher Zykluszeit.
Noch nicht kritisch :)
Du kannst auch einfach folgende Zeilen anstelle des FCs nutzen, damit Fallen selbst die IF..ELSE weg.
BOOL wird auch implizit konvertiert, ich bevorzuge die explizite Konvertierung.

Q_dbxxx[X].bYTE1 := BOOL_TO_BYTE("VAR für I_x1 vom Aufruf X");
Q_dbxxx[X].bYTE2 := BOOL_TO_BYTE("VAR für I_x1 vom Aufruf X" AND "VAR für I_x2 vom Aufruf X");
Danke Dir für den Vorschlag
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi Zusammen
Danke euch allen für eure Hilfe.

Ich hätte noch eine zusätzliche Frage zum Array.

Kann ich relativ einfach ein bei einem ARRAY OF BOOL abfragen ob alle bits in diesem ARRAY gesetzt sind ?


So kann ich das ja auf jedes Bit einzeln abfragen, will nur nicht das ganze 64 mal machen
IF xBitOfArray[1] = TRUE THEN xKonfigDone:= TRUE; END_IF;
 
Zuletzt bearbeitet:
Kann ich relativ einfach ein bei einem ARRAY OF BOOL abfragen ob alle bits in diesem ARRAY gesetzt sind ?
Wenn Du feststellen willst, ob ALLE Bits gesetzt sind, kannst Du in einer FOR-Schleife alle Bits abfragen, aber die Schleife abbrechen, sobald das erste Bit gefunden wird, das nicht gesetzt ist.

Code:
xKonfigDone := TRUE ;
FOR idx := 1 TO 64 // ggfs anpassen, z.B. 0..63
    IF NOT xBitOfArray[idx] THEN
        xKonfigDone := FALSE ;
        EXIT ;
    END_IF;
END_FOR ;
oder mit Umweg über zählen und deshalb ohne Abkürzung durch EXIT:
Code:
iBitCount := 0 ;
FOR idx := 1 TO 64 // ggfs anpassen, z.B. 0..63
    IF xBitOfArray[idx] THEN
        iBitCount := iBitCount + 1 ;
    END_IF;
END_FOR ;
xKonfigDone := iBitCount = 64 ;
Dann kann man sich noch den Luxus erlauben, den Zähler als "FortschrittsBalken" zu visualisieren. ;)
 
Zuletzt bearbeitet:
Meines Wissens gibt es kein Biblioteksfunktion dafür.

Ich wurde dafür WORD Logik oder DWORD Logik verwenden.
Ungf.:

Code:
MyArray : ARRAY[0..15] OF BOOL ;
MyWord AT MyArray : WORD ;
AlleBitsTrue : BOOL ;

// alle bits TRUE ?
AlleBitsTrue := MyWord = W#16#FFFF ;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Kann ich relativ einfach ein bei einem ARRAY OF BOOL abfragen ob alle bits in diesem ARRAY gesetzt sind ?
Wenn Du Dein ARRAY [1..64] OF BOOL zwingen kannst, daß es auf den selben Speicheradressen wie ein LWORD oder 2 DWORD oder allgemein xWORD liegt (in Speicher mit "Standard"-Zugriff legen oder dorthin kopieren), dann kannst Du die xWORDs auswerten. Wenn das ARRAY in "optimiertem" Speicher liegt, dann geht das nicht, dann muß jedes Bool einzeln geprüft werden.

Möglicherweise geht auch, daß Du Dir ein Vergleichs-Array erzeugst/hinterlegst, wo alle Bits/Bools gesetzt sind, und dann vergleichst ob die Arrays gleich sind (gleichen Inhalt haben). Das wird dann aber aufwändiger als es aussieht, auch wenn der Vergleich nur eine einzelne Anweisung ist, weil da im Hntergrund alle 64 Bits einzeln verglichen werden. Da kommt es auf den SCL-Compiler drauf an wie effizient der erzeugte Programmcode wird.

Harald
 
Was ich bei den AT-Sicht elegant finde, ist dass es wird keine Daten hin oder her kopiert. Es sind dieselbe Daten die nur mit eine anderen Deklaration betrachtet wird.
 
In "wirklich optimiertem" Speicher geht aber kein AT ("international" nennt sich das UNION). AT geht nur in Speicher, wo die Variablen eine referenzierbare Anfangsadresse haben und Struct/Array-Member (lückenlos) hintereinander liegen. Der TIA-SCL-Compiler ist leider (absichtlich) so doof, daß er in "optimiertem" Speicher kein Bool-Array auf ein DWORD legen kann, bzw. überhaupt gar nicht 2 Variablen auf die selbe Adresse/Speicherplatz legen kann.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin,

als relativ einfache Lösung:

Code:
TempBool := TRUE;

For Index := 1 TO 64 DO

    TempBool := TempBool AND Array[Index];

END_FOR;

Ist TempBool hinter der FOR-Schleife TRUE sind alle Elemente TRUE.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
als relativ einfache Lösung:

Code:
TempBool := TRUE;

For Index := 1 TO 64 DO

    TempBool := TempBool AND Array[Index];

END_FOR;
Relativ einfach ja, aber auch relativ uneffizient, weil in jedem Schleifendurchlauf ein Zwischenergebnis gebildet und gespeichert wird. Das ist bei AND aber gar nicht nötig, sondern nur wenn (das erste) FALSE gefunden wird. Und da kann man die Schleife auch gleich abbrechen. So wie Heinileini schon gezeigt hatte:
Code:
xKonfigDone := TRUE ;
FOR idx := 1 TO 64 DO // ggfs anpassen, z.B. 0..63
    IF NOT xBitOfArray[idx] THEN
        xKonfigDone := FALSE ;
        EXIT ;
    END_IF;
END_FOR ;

Harald
 
Relativ einfach ja, aber auch relativ uneffizient, weil in jedem Schleifendurchlauf ein Zwischenergebnis gebildet und gespeichert wird. Das ist bei AND aber gar nicht nötig, sondern nur wenn (das erste) FALSE gefunden wird. Und da kann man die Schleife auch gleich abbrechen. So wie Heinileini schon gezeigt hatte:
Moin Harald

Du hast Recht das ist nicht der effizienteste Code! Meiner Erfahrung nach wirken sich Bausteinaufrufe (hier der Aufruf des FC) stärker auf die Zykluszeit aus wie die Schleife.
Es geht mir mit meinem Vorschlag auch nicht um den effizientesten, sondern einen übersichtlichen Code und eine relativ stabile Zykluszeit.
 
Zurück
Oben