AND O Gewichtung in ST

SY50

Level-1
Beiträge
271
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo, ich habe ein Programm bekommen, was ich auf eine Andere Steuerung umsetzen soll.

Nun sind hier viele Dinge zwar schon in ST gemacht, allerdings mit vielen Verknüpfungen in einer Zeile.
Ich wollte diese Bedingungen nun in eine IF abfrage packen und etwas leserlicher verschachteln.

Nun zur Frage: Wie ist die gewichtung von AND und OR in ST???? Kann man das so sehen wie Punkt vor Strichrechnung? ---> AND vor OR????

Hier ein zu übersetzender Programmcode:

Code:
sac_virtual_master.Start:=SR_start_ref.Q1 AND CAC_main_drive.ActualAxisMode=7 OR sac_virtual_master.AxisMode=1 AND machine_running OR sac_virtual_master.AxisMode=1 AND  tip_buttom;

Wie würde das hier aussehen?

Danke schon mal
 
AND geht vor OR - das ist auch so im Codesys-Handbuch dokumentiert, Stichworte: Ausdrücke, Bindungsstärke.

Doch warum willst Du den perfekten Zuweisungsausdruck in dieses unsägliche IF..THEN verschlimmbessern? Man kann auch Zuweisungsausdrücke übersichtlich mehrzeilig formatieren.

Bei der Umwandlung einer Zuweisung in IF..THEN besteht die Gefahr, daß (fehlerhafter) Code programmiert wird, der anders als der original-Code funktioniert; oder es wird (durch die dann 2 Zuweisungen) wahrscheinlich einfach nur sinnlos aufgeblähter Code erzeugt.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja wie du vermutest AND vor UND
um eine bessere Lesbarkeit zu erhalten reicht es meistens schon aus es untereinander zu schreiben
z.B.

sac_virtual_master.Start := R_start_ref.Q1 AND CAC_main_drive.ActualAxisMode=7
OR sac_virtual_master.AxisMode=1 AND machine_running
OR sac_virtual_master.AxisMode=1 AND tip_buttom;

mfg Jochen
 
Ja wie du vermutest AND vor UND
um eine bessere Lesbarkeit zu erhalten reicht es meistens schon aus es untereinander zu schreiben
z.B.

sac_virtual_master.Start := R_start_ref.Q1 AND CAC_main_drive.ActualAxisMode=7
OR sac_virtual_master.AxisMode=1 AND machine_running
OR sac_virtual_master.AxisMode=1 AND tip_buttom;

mfg Jochen

Hier ein Vorschlag, das brauchen wir zuerst (kann als *.lib gespeichert werden)
(*Funktion*)
FUNCTION FC_8_Bit_to_Byte: BYTE
VAR_INPUT
B0:BOOL;
B1:BOOL;
B2:BOOL;
B3:BOOL;
B4:BOOL;
B5:BOOL;
B6:BOOL;
B7:BOOL;
END_VAR
VAR
END_VAR
(*************************************************************)
FC_8_Bit_to_Byte:=0;


FC_8_Bit_to_Byte:= BOOL_TO_BYTE(B0)
OR SHL(BOOL_TO_BYTE(B1),1)
OR SHL(BOOL_TO_BYTE(B2),2)
OR SHL(BOOL_TO_BYTE(B3),3)
OR SHL(BOOL_TO_BYTE(B4),4)
OR SHL(BOOL_TO_BYTE(B5),5)
OR SHL(BOOL_TO_BYTE(B6),6)
OR SHL(BOOL_TO_BYTE(B7),7);
(**********************************************************************)
(*ENDE Funktion*)


(*Programm*)
Cmd:=FC_8_Bit_to_Byte(
(*1*) B0:=R_start_ref.Q1,
(*2*) B1:=CAC_main_drive.ActualAxisMode=7,
(*4*) B2:=sac_virtual_master.AxisMode=1,
(*8*) B3:=machine_running ,
(*1*) B4:=sac_virtual_master.AxisMode=1
(*2*) B5:= tip_buttom,
(*4*) B6:=0,
(*8*) B7:=0,
);
sac_virtual_master.Start:=0;(*RS *)

CASE Cmd OF
16#03: sac_virtual_master.Start:=1;
16#0C: sac_virtual_master.Start:=1;
16#30: sac_virtual_master.Start:=1;
END_CASE;


Oder
sac_virtual_master.Start:=0;(*RS *)

