TIA TIA SCL-Code vereinfachen ?

Zuviel Werbung?
-> Hier kostenlos registrieren
Schau dir die Sichten / Views (Deklaration mit AT) an.
Das macht dann richtig Spass!

Gruß
Dieter

Hallo Dieter,

Und schon bin ich wieder überfordert.
Meinst du "Variablen mit AT überlagern" ?
Irgendwie finde ich der Sicht nicht.

Es kann auch meine Testumgebung sein (300/400er).
Wobei ich es beim 1500er auch nicht finde.

Bram
 
Hier mal ein Beispiel mit Anypointer

Deklaration
Code:
VAR_TEMP    // temporäre Variablen
    iRetVal         : INT;  // Rückgabewert von Funktionen, SFC, ...
    anyQuellDaten   : ANY;  // Any-Pointer Quelldaten
    vQuellDaten AT anyQuellDaten : STRUCT //Sicht auf Anypointer-Quelldaten
        byID  : BYTE;
        byTyp : BYTE;
        iAnz  : INT;
        iDBNr : INT;
        dwPTR : DWORD;
        END_STRUCT;


END_VAR

Anypointer für Blockmove aufbereiten und Daten kopieren
Code:
vQuelldaten.byID  := 16#10;
vQuelldaten.byTyp := 16#02;
vQuelldaten.iAnz  := 26;
vQuelldaten.iDBNr := "Datenverw".AuftragNr + 101;
vQuelldaten.dwPtr := 16#84000000; // Zeiger auf DBX0.0
iRetVal:= BLKMOV(SRCBLK := anyQuelldaten, DSTBLK := "Auftrag".Next);

Gruß
Dieter
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Dieter,

Das muss ich mir mal im alle ruhe anschauen. Im Moment verstehe ich es nicht.
Was ich jetzt in SCL mache ist reine Analogwertverarbeitung und Rangierung der Signalen.

Da ist mir wieder so ne Sache über die Füssen gelaufen.
Was mach Mann wenn ein Boolsche variable immer mit der selbe Formel (Logik) beschrieb wird?

In mein fall :

immer wieder die Formel ausfüllen

Code:
    #HH_AL_1oo2_OUT := (#HH_AL_Intern_Channel_A AND NOT #MF_AL_Intern_Channel_A) OR (#HH_AL_Intern_Channel_B AND NOT #MF_AL_Intern_Channel_B);
        #STATE_HMI_1oo2.HH_ALARM_1oo2_OUT := (#HH_AL_Intern_Channel_A AND NOT #MF_AL_Intern_Channel_A) OR (#HH_AL_Intern_Channel_B AND NOT #MF_AL_Intern_Channel_B);
        #Comm_ZLT."STATE 1oo2".HH_ALARM_1oo2_OUT := (#HH_AL_Intern_Channel_A AND NOT #MF_AL_Intern_Channel_A) OR (#HH_AL_Intern_Channel_B AND NOT #MF_AL_Intern_Channel_B);
        #Signal_Bytes_HMI."1oo2".HH_ALARM_1oo2 := (#HH_AL_Intern_Channel_A AND NOT #MF_AL_Intern_Channel_A) OR (#HH_AL_Intern_Channel_B AND NOT #MF_AL_Intern_Channel_B);
        #Comm_ZLT."Failure Messages 1oo2".HH_ALARM_1oo2 := (#HH_AL_Intern_Channel_A AND NOT #MF_AL_Intern_Channel_A) OR (#HH_AL_Intern_Channel_B AND NOT #MF_AL_Intern_Channel_B);

Mit IF-ELSE

