TIA in AWL Array elemente Addieren

Wer Lust hat kann ja mal mit einer realen S7-1500-CPU die Performance messen, ob da wirklich ein Faktor 10 schneller bei rauskommt.
Mit 50 Real Werten:
AWL optimiert ~8µs
SCL optimiert ~10µs
AWL nicht optimiert ~17µs

Code SCL:
Code:
#tmp_res := 0;
FOR #i := 0 TO 49 DO
    #tmp_res += #Input[#i];
END_FOR;
#AddReal_SCL := #tmp_res;

Code AWL optimiert:
Code:
      L     0.0
      T     #tmp_res
      L     0
      T     #i
loop: L     #i
      L     49
      <=I
      JCN   end
      L     #tmp_res
      L     #Input[#i]
      +R
      T     #tmp_res
      L     #i
      L     1
      +I
      T     #i
      JU    loop
end:  L     #tmp_res
      T     #AddReal_AWL

Code AWL nicht optimiert von PN/DP übernommen und auf die Testumgebung angepasst:
Code:
//AWL
// #tmpSumme := 0.0; initialisieren
      L     0.0
      T     #tmpSumme

// ptr := Address("MyDB".RealArray); Pointer AR1 auf "MyDB".RealArray setzen
      OPN   "TimeTest_NotOptimized"
      L     P#DBX0.0             //(P#0.0 geht auch) Offset des RealArray in "MyDB" per Hand einsetzen
      LAR1                       //DBNO + AR1 zeigen jetzt auf das erste Element des RealArrays in MyDB

// For #tmpLoopCount := 50 TO 1 BY -1 DO
      L     50                   //50 Elemente addieren