CASE Cmd OF
16#03,16#0C,16#30: sac_virtual_master.Start:=1;
END_CASE;

(******************************************************)
wird was zusaetzlich gebraucht, einfach in case einfuegen

Irek
 
@Irek
Einer unserer langjährigen Lieferanten hat neulich einen Millionenauftrag verloren wegen unübsichtlicher, schwer verständlicher Programmierung.
Mit so einem Code wie du ihn hin hier zeigst, würdest du bei uns nicht ins Haus kommen.
Welcher Instandhalter soll das noch nachvollziehen können?

Gruß
Dieter
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Irek
Einer unserer langjährigen Lieferanten hat neulich einen Millionenauftrag verloren wegen unübsichtlicher, schwer verständlicher Programmierung.
Mit so einem Code wie du ihn hin hier zeigst, würdest du bei uns nicht ins Haus kommen.
Welcher Instandhalter soll das noch nachvollziehen können?

Gruß
Dieter

Ja, das trift hier zu, weil bei vielen das Wissen um Binaerzahlen und HEX-Zahlen nicht vorhanden sei.
Wer aus der Siemenswelt kommt und mit U E1.1 O E1.3 SA1.1 programmiert hat ist hier total verloren.
Ich sehe das auch bei uns, mit Siemens angefangen und stehengeblieben!
Bei Codesys (Beckhoff) wird dann meistens in uneffektiven FUP programmiert, deswegen kommen manche Zeilen in eine Lib,
und der Delikvent kann dann seine Legos zusammensetzen.

Irek
 
@Irek
Einer unserer langjährigen Lieferanten hat neulich einen Millionenauftrag verloren wegen unübsichtlicher, schwer verständlicher Programmierung.
Mit so einem Code wie du ihn hin hier zeigst, würdest du bei uns nicht ins Haus kommen.
Welcher Instandhalter soll das noch nachvollziehen können?

Gruß
Dieter

Warum schreibt ihr dann nicht in euer Lastenheft: "Unsere Instandhalter verstehen nur 0815 Binärverknüpfungen. Bitte Programmcode entsprechend aufblähen". Ich wette euer Langjähriger Lieferant hätte dann auch entsprechend geliefert.

Ich fasse da wo es sinnvoll ist auch binäre Signale in Bytes, Wörtern oder Doppelwörtern zusammen und arbeite dann mit denen weiter. Gerade beim Auswerten von Signalskombinationen bei denen es dutzende oder hunderte Zustände geben kann wird die Instandhaltung mit der "klassischen" Bitverknüpfung garantiert auch nicht Glücklicher.
 
@Irek

Was ist an deiner Programmierung übsichtlicher oder besser als an der Programmierung von Jochen?

sac_virtual_master.Start := R_start_ref.Q1 AND CAC_main_drive.ActualAxisMode=7
OR sac_virtual_master.AxisMode=1 AND machine_running
OR sac_virtual_master.AxisMode=1 AND tip_buttom;

Und stell dir vor, ich würde sowas simples wie einen NC-Start sogar auch in Codesys in FUP packen.
Einfach weil ich dann weiss, dass es der Instandhalter locker findet und ich dann nicht in meiner Freizeit gestört werde.

Gruß
Dieter
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Doch warum willst Du den perfekten Zuweisungsausdruck in dieses unsägliche IF..THEN verschlimmbessern?
Vermutlich, weil IF..THEN..ELSE-Konstrukte vieles besser verständlich machen, wenn man eher ereignisorientiert denkt und arbeitet. Man könnte z. B. schreiben:
Code:
IF CAC_main_drive.ActualAxisMode=7
THEN
   sac_virtual_master.Start:=SR_start_ref.Q1;
ELSIF sac_virtual_master.AxisMode=1
THEN
   sac_virtual_master.Start:=machine_running OR tip_buttom;
ELSE
   sac_virtual_master.Start:=FALSE;
END_IF
Ob das der Verständlichkeit förderlich ist, kann man anhand der einzelnen aus dem Zusammenhang herausgelösten Codezeile nicht wirklich beurteilen. Wenn ich nur die eine Zeile betrachte, würde ich aber auch als grundsätzlicher IF..THEN..ELSE-Befürworter darauf verzichten.