Code:
     IF  (#HH_AL_Intern_Channel_A AND NOT #MF_AL_Intern_Channel_A) OR (#HH_AL_Intern_Channel_B AND NOT #MF_AL_Intern_Channel_B)THEN
            #HH_AL_1oo2_OUT := true;
            #STATE_HMI_1oo2.HH_ALARM_1oo2_OUT := true;
            #Comm_ZLT."STATE 1oo2".HH_ALARM_1oo2_OUT := true;
            #Signal_Bytes_HMI."1oo2".HH_ALARM_1oo2 := true;
            #Comm_ZLT."Failure Messages 1oo2".HH_ALARM_1oo2 := true;
        ELSE
            #HH_AL_1oo2_OUT := false;
            #STATE_HMI_1oo2.HH_ALARM_1oo2_OUT := false;
            #Comm_ZLT."STATE 1oo2".HH_ALARM_1oo2_OUT := false;
            #Signal_Bytes_HMI."1oo2".HH_ALARM_1oo2 := false;
            #Comm_ZLT."Failure Messages 1oo2".HH_ALARM_1oo2 := false;
            ;
        END_IF;

Oder mit zwischenspeicher

Code:
  #Zwischenspeicher := (#HH_AL_Intern_Channel_A AND NOT #MF_AL_Intern_Channel_A) OR (#HH_AL_Intern_Channel_B AND NOT #MF_AL_Intern_Channel_B);
        #HH_AL_1oo2_OUT := #Zwischenspeicher;
        #STATE_HMI_1oo2.HH_ALARM_1oo2_OUT := #Zwischenspeicher;
        #Comm_ZLT."STATE 1oo2".HH_ALARM_1oo2_OUT := #Zwischenspeicher;
        #Signal_Bytes_HMI."1oo2".HH_ALARM_1oo2 := #Zwischenspeicher;
        #Comm_ZLT."Failure Messages 1oo2".HH_ALARM_1oo2 :=   #Zwischenspeicher;

Hab mich z.b. entschieden für die erste variant.

Bram
 
Bram, ich hätte Variante 2 verwendet.
Sie ist schlichtweg am besten lesbar.
Am schnellsten ist Variante 3.
Variante 1 würde ich nicht nehmen, du 3mal das Erbebnis bilden musst.

Gruß
Dieter
 
Mahlzeit.
Hab mich grad wegen dieser Diskusion angemeldet, da ich selber eine Frage diesbezüglich habe und jeden tag ins Forum schaue um neue Ideen zu sammeln.
Wie würdet ihr das Vorzeichen einer Real variable in SCL entfernen? Ich hab das Bisher so gemacht
Code:
 #T_POS_RE_DIF := DWORD_TO_REAL(DW#16#7FFFFFFF And REAL_TO_DWORD(#IO_AKT_PRG[1].WKZ_H - #IO_AKT_PRG[2].WKZ_H));
was absolut nicht schön ist, so mach ich das normaler weise auch in AWL.

Hallo

also bei AS300 und AS400 mach ich das auch so. Und wegen der Subtraktion ist das auch bei 1200 und 1500 nicht schlecht.

Bei 1200 und 1500 geht es inzwischen auch mittels

Code:
#T_POS_RE_DIF  := #IO_AKT_PRG[1].WKZ_H - #IO_AKT_PRG[2].WKZ_H;
#T_POS_RE_DIF.%x31 := FALSE;

dauert aber in etwa genauso lange.


'n schön' Tach auch
HB
 
Hier mal ein Beispiel mit Anypointer

Deklaration
Code:
VAR_TEMP    // temporäre Variablen
    iRetVal         : INT;  // Rückgabewert von Funktionen, SFC, ...
    anyQuellDaten   : ANY;  // Any-Pointer Quelldaten
    vQuellDaten AT anyQuellDaten : STRUCT //Sicht auf Anypointer-Quelldaten
        byID  : BYTE;
        byTyp : BYTE;
        iAnz  : INT;
        iDBNr : INT;
        dwPTR : DWORD;
        END_STRUCT;


END_VAR

Anypointer für Blockmove aufbereiten und Daten kopieren
Code:
vQuelldaten.byID  := 16#10;
vQuelldaten.byTyp := 16#02;
vQuelldaten.iAnz  := 26;
vQuelldaten.iDBNr := "Datenverw".AuftragNr + 101;
vQuelldaten.dwPtr := 16#84000000; // Zeiger auf DBX0.0
iRetVal:= BLKMOV(SRCBLK := anyQuelldaten, DSTBLK := "Auftrag".Next);

Gruß
Dieter


Nun verwirr den armen Anfänger doch nicht so.
AT ist was für Notfälle, aber kein schnelles sauberes SCL.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich muss HelleBarde ganz klar bestätigen - stell dir einfach vor deine Bedingung und die Anzahl an Zielvariablen wäre doppelt/dreifach so Umfangreich - es Gewinnt immer die 3. Varianten - in Schreibaufwand, Lesbarkeit, Wartbarkeit und Geschwindigkeit

Oberstes Ziel ist es immer redundaten Code zu vermeiden - alles was mehr als 1 mal vorkommt und komplex ist muss normalerweise in eine Zwischenvariable
 
Zuletzt bearbeitet:
Auch ich bevorzuge Variante 3. Weil diese entspricht dem Code, wie er vom KOP/FUP-Kompiler erzeugt würde.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Ralle

ABS( -3 ) ist 3
-3 AND 16#7FFF_FFFF = 16#7FFF_FFFD = 2147483645

also nicht das was hier gesucht wird.

'n schön' Tach auch
HB

Vermute aber dann ist eher sein Code nicht korrekt, denn er wollte bei einer Real das Vorzeichen entfernen.
Und dafür ist ABS() da.
Welchen Sinn ergibt dann die obige Rechnung und vor allem auch dein Codebeispiel, in dem du .x31 manipulierst?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Vermute aber dann ist eher sein Code nicht korrekt, denn er wollte bei einer Real das Vorzeichen entfernen.
Und dafür ist ABS() da.
Welchen Sinn ergibt dann die obige Rechnung und vor allem auch dein Codebeispiel, in dem du .x31 manipulierst?

Hi

jo Ralle, hast Recht, für Real sollte man ABS() nehmen.

Das .%x31 ist ein Zugriff auf das Vorzeichen bit des REAL. Für ein LREAL müsstest du .%x63 verwenden.
mit
Code:
aReal.%x31 := false
kommt genau das Gleiche raus wie mit
Code:
AND 16#7FFF_FFFF
aber ohne das ganze hin und her wandeln. Wobei REAL_TO_DWORD und DWORD_TO_REAL nur die Typprüfung beruhigen, gewandelt wird da gar nix. Deswegen ist das auch weder schneller noch langsamer.

Somit haben wir bei der 1200/1500 drei Möglichkeiten das Vorzeichen los zu werden. Und alle drei sind gleich schnell.

'n schön' Tach auch
HB
 
wobei man natürlich Code wie diesen total vermeiden sollte

Wert.%x31 := false


oder


AND 16#7FFF_FFFF

Falls bei einer Umstellung der Software aus REAL ein LREAL wird oder vielleicht ein INT
"geht" der Code immer noch - ist aber total falsch und bleibt unerkannt
 
Zurück
Oben