LSUM: T     #tmpLoopCount

      L DBD [ AR1 , P#0.0 ]      //#tmpSumme += *ptr;
      L     #tmpSumme
      +R
      T     #tmpSumme

      +AR1  P#4.0                //ptr auf nächstes Element im RealArray setzen

      L     #tmpLoopCount
      LOOP  LSUM                 //END_FOR;  (#tmpLoopCount - 1) = 0 ?

      L     #tmpSumme
      T     "TimeTest_NotOptimized".ErgAWL

1680158030468.png

Edit:
hatte einen falschen Aufruf und hab die Zykluszeit durch weniger Bausteine beobachten noch reduziert.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hat mich jetzt auch grad interessiert.
1680160895098.png
Ich hab den Baustein von Harald Genommen (SummenLoopAWL) nicht optimierter DB.
dann eine FOR Schleife auf einen Optimierten Baustein
Und in AWL ausprogrammiert auf nicht optimierten DB.
Code:
      L     #summe
      L     "MyDB".Wert[4001]
      +R
      T     #summe
      L     #summe
      L     "MyDB".Wert[4002]
      +R
      T     #summe
      L     #summe
      L     "MyDB".Wert[4003]
      +R
      T     #summe

Immer 5000 Realwerte aufsummiert in einer 1510sp DJ01

Ich bin etwas erstaunt wie viel schneller dass es ohne loop läuft. Mal abgesehen dass es dafür natürlich unglaublich viel speicher braucht.
Aber wenn man an der Zykluszeit kratzt scheint das tatsächlich der Weg zu sein.

PS: Was ich weiterhin erstaunlich finde. Wenn man den AWL Code Optimiert. Also das
Code:
      L     0.0
      L     "MyDB".Wert[1]
      +R
. 
. 
    L     "MyDB".Wert[4002]
      +R
      L     "MyDB".Wert[4003]
      +R
.
. 
     T    "MyDB".summe
ändert sich an dessen Zykluszeit praktisch gar nichts.
 
Zuletzt bearbeitet:
PS: Was ich weiterhin erstaunlich finde. Wenn man den AWL Code Optimiert. Also das
Code:
      L     0.0
      L     "MyDB".Wert[1]
      +R
.
.
    L     "MyDB".Wert[4002]
      +R
      L     "MyDB".Wert[4003]
      +R
.
.
     T    "MyDB".summe
ändert sich an dessen Zykluszeit praktisch gar nichts.
Ziemlich sicher die automatische Optimierung des Compilers beim Übersetzen in Maschinencode.

Aber dafür sparst du dir wahrscheinlich ein wenig Speicherplatz.
 
Die Problemstellung wie ich es lese:
Die Übertragung von 50 Analogwerte über eine serielle BK8000 ist nicht 100% zuverlässig.
Einzigste Zeichen dass die Datenübertragung schief gegangen ist, ist dass die Werte gehen auf 0.
Deswegen willst du eine Fehler bei die Datenübertragung erkennen um falsche Störmeldungen über Signalfehler zu vermeiden.
Du hast ein Programm erstellt der die Werte für 0 scannt, aber du hast gefunden es funktioniert nicht zuverlässig.
Und du hast gefunden dass es wird zuverlässiger desto schneller die Code läuft.
Ist dies korrekt ?

Wenn es korrekt ist, dann vermute ich du hast ein Timing Problem zwischen die Datentransfer Baustein und die Test-Baustein.
Laufen einer von die in eine zyklische Task und die andere nicht ? (*)
Wenn die Code schneller wird, verschwindet das Problem nicht. Es wird nur mehr selten.

AWL optimiert ~8µs
SCL optimiert ~10µs
AWL nicht optimiert ~17µs
8µs oder 10µs oder 17µs, es ist sowiso am weiten schneller als eine serielle Datenübertragung.

Viele Fragen mehr, aber die Fokus auf die Zykluszeit ist die falsche Richtung.

Warum nimmst du nicht ein Profinet Buskoppler wie BK9053 anstatt die serielle BK8000 ?
Dann hast du bessere Diagnostik, und ich vermute die Problematik dass die Analogwerte manchmal auf 0 gehen einfach verschwindet.

* edit: Vermutlich eher die Datentransfer läuft uber mehrere Zyklen.
Die Datentransfer Baustein MUSS ein Statusbit haben dass die Datentransfer fertig ist.
Welche Baustein(e) ist es ?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich sehe das genauso wie Jesper. Die Lösung des Problems ist auch aus meiner Sicht erstmal die Kommunikation vernünftig hinzubekommen. Jetzt ist natürlich ganz generell diese Form der Kommunikation auch nicht mehr so ganz "State of the Art".
Wie Jesper schon geschrieben hat, ist die Kommunikation ganz sicher azyklisch - man sollte also auf jeden Fall erstmal checken ob wirklich komplett übertragen worden ist und ob die Anzahl der empfangenen Zeichen mit der erwarteten Anzahl übereinstimmt. Wahrscheinlich erübrigt sich dann die Array-Geschichte schon.
Ganz unabhängig davon würde ich aber eine Array-Auswertung GRUNDSÄTZLICH in SCL (schon allein wegen der besseren Les- und Wartbarkeit des Codes) umsetzen.
 
Ich sehe das genauso wie Jesper. Die Lösung des Problems ist auch aus meiner Sicht erstmal die Kommunikation vernünftig hinzubekommen. Jetzt ist natürlich ganz generell diese Form der Kommunikation auch nicht mehr so ganz "State of the Art".
Wie Jesper schon geschrieben hat, ist die Kommunikation ganz sicher azyklisch - man sollte also auf jeden Fall erstmal checken ob wirklich komplett übertragen worden ist und ob die Anzahl der empfangenen Zeichen mit der erwarteten Anzahl übereinstimmt. Wahrscheinlich erübrigt sich dann die Array-Geschichte schon.
Ganz unabhängig davon würde ich aber eine Array-Auswertung GRUNDSÄTZLICH in SCL (schon allein wegen der besseren Les- und Wartbarkeit des Codes) umsetzen.
Das Problem ist der Aufwand bei Umbau der Anlage auf PROFIBUS oder auf PROFINET. Bei einer neuen Anlagen wäre ich auf PROFIBUS oder PROFINET gewechselt.
 
In der S7-1500 kannst Du die Arrayelemente auch variabel in AWL ansprechen. Da brauchst Du keinen Pointer. Nur nen AWL LOOP... (und dann auch mit "optimiertem" DB)
Ach, das wußte ich noch gar nicht. Welche Kunden/Programmierer verlangen denn, daß AWL nur für die S7-1500 noch weiterentwickelt wird/wurde?? Können/wollen die kein SCL oder ist SCL nicht effizient genug?

Aber schneller als in SCL ist das bestimmt nicht.
Warum nicht? In AWL habe ich die volle Freiheit, wie optimal ich programmiere. Da bin ich nicht davon abhängig, wie starr/stupide der Siemens-SCL-Compiler den SCL-Code in Maschinencode übersetzt, der setzt wohl im wesentlichen nur Macros zusammen. Bisher habe ich immer in AWL effizienteren Code erzeugt als in SCL möglich (es sei denn, AWL-Programme werden absichtlich in langsameren Code übersetzt) - das dauert allerdings auch wesentlich länger, als einfach ein paar Zeilen SCL hinzutippen ohne mir Gedanken über Effizienz zu machen.

Wobei für REAL nen Vergleich auf Gleichheit immer problematisch ist. Würd vielleicht eher x>0.01 OR x<0.01 abfragen...
Ein Vergleich eines REAL-Wertes auf "gleich 0.0" ist kein Problem. Der Wert 0.0 ist im REAL-Format exakt darstellbar. Problematisch ist höchstens, ob ein Analogeingangswert oder das Ergebnis einer Berechnung exakt 0.0 ergibt. Hier im Thema kommt die 0.0 allerdings durch Kommunikationsausfall als Ersatzwert zustande (alle Bits = 0 ist DW#16#00000000 = REAL#0.0). Da ist der Vergleich auf "gleich 0.0" praktikabel.


es handelt sich um Temperaturen, ich möchte eine Fehlerbehandlung damit erreichen. Die ersten 50 Temperaturen in einem Array speichern und addieren wenn Sie nicht alle gleich null sind dann kann ich sie in einem anderen DB kopieren sonst schreiben einen 7FFF um einen Fehler zu melden
Du willst eigentlich prüfen, ob alle Temperaturwerte = 0 sind, aber nicht jeden einzelnen Wert auf 0 vergleichen. Du meinst, die Idee mit dem Addieren aller Werte und schauen ob in der Summe 0 rauskommt wäre effizienter? Diese Addier-Lösung ist aber nicht korrekt! Wenn die 50 Werte um 0.0 schwanken (z.B. mal -0.5, mal 0.0, mal +0.5) dann kann sich im Durchschnitt bzw. in der Summe 0.0 ergeben!

Wenn Du die Prüfung der 50 Werte auf 0 beibehalten willst, dann müsstest Du wirklich jeden einzelnen Wert auf 0 prüfen. Das kann man allerdings tatsächlich effizienter lösen als jeden einzelnen Wert mit 0 zu vergleichen: die Bitmuster der 50 REAL (der DWORD wo die REAL liegen) ver-odern und am Ende das Ergebnis auf 0 vergleichen. Wenn irgendein Wert <> 0 ist, dann ergibt sich auch das Ergebnis <> 0. In AWL kann man das ver-odern auch sehr effizient vorzeitig abbrechen, sobald der erste Wert <> 0 ver-odert wurde: mit dem Sprung SPN. (In SCL geht das so nicht).

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@batindeko : ich meinte jetzt nicht einen möglichen Umbau auf PB oder PN - ich (und auch Jesper) meinte hier die Kommunikation selbst - also das Hantieren mit xen Empfangs-Bausteinen ... da läuft aus miener Sicht ab und an etwas nicht sauber ...
 
Die Problemstellung wie ich es lese:
Die Übertragung von 50 Analogwerte über eine serielle BK8000 ist nicht 100% zuverlässig.
Einzigste Zeichen dass die Datenübertragung schief gegangen ist, ist dass die Werte gehen auf 0.
Deswegen willst du eine Fehler bei die Datenübertragung erkennen um falsche Störmeldungen über Signalfehler zu vermeiden.
Du hast ein Programm erstellt der die Werte für 0 scannt, aber du hast gefunden es funktioniert nicht zuverlässig.
Und du hast gefunden dass es wird zuverlässiger desto schneller die Code läuft.
Ist dies korrekt ?

Wenn es korrekt ist, dann vermute ich du hast ein Timing Problem zwischen die Datentransfer Baustein und die Test-Baustein.
Laufen einer von die in eine zyklische Task und die andere nicht ? (*)
Wenn die Code schneller wird, verschwindet das Problem nicht. Es wird nur mehr selten.


8µs oder 10µs oder 17µs, es ist sowiso am weiten schneller als eine serielle Datenübertragung.

Viele Fragen mehr, aber die Fokus auf die Zykluszeit ist die falsche Richtung.

Warum nimmst du nicht ein Profinet Buskoppler wie BK9053 anstatt die serielle BK8000 ?
Dann hast du bessere Diagnostik, und ich vermute die Problematik dass die Analogwerte manchmal auf 0 gehen einfach verschwindet.

* edit: Vermutlich eher die Datentransfer läuft uber mehrere Zyklen.
Die Datentransfer Baustein MUSS ein Statusbit haben dass die Datentransfer fertig ist.
Welche Baustein(e) ist es ?
richtig ich habe ein Programm erstellt was die 50 Analogwerte addiert und auf Null prüft aber getestet habe ich es noch nicht. Das mache ich morgen an der Anlage. Wo hast du bitte gelesen dass die Übertragung von 50 Analogwerte bei BK8000 nicht 100% zuverlässig ist. Das war ein Grund warum die sich damals vor 25 Jahren auf die seriellle BK8000 entschieden hatte, weil man mehr Thermoelemente anschließen konnte.
ich benutze die folgenden Bausteine für die Kommunination receive p2p und send p2p, receice reset. Leider bei der Response der Datenübertragung gibt es keine Statusbit eingebaut was sagt das der Datentransfer fertig ist
 
Wo hast du bitte gelesen dass die Übertragung von 50 Analogwerte bei BK8000 nicht 100% zuverlässig ist.
Hier:
Die Taktung ist bei mir sehr schnell für einige Regelungsprozesse und hat schon in der vergangenheit für ein paar Sekunden zu falschen Messwerte geführt haben wegen Auslatung der CPU deswegen würde ich vorerst nicht einsetzen.
Und hier:
Und es ist schon mal passiert die Datenübertragung schiefgelaufen ist und bei den ersten 50 Temperaturen 0 schreibt.
Wobei ich völlig uneinig bin, dass die Auslastung von die 1516 CPU der Grund sein kann.

Das war ein Grund warum die sich damals vor 25 Jahren auf die seriellle BK8000 entschieden hatte, weil man mehr Thermoelemente anschließen konnte.
Wie vorgeschlagen, du kannst die BK8000 für ein Profinet Buskoppler austauschen, dann hast du die Daten direkt in die CP1516 CPU, viel höhere Performance, bessere Diagnostik, vermutlich viel zuverlässiger, viel einfacher, usw. usw.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ach, das wußte ich noch gar nicht. Welche Kunden/Programmierer verlangen denn, daß AWL nur für die S7-1500 noch weiterentwickelt wird/wurde?? Können/wollen die kein SCL oder ist SCL nicht effizient genug?


Warum nicht? In AWL habe ich die volle Freiheit, wie optimal ich programmiere. Da bin ich nicht davon abhängig, wie starr/stupide der Siemens-SCL-Compiler den SCL-Code in Maschinencode übersetzt, der setzt wohl im wesentlichen nur Macros zusammen. Bisher habe ich immer in AWL effizienteren Code erzeugt als in SCL möglich (es sei denn, AWL-Programme werden absichtlich in langsameren Code übersetzt) - das dauert allerdings auch wesentlich länger, als einfach ein paar Zeilen SCL hinzutippen ohne mir Gedanken über Effizienz zu machen.


Ein Vergleich eines REAL-Wertes auf "gleich 0.0" ist kein Problem. Der Wert 0.0 ist im REAL-Format exakt darstellbar. Problematisch ist höchstens, ob ein Analogeingangswert oder das Ergebnis einer Berechnung exakt 0.0 ergibt.
Hier im Thema kommt die 0.0 allerdings durch Kommunikationsausfall als Ersatzwert zustande (alle Bits = 0 ist DW#16#00000000 = REAL#0.0). Da ist der Vergleich auf "gleich 0.0" praktikabel.



Du willst eigentlich prüfen, ob alle Temperaturwerte = 0 sind, aber nicht jeden einzelnen Wert auf 0 vergleichen. Du meinst, die Idee mit dem Addieren aller Werte und schauen ob in der Summe 0 rauskommt wäre effizienter? Diese Addier-Lösung ist aber nicht korrekt! Wenn die 50 Werte um 0.0 schwanken (z.B. mal -0.5, mal 0.0, mal +0.5) dann kann sich im Durchschnitt bzw. in der Summe 0.0 ergeben!

Wenn Du die Prüfung der 50 Werte auf 0 beibehalten willst, dann müsstest Du wirklich jeden einzelnen Wert auf 0 prüfen. Das kann man allerdings tatsächlich effizienter lösen als jeden einzelnen Wert mit 0 zu vergleichen: die Bitmuster der 50 REAL (der DWORD wo die REAL liegen) ver-odern und am Ende das Ergebnis auf 0 vergleichen. Wenn irgendein Wert <> 0 ist, dann ergibt sich auch das Ergebnis <> 0. In AWL kann man das ver-odern auch sehr effizient vorzeitig abbrechen, sobald der erste Wert <> 0 ver-odert wurde: mit dem Sprung SPN. (In SCL geht das so nicht).

Harald
es ist so es gibt schon einige Thermoelemente welche draußen stehen und können im Winter z.B bis 0 Grad runtergehen.
mit ver-odern meist du diesen Befehl OW
 
ich benutze die folgenden Bausteine für die Kommunination receive p2p und send p2p, receice reset. Leider bei der Response der Datenübertragung gibt es keine Statusbit eingebaut was sagt das der Datentransfer fertig ist
Laut die Hilfe für Receive_P2P:
COM_RST IN/OUT BOOL
Initialization of the instruction
The instruction is initialized with TRUE. The instruction then resets COM_RST to FALSE.
Also, du setzt das Bit um eine Lesevorgang zu starten.
Die Baustein setzt den Bit zurück wenn fertig.
Du kannst auch die STATUS vergleichen ungleich 16#0000

edit: COM_RST gibt es nicht für S71500.
 
Zuletzt bearbeitet:
Wie vorgeschlagen, du kannst die BK8000 für ein Profinet Buskoppler austauschen, dann hast du die Daten direkt in die CP1516 CPU, viel höhere Performance, bessere Diagnostik, vermutlich viel zuverlässiger, viel einfacher, usw. usw.
würde ich auch aber es würde zum einem Aufwand führen,dass meine Kollegen nicht jetzt wollen z.B neue Verteiler bestellen usw..
 
Zuviel Werbung?
-> Hier kostenlos registrieren
würde ich auch aber es würde zum einem Aufwand führen,dass meine Kollegen nicht jetzt wollen z.B neue Verteiler bestellen usw..
Noch eine Alternative wäre auf Profibus zu wechseln.
Die 1516-3PN/DP hat schon das Profibus Schnittstelle.
Wenn die Busgeschwindigkeit niedrig gehalten wird (187.5 k) dann kann die Abstand bis 1000 m gehen.
Eventuell kann das Buskabel sogar wiederverwendet werden.
 
Laut die Hilfe für Receive_P2P:

Also, du setzt das Bit um eine Lesevorgang zu starten.
Die Baustein setzt den Bit zurück wenn fertig.
Du kannst auch die STATUS vergleichen ungleich 16#0000

edit: Und selbstvertsändlich gibt es auch das DONE bit !
Diese COM_RST habe ich bei mir nicht. In welche version ist es vorhanden?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn Du die Prüfung der 50 Werte auf 0 beibehalten willst, dann müsstest Du wirklich jeden einzelnen Wert auf 0 prüfen. Das kann man allerdings tatsächlich effizienter lösen als jeden einzelnen Wert mit 0 zu vergleichen: die Bitmuster der 50 REAL (der DWORD wo die REAL liegen) ver-odern und am Ende das Ergebnis auf 0 vergleichen. Wenn irgendein Wert <> 0 ist, dann ergibt sich auch das Ergebnis <> 0.
(y)
In AWL kann man das ver-odern auch sehr effizient vorzeitig abbrechen, sobald der erste Wert <> 0 ver-odert wurde: mit dem Sprung SPN. (In SCL geht das so nicht).
Wenn man ohnehin das VerOdern vorzeitig abbrechen möchte, dann kann man sich das VerOdern doch eigentlich ganz ersparen.
Aber das Verodern dient dann nur noch dazu, die StatusBits so zu beeinflussen, dass man sie mit dem SprungBefehl auswerten kann, ohne explizit mit 0 vergleichen zu müssen?
 
mit ver-odern meist du diesen Befehl OW
Fast richtig. Ich meine OD

ungetestet, ich weiß nicht ob das in S7-1500-AWL so geht:
Code:
//AWL mit Array-Adressierung (nur mit optimiertem DB?)
      L     0
      T     #tmpDWord

// For #i := 50 TO 1 BY -1 DO
      L     50
LOR:  +     -1         //weil Array[0..49]
      T     #i

      L     "MyDB".RealArray[#i]
      L     #tmpDWord
      OD
      SPN   MEND       //Wert <> 0 gefunden!
      T     #tmpDWord

      L     #i
      +     1          //weil Array[0..49]
      LOOP  LOR

      L     #tmpDWord
MEND: T     "MyDB".dwResult

Harald
 
Zurück
Oben