@Irek
Hast Du vielleicht vergessen, Deinen Beitrag als "Fun zum Feierabend" zu kennzeichnen?
Wie lange wird es dauern, bis jemand endlich herausgefunden hat, wann sac_virtual_master.Start = True wird? Ich bin solchen Basteleien gegenüber nicht von vornherein abgeneigt, aber in diesem Fall ist das weit über das Ziel hinausgeschossen. Und aussagekräftige Konstantennamen statt Zahlenwerte für die CASE-Selektoren sind das Mindeste, was man dabei seiner Nachwelt zugute tun sollte.
 
Warum schreibt ihr dann nicht in euer Lastenheft: "Unsere Instandhalter verstehen nur 0815 Binärverknüpfungen. Bitte Programmcode entsprechend aufblähen". Ich wette euer Langjähriger Lieferant hätte dann auch entsprechend geliefert.

Ich fasse da wo es sinnvoll ist auch binäre Signale in Bytes, Wörtern oder Doppelwörtern zusammen und arbeite dann mit denen weiter. Gerade beim Auswerten von Signalskombinationen bei denen es dutzende oder hunderte Zustände geben kann wird die Instandhaltung mit der "klassischen" Bitverknüpfung garantiert auch nicht Glücklicher.

Unsere Instandhalter verstehen deutlich mehr als simple Biverknüpfungen.

Welcher Code ist übersichtlicher? Der von Jochen oder der von Irek?
Wie gehst du bei Fehlersuche an einer fremden Anlage vor?
Wo erkennst du schneller welche Bedingung fehlt?
Wenn ein Signal flackert (soll ja bei NC-Freigaben durchaus vorkommen) wo siehst du schneller welches konkrete Signal?
Wenn du an der Anlage ein weiteres Signal verknüpfen musst ... Wo ist es einfacher?

Gruß
Dieter
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Dieter

vielleicht so

(*Programm*)
Cmd:=FC_8_Bit_to_Byte(
(*1*) B0:=R_start_ref.Q1,
(*2*) B1:=CAC_main_drive.ActualAxisMode=7,
(*4*) B2:=sac_virtual_master.AxisMode=1,
(*8*) B3:=machine_running ,
(*1*) B4:=sac_virtual_master.AxisMode=1
(*2*) B5:= tip_buttom,
(*4*) B6:=0,
(*8*) B7:=neues_Signal,
);
sac_virtual_master.Start:=0;(*RS *)
neues_Resultat:=0;
CASE Cmd OF
16#03: sac_virtual_master.Start:=1;
16#0C: sac_virtual_master.Start:=1;
16#30: sac_virtual_master.Start:=1;
16#80: neues_Resultat:=1;
END_CASE;


Oder
sac_virtual_master.Start:=0;(*RS *)
neues_Resultat:=1;
CASE Cmd OF
16#03,16#0C,16#30: sac_virtual_master.Start:=1;
16#80: neues_Resultat:=1;
END_CASE;

(******************************************************)
wird was zusaetzlich gebraucht, einfach in case einfuegen

Irek
 
@Irek

Das Verfahren ist mir schon klar, was mich daran stört ist die vermeintliche Unübersichtlichkeit.
Die eigentlich einfache binäre Logik muss ich mir bei deinem Verfahren erst "zurückrechnen".
Der Code ist nicht kürzer, die Programmausführung nicht schneller.
Einzig bei einer HMI-Diagnose kann ich mir Vorteile vorstellen.

Persönlich würde ich sowas einfach in Funktionplan programmieren:

FUP.JPG

Gruß
Dieter
 
@ Dieter

Cmd:=FC_8_Bit_to_Byte(
(*1*) B0:=R_start_ref.Q1 and _Freigabe, (*Zusatzbedinung*)
(*2*) B1:=CAC_main_drive.ActualAxisMode=7,
(*4*) B2:=sac_virtual_master.AxisMode=1,
(*8*) B3:=machine_running,
(*1*) B4:=sac_virtual_master.AxisMode=1
(*2*) B5:= tip_buttom,
(*4*) B6:=0,
(*8*) B7:=neues_Signal and not machine_running (*Ausmaskieren = sperren*)
);

Das ist genau der Zweck an der Sache, wobei nach einigen Tagen sind die Hex-Zahlen einfach zu handhaben, Sache der Gewoehnung

Gruss
Irek
 
Zuviel Werbung?
-> Hier kostenlos registrieren
wobei nach einigen Tagen sind die Hex-Zahlen einfach zu handhaben, Sache der Gewoehnung
Der Instandhalter in der Nachtschicht hat aber nicht tagelang zeit, um herauszubekommen, warum er die Maschine oder Anlage nicht starten kann. Da muß er schnell die Ursache finden - mit rasend steigenden Produktionsausfall-Kosten im Nacken!

