Hier mal ein interessantes Dokument ( vor allem auch wegen dem CEM )
Zykluszeit Vergleichsmessung
Hmmm.
"SLD 3 // alter S5 Trick --> mit 8 multiplizieren" :
Das ist kein Trick und es ist garantiert älter als S5!
Zum GrundWissen eines SPS-Programmierers sollte gehören, dass 2 * X = X + X ist und, dass dadurch jeweils das BitMuster um 1 Position nach links verschoben wird.
Nicht in allen S5-BefehlsSätzen gab es Befehle zum Multiplizieren oder gar Dividieren. Man musste auf SiemensStandardBausteine zurückgreifen oder selbst etwas basteln. Die o.g. (Er-)Kenntnisse waren beim SelbstBasteln einer Multiplikation sehr hilfreich.
Das LinksSchieben birgt aber die Gefahr, dass sich der Zustand des höchstwertigen Bits umkehren kann und somit (nicht nur) das Vorzeichen der Zahl wechselt: Überlauf!
Der UmkehrSchluss, dass zum Dividieren durch eine ZweierPotenz (2^n) "ganz einfach" das BitMuster um n Positionen nach rechts verschoben werden muss, ist allerdings trügerisch.
Wenn der SchiebeBefehl von links mit Nullen auffüllt, dann funktioniert es nur für positive Zahlen.
Wird jedoch beim Schieben nach rechts nicht grundsätzlich mit 0 aufgefüllt, sondern das höchstwerige Bit unverändert erhalten bleibt, dann funktioniert es auch für negative Zahlen bei der "ZweierKomplementDarstellung" dualer Zahlen.
Der eigentliche "(S5-)Trick" ist jedoch folgender:
Ich unterstelle, dass mit 'L AE_Slider1' ein INT-Wert (16Bit!) geladen wird.
Aus dem symbolischen Namen ist dies leider (für mich) nicht ersichtlich - L AWxxx oder L EWxxx oder L MWxxx oder L DWxxx wäre eindeutig.
Erst ab Programm3 ist es ohne nachzudenken klar.
Wenn man (z.B. in S5) einen INT-Wert in den 32BitAkku lädt und mit DoppelWortBefehlen weiterarbeitet (sofern verfügbar),
muss man dafür sorgen, dass
- entweder negative Werte negativ bleiben, statt zu grossen positiven Werten verfälscht zu werden
- oder negative Werte zu 0 machen, wenn negative Werte für den VerwendungsZweck so korrekt behandelt werden können.
Letzteres tut "Programm1: AWL mit TrickProgrammierung".
Kurzum: das Programm ist durch die wenigen Befehle sehr kurz und übersichtlich.
Ich kann in NullKommaNix erfassen, was es tut und, dass es korrekt arbeitet! ProgrammierTricks kann ich darin beim besten Willen nicht entdecken. Und es wird erst recht nicht "tief in die Trickkiste gegriffen".
"Nachvollziehbar ist dieser Code nur für die wenigsten." Weil die wenigsten jemals in AWL oder Assembler promrammiert haben?
Zu "Programm2: AWL ohne TrickProgrammierung":
Netzwerk 2: Es gibt viel zu lesen. Dennoch recht leicht zu erfassen und abzuhaken. Einverstanden, ist OK!
Netzwerk 1: Kurz und knapp. Aber OK?
NEIN! Trotz Grübelns kann ich keinen "Trick" entlarven, der für ein korrektes Verhalten beim Laden eines negativen Wertes sorgt.
Fazit: Die Behauptung "ohne TrickProgrammierung" ist also gerechtfertigt.
Programm2 ist umfangreicher als Programm1 und allein dadurch ein wenig schwerer (nicht leichter!) zu erfassen.
Es ist "einfacher" gestaltet, insofern auf eine (sinnvolle) Behandlung negativer Werte verzichtet wird.
ABER: Im Gegensatz zu Programm1 arbeitet es bei negativen Werten nicht korrekt!
Fehlende Funktionalität durch mehr Befehle bei geringfügig weniger Übersichtlichkeit! Worin soll der Vorteil liegen?
Zu "Programm3: KOP/FUP":
Netzwerk 2: Es gibt viel zu lesen. Dennoch recht leicht zu erfassen und abzuhaken. Einverstanden, ist "identisch" mit Programm2 und ist OK!
Netzwerk 1: Kurz und knapp. Aber OK? Ich weiss es nicht.
Schnell zu erfassen ist, dass negative EingangsWerte kein Problem sind (wegen INT -> REAL).
Ohne eine Beschreibung und ohne Einblick in den Baustein 'NORM_X Int to Real' und ohne die Möglichkeit, ihn testen zu können, kann ich nur hoffen, dass die Parametrierung seines Eingangs MIN mit 0 genau das tut, was auch in Programm1 geschieht und was in Programm2 geschlampert wurde.
Edit: letzten Satz gestrichen, da er wegen des vorausgehenden Satzes gegenstandslos und verwirrend ist.
Zu "Programm4: SCL":
Abschnitt 2 ("Netzwerk 2") "// Ausgänge ansteuern" :
Schnell zu erfassen und abzuhaken. Einverstanden, ist "identisch" mit Programm2 und Programm3 und OK!
Abschnitt 1 ("Netzwerk 1") "// Analogwert einlesen und normieren (0..10V -> 0..27648 -> 0..8)":
Kurz und knapp. Aber OK? Ich weiss es nicht.
Genügt die Multiplikation mit DINT#8, um den Compiler dazu zu bewegen, "AE_Slider1" implizit von INT in DINT zu konvertieren?
Wenn ja, alles gut und ich hätte trotzdem lieber ' DINT#8 * "AE_Slider1" ' an Stelle von ' "AE_Slider1" * DINT#8 ' geschrieben
und noch lieber '#l_iTemp := DINT_TO_INT(INT_TO_DINT("AE_Slider1") * 8 / 27648);'.
Zu "Programm5: CEM":
Anderer Lösungsweg als bei Programm1 bis Programm4. Dieser Lösungsweg hätte auch bei den Programmen 2..4 beschritten werden können und die FussAngel der negativen EingangsWerte wäre damit vermieden worden:
Statt zu normieren, werden einfach die 8 Vergleichswerte ausserhalb des Programms entsprechend berechnet und als Konstanten in das Programm eingetragen (= "ProgrammierTrick"?).
Warum aber das CEM-Programm sooo viel langsamer ist als alle anderen Varianten, kann ich mir Mangels Kenntnissen über CEM nicht erklären.
Selbst eine S5-Variante von Programm2 dürfte mindestens doppelt so schnell sein - trotz Interpreter statt Compiler.