Array of BOOL mit UND auswerten

Zuviel Werbung?
-> Hier kostenlos registrieren
// Flur Rechts
FOR iFlurOben := 1 TO 5 BY 1 DO
GVL.xGesPrasenzFlurRechts := GVL.xGesPrasenzFlurRechts OR aPrasenzFlurRechts[iFlurRechts];
END_FOR
:unsure:
Ist die falsche Laufvariable hier nur ein Abtippfehler oder ist/war das auch so im Original?
 
Code:
// Flur Rechts
FOR iFlurOben := 1 TO 5 BY 1 DO
    GVL.xGesPrasenzFlurRechts := GVL.xGesPrasenzFlurRechts OR aPrasenzFlurRechts[iFlurRechts] ;
END_FOR ;
Das kann nicht funktionieren. Die LaufVariable 'iFlurOben' wird durch die ForSchleife zwar von 1 bis 5 bzw. 6 hochgezählt, ABER diese LaufVariable wird in der Schleife gar nicht benutzt, weil dort stattdessen der falsche VariablenName 'iFlurRechts' benutzt wird und deshalb bei jedem SchleifenDurchlauf auf dasselbe ArrayElement zugegriffen wird ... oder auf ein nicht existierendes Element ausserhalb des definierten ArrayBereiches, denn in 'iFlurRechts' könnte ja ein Wert <1 oder >5 stehen.
Die Variable 'GVL.GesPrasenzFlurRechts' muss vor der FOR-Schleife zwingend mit FALSE (oder mit einem Element des Arrays 'aPrasenzFlurRechts[]') vorbesetzt werden.
Dadurch kann 'GVL.GesPrasenzFlurRechts' selbstverständlich vorübergehend einen falschen bzw. den nicht endgültigen Wert beinhalten. Der Wert "flackert" also, aber wen juckt das denn?
Nach Durchlaufen der Schleife (auch bei vorzeitigem Abbruch der Schleife per EXIT - wie von Harald vorgeschlagen) ist das Flackern vorbei.
Will man partout das Flackern in der "ErgebnisVariablen" vermeiden, dann benutzt man eine HilfsVariable und kopiert ihren Inhalt nach der Schleife in die ErgebnisVariable um.

Edit: Warum konnte ich Deinen Beitrag erst sehen, nachdem ich meinen abgeschickt habe, Mario?
 
Dadurch kann 'GVL.GesPrasenzFlurRechts' selbstverständlich vorübergehend einen falschen bzw. den nicht endgültigen Wert beinhalten. Der Wert "flackert" also, aber wen juckt das denn?
Wenn GVL.GesPrasenzFlurRechts in einer anderen Task gelesen wird (z.B. in einer schnelleren bzw. höherprioren Task) und diese Task kann die Task der Berechnung unterbrechen, dann kann die Unterbrechung auch mitten im Schleifendurchlauf passieren und der Wert kann beim Leser "flackern". Oder wenn die Variable an eine Function per Referenz übergeben wird, und die lesende Task unterbricht die Task der Function, dann kann das "flackern" ebenfalls passieren. Bei mehrfachen Zuweisungen empfiehlt es sich, (vorsichtshalber) zunächst auf eine Hilfsvariable zuzuweisen, und erst danach auf die Ergebnisvariable umzukopieren.
 
Moin zusammen,
Dank Eures Inputs kam ich auf die nun funktionierende Lösung. Basis war der Vorschlag von PN/DP. Den Befehl Exit kannte ich noch nicht und war der Gamechanger:
Danke an Euch!