Hast Du eigentlich auch praktische Erfahrung mit Maschinen im Produktionsprozess oder bist Du "nur" ein Baustein-Entwickler am Schreibtisch? ;)

Übrigens könnte ich wetten, daß gerade Deine Art der Programmierung "aufgeblähten" Code erzeugt, nicht der bewährt einfache verständliche Code von Dieter ...

Harald
 
das sieht der Instandhalter

****************************************************************************************
Error:
0- no Errors
--on Init--
16#01- no Init Pos.
16#02- Cylinder in final Pos(State 2)
16#03- Cyl Sensor failure
--on Start--
16#10- Cylinder no basic Pos.(State1 )
16#11- Cylinder in final Pos
16#12- Cyl Sensor failure
-- on Work --
16#20- Timeout, Cylinder final Pos. not reached
16#21- Cylinder in Pos1;Timeout Cylinder final Pos. not reached
16#22- Cyl Sensor failure
16#30- Cylinder no final Pos(State 2)
16#31- Cylinder in Pos1
16#32- Cyl Sensor failure
16#40- Timeout, Cylinder basic Pos. not reached
16#41- Cylinder in Pos2;Timeout Cylinder basic Pos. not reached
16#42- Cyl Sensor failure
--others--
16#FF- Value incorrect

*****************************************************************************************
Texte werden ueber HMI ausgegeben, sonst Web oder SMS
(einfaches Beispiel aus einen Baustein).
Dafuer existiert ein Baustein, der den Code in String uebersetzt und fuer weitere Zwecke aufbereitet.
D. h. der Leitstand und der Instandhalter bekommen je nach Tiefe der Kommunikation eine aufbereitete Nachricht mit alle den Infos im Klartext.
Nix PG auspacken und anschliessen, alle Fehler muessen im Programm erfasst werden und als Text das System verlassen.
Woanderes nennt man sowas "Kostenoptimierung" bezogen auf uns Programmierer.


Irek
 
Zuletzt bearbeitet:
@ Dieter

Cmd:=FC_8_Bit_to_Byte(
(*1*) B0:=R_start_ref.Q1 and _Freigabe, (*Zusatzbedinung*)
(*2*) B1:=CAC_main_drive.ActualAxisMode=7,
(*4*) B2:=sac_virtual_master.AxisMode=1,Ic
(*8*) B3:=machine_running,
(*1*) B4:=sac_virtual_master.AxisMode=1
(*2*) B5:= tip_buttom,
(*4*) B6:=0,
(*8*) B7:=neues_Signal and not machine_running (*Ausmaskieren = sperren*)
);

Das ist genau der Zweck an der Sache, wobei nach einigen Tagen sind die Hex-Zahlen einfach zu handhaben, Sache der Gewoehnung

Gruss
Irek

Ich bin grad am Überlegen wo ich so eine Programmierung schon mal gesehen hab.
Hast du Anleihen bei Moore-Schaltwerken und / oder VHDL genommen?
Für normale SPS-Programmierung ist dein Stil ungewöhnlich.
Was für Anlagen / Maschinen programmierst du hauptsächlich?

Gruß
Dieter
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Dieter

Atmel, PIC, XILINX
Nehme aus jede Welt das was eine Vereinfachung bringt, das Ergebnis ist entscheidend.
Wenn andere davon profitieren, bin ich mit dem was geschrieben wurde schon zufrieden.

Irek
 
@Dieter

Atmel, PIC, XILINX
Nehme aus jede Welt das was eine Vereinfachung bringt, das Ergebnis ist entscheidend.
Wenn andere davon profitieren, bin ich mit dem was geschrieben wurde schon zufrieden.

Irek

Naja da muss ich dich entäuschen.
Profitieren werde ich daraus nicht, da es mir bei meinen Maschinen keine Vorteile bringt.

Was mir noch einfällt:
Deine Funktion FC_8_Bit_to_Byte ist doch eigentlich in Codesys überflüssig.
In Codesys funktioniert doch auch:

Code:
cmd := 0;
cmd.0 := R_start_ref.Q1 and _Freigabe;
cmd.1 := CAC_main_drive.ActualAxisMode=7;
...

Gruß
Dieter
 
Zurück
Oben