Code:
VAR
// Trigger Berechnung
    BlinkHelligkeit             : WagoAppBuildingHVAC.FbBlinker;                                                                            // Trigger zum berechnen der Flurhelligkeit
    tcp_BlinkHelligkeit         : typConfigBlinker := (tTimeHigh := TIME#500MS, tTimeLow := TIME#30S);                                        // Config BlinkHelligkeit
    
// Flanke Berechnung
    R_TRIGBerechnung             : R_TRIG;                                                                                                    // Erkennung Flanke pos. Berechnung

// Helligkeitsauswertung
// Flur Nord                                                                                                   
    rHV_FlurHelligkeitN         : REAL;                                                                                                        // Hilfsvariable Merker
    iFlurH_N                     : INT := 1;                                                                                                    // Laufvariable
END_VAR

// Flur Nord
    xHV_FlurPIR_N := FALSE;   
    FOR iFlurP_N := 1 TO CONST.bcMaxMS_FlurN BY 1 DO
        IF GVL.asFlur_DataIn_Nord[iFlurP_N].xPrasenz THEN
            xHV_FlurPIR_N := TRUE;
            EXIT;
                ELSE
                    xHV_FlurPIR_N := FALSE;               
        END_IF
    END_FOR
    GVL.asFlur_DataOut_Nord.xMW_Prasenz := xHV_FlurPIR_N;
 
Du könntest es dir auch noch einfacher machen :
In deiner Schleife zählst du einfach eine Variable hoch wenn du ein Präsenz-Bit hast. Vor der Schleife mußt du diese Variable natürlich nullen.
Ist nach der Schleife die Variable > 0 dann hast du eine Präsenz, ist sie = 0 dann wurde nirgendwo etwas erkannt ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
VAR
// Trigger Berechnung
    BlinkHelligkeit             : WagoAppBuildingHVAC.FbBlinker;                                                                            // Trigger zum berechnen der Flurhelligkeit
    tcp_BlinkHelligkeit         : typConfigBlinker := (tTimeHigh := TIME#500MS, tTimeLow := TIME#30S);                                        // Config BlinkHelligkeit
 
// Flanke Berechnung
    R_TRIGBerechnung             : R_TRIG;                                                                                                    // Erkennung Flanke pos. Berechnung

// Helligkeitsauswertung
// Flur Nord                                                                                               
    rHV_FlurHelligkeitN         : REAL;                                                                                                        // Hilfsvariable Merker
    iFlurH_N                     : INT := 1;                                                                                                    // Laufvariable
END_VAR

// Flur Nord
    xHV_FlurPIR_N := FALSE;
    FOR iFlurP_N := 1 TO CONST.bcMaxMS_FlurN BY 1 DO
        IF GVL.asFlur_DataIn_Nord[iFlurP_N].xPrasenz THEN
            xHV_FlurPIR_N := TRUE;
            EXIT;
                ELSE
                    xHV_FlurPIR_N := FALSE;           
        END_IF
    END_FOR
    GVL.asFlur_DataOut_Nord.xMW_Prasenz := xHV_FlurPIR_N;
Die beiden gestrichenen Zeilen können weg. Das EXIT bewirkt, dass die Schleife beim erstbesten 'GVL.asFlur_DataIn_Nord[iFlurP_N].xPrasenz = TRUE' verlassen wird und evtl. nachfolgende Elemente des Array mit Inhalt FALSE werden nicht mehr abgefragt.
Im Falle, dass alle ArrayElemente 'GVL.asFlur_DataIn_Nord[iFlurP_N].xPrasenz = FALSE' sind, ist 'xHV_FlurPIR_N' mit FALSE passend vorbesetzt.

PS:
Normalerweise kann man zwei komplette Arrays mit einem Befehl auf gleich bzw. ungleich vergleichen
(z.B. IF aArray1[] = aArray2[] THEN ...).
Will man also ein komplettes Array darauf hin prüfen, ob alle Elemente leer sind, muss man nicht alle bzw. mehrere Elemente einzeln prüfen, aber man benötigt zum Vergleich ein leeres Array, das dieselbe Anzahl Elemente hat UND denselben DatenTyp.
 
Zuletzt bearbeitet:
Den Befehl Exit kannte ich noch nicht und war der Gamechanger
Das EXIT kann man auch weglassen und dafür die temporäre Variable immer mit dem jeweiligen Präsenzmelder OR-verknüpfen, dann wird die Schleife mit allen Durchläufen immer voll durchlaufen ---> gleich bleibende (aber längere) Bearbeitungszeit/Zykluszeit.
Mit EXIT wird die Schleife beim ersten gfundenen TRUE verlassen/beendet, weil sich danach das Ergebnis der eingesparten OR-Verknüpfung sowieso nicht mehr ändern kann. :cool:

Ohne EXIT:
Code:
    xHV_FlurPIR_N := FALSE;

    FOR iFlurP_N := 1 TO CONST.bcMaxMS_FlurN BY 1 DO
        xHV_FlurPIR_N := xHV_FlurPIR_N OR GVL.asFlur_DataIn_Nord[iFlurP_N].xPrasenz;
    END_FOR;

    GVL.asFlur_DataOut_Nord.xMW_Prasenz := xHV_FlurPIR_N;


Code:
// Flur Nord
    xHV_FlurPIR_N := FALSE;
    FOR iFlurP_N := 1 TO CONST.bcMaxMS_FlurN BY 1 DO
        IF GVL.asFlur_DataIn_Nord[iFlurP_N].xPrasenz THEN
            xHV_FlurPIR_N := TRUE;
           EXIT;
                ELSE                          <-- überflüssig
                    xHV_FlurPIR_N := FALSE;   <-- überflüssig
        END_IF                              <-- ; fehlt
    END_FOR                                 <-- ; fehlt
    GVL.asFlur_DataOut_Nord.xMW_Prasenz := xHV_FlurPIR_N;
Der ELSE-Zweig ist völlig überflüssig, weil xHV_FlurPIR_N schon vor der Schleife mit FALSE vorbelegt wurde.
Das "BY 1" braucht man auch nicht hinschreiben, das ist bei FOR-Schleifen Standard.
PPS: hinter END_IF und END_FOR fehlen die Semikolons ";"

PS: @Heinileini war schneller
Die beiden gestrichenen Zeilen
Leider kann man im neuen Forum Text in einer Code-Box nicht mehr formatieren (farbig, fett, durchgestrichen). Die Format-Tags werden ignoriert.
 
Zuletzt bearbeitet:
Leider kann man im neuen Forum Text in einer Code-Box nicht mehr formatieren (farbig, fett, durchgestrichen). Die Format-Tags werden ignoriert.
So hatte ich es mir eigentlich auch gemerkt, war mir aber nicht ganz sicher. Darum habe ich's ausprobiert. Vor und sogar unmittelbar nach dem Abschicken war meine Streichung noch sichtbar. Jetzt ist sie's nicht mehr. Sorry vielstmals!
"WYSIWYG" (= What you see is what you get) war doch mal das Zauberwort in der WindowsWerbung.
Das waren noch Zeiten, als man wenigstens noch versucht hat, solche Selbstverständlichkeiten umzusetzen. ;)
 
Zurück
Oben