Step 5 Fragen zu AWL Code einer bestehenden Anlage (SLW, LAR1...)

Mogli

Level-2
Beiträge
123
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Morgen zusammen,

wir haben hier eine Bestandsanlage, bei der ich gerade versuche (offline) zu verstehen wie ein Hubwerk im Programm funktioniert.
Es gibt einen FC, der Vergleicht, ob der Hubwagen (IST-Position) im Positionsfenster (Soll-Pos) ist.
Da gibt es ein NW in diesem FC, welches in AWL geschrieben wird. Ich verstehe leider nicht, was dieses NW macht. Zur Zeit kann ich nicht online an die Anlage.
Vielleicht hat jemand von euch eine Idee.

Der Code sieht wie folgt aus:
Was würde im "#Setpoint" stehen, wenn das "#Sollfach" = 0 wäre? Bzw. was macht dieser Code mit dem Sollfach?
Im DB14 sind die Sollwerte von Fach 0 bis 18 hinterlegt (jeweils als INT und jedes hat auch einen "festgeschriebenen" Anfangswert.

1666331757801.png
Schon Mal vielen Dank für eure Hilfe/ Infos.

SPS: CPU315-2 DP
SW: S7 V5.6 SP1

Grüße aus Luxembourg!
 
Wenn #Sollfach = 0 ist, dann ergibt sich AR1 = 0 und der Wert von DB14.DBW0 wird in #Setpos kopiert.

PS: Der AWL-Code entspricht diesem SCL-Code: #Setpos := DB14.Sollwerte_IntArray[#Sollfach]; wobei im AWL-Code das Sollwerte_IntArray bei DBX0.0 beginnen muß.

Harald
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
schau dir das auch mal an
 
Der Code stammt wohl von einer S5 Migration.
SLW4 bringt den Wert von der alten Wortadressierung in S5 zur Byteadressierung in S7 (Verdoppelung des Wertes) und gleichzeitig in das nötige Pointerformat zur indirekten Adressierung über das Adressregister 1.
 
Im DB14 "Fachdaten Hubwerk" existiert eine Liste mit Werten im 16 Bit Format ( WORD oder INT).
Diese wird über den Pointer adressiert (berechnet aus #Sollfach) und in die Variable #Setpos geladen.
SLW4 bewirkt eine Adressierung im Wortformat bei STEP7
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Code stammt wohl von einer S5 Migration.
Das sieht mir eher nicht so aus. Das ist eine S7-typische Umrechnung von Array-Index zu Speicheradresse des Array-Elementes und indirekte Adressierung mit AR1.

SLW4 bringt den Wert von der alten Wortadressierung in S5 zur Byteadressierung in S7 (Verdoppelung des Wertes) und gleichzeitig in das nötige Pointerformat zur indirekten Adressierung über das Adressregister 1.
Das ist so nicht korrekt formuliert. In der S7 wird der Speicher nicht Wordweise und nicht Byteweise adressiert, sondern Bitweise. Um die Anfangsadresse (bzw. einen Pointer) eines Bytes zu berechnen, muß die Byte-Nummer der Adresse mit 8 multipliziert werden, weil ein Byte 8 Bit groß ist. Auch bei Word-Adressen muß die Byte-Nummer der Adresse mit 8 multipliziert werden. Die Multiplikation mit 8 macht man effizient mit "SLD 3". Weil das Array (bzw. die Liste) von Mogli INT-Werte enthält, liegen die Listen-Elemente 2 Byte = 16 Bit auseinander und der (Bit-)Offset der Listen-Elemente relativ zum Anfang der Liste ergibt sich aus "Index * 8 * 2" bzw. zusammengefasst "Index * 16". Die Multiplikation mit 16 macht man effizient mit "SLD 4" ( * 8 * 2 entspricht: "SLD 3" + "SLD 1" ).
Im Code von Mogli wird "SLW 4" anstatt "SLD 4" verwendet, da hat sich der Programmierer vermutlich keine besonderen Gedanken gemacht, daß eigentlich "SLD 4" verwendet werden müsste. Dadurch funktioniert der Code nur mit einem Index bis höchstens 4095 (reicht hier aber, der Index ist nur 0..18 ).

SLW4 bewirkt eine Adressierung im Wortformat bei STEP7
"SLW 4" ist lediglich eine Multiplikation. Daß auf die Speicheradresse im Wortformat zugegriffen wird, bestimmt die Zugriffs-Operation, hier "L DBW [...]"

Harald
 
Zuletzt bearbeitet:
In diesem Fall meinte ich natürlich nicht den Speicher allgemein, sondern die Adressierung der Datenbausteine.
Bei der indirekten Adressierung eines Datenbytes in S7 brauchst du den Wert im Pointerformat, also SLW3.
Da die Adresse im DB von S5 auf S7 doppelt so groß ist, macht die Migration daraus ein SLW4.
Ansonsten magst du richtig liegen, spielt hier aber keine Rolle.
 
Das sieht mir eher nicht so aus. Das ist eine S7-typische Umrechnung von Array-Index zu Speicheradresse des Array-Elementes und indirekte Adressierung mit AR1.


Das ist so nicht korrekt formuliert. In der S7 wird der Speicher nicht Wordweise und nicht Byteweise adressiert, sondern Bitweise. Um die Anfangsadresse (bzw. einen Pointer) eines Bytes zu berechnen, muß die Byte-Nummer der Adresse mit 8 multipliziert werden, weil ein Byte 8 Bit groß ist. Auch bei Word-Adressen muß die Byte-Nummer der Adresse mit 8 multipliziert werden. Die Multiplikation mit 8 macht man effizient mit "SLD 3". Weil das Array (bzw. die Liste) von Mogli INT-Werte enthält, liegen die Listen-Elemente 2 Byte = 16 Bit auseinander und der (Bit-)Offset der Listen-Elemente relativ zum Anfang der Liste ergibt sich aus "Index * 8 * 2" bzw. zusammengefasst "Index * 16". Die Multiplikation mit 16 macht man effizient mit "SLD 4" ( * 8 * 2 entspricht: "SLD 3" + "SLD 1" ).
Im Code von Mogli wird "SLW 4" anstatt "SLD 4" verwendet, da hat sich der Programmierer vermutlich keine besonderen Gedanken gemacht, daß eigentlich "SLD 4" verwendet werden müsste. Dadurch funktioniert der Code nur mit einem Index bis höchstens 4095 (reicht hier aber, der Index ist nur 0..18 ).


"SLW 4" ist lediglich eine Multiplikation. Daß auf die Speicheradresse im Wortformat zugegriffen wird, bestimmt die Zugriffs-Operation, hier "L DBW [...]"

Harald
Hallo @PN/DP

So sieht der DB14 aus:

1666342424628.png

Heist das dann, wenn nun das "#Sollfach" z.B auf 3 stehen würde, würde dann der Wert aus DB10.DBW4 (Fach2) genommen werden und auf "#Setpoint" geladen werden? Sprich #Setpoint = 2168?
 
Da die Adresse im DB von S5 auf S7 doppelt so groß ist, macht die Migration daraus ein SLW4.
Ansonsten magst du richtig liegen, spielt hier aber keine Rolle.
Wie in der S5 ein DB adressiert wird spielt hier gar keine Rolle. Bei einer S7 ist die Berechnung der Speicheradresse immer gleich, egal ob DB- oder Merker- oder E/A-Adresse berechnet wird.
Und das "SLW 4" kommt daher, weil in der Liste die Listen-Elemente 16 Bit weit auseinanderliegen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
#Setpoint wäre dann aus "Fach_3" = 4250
Warum? Bzw. wie kommt das dann zu Stande?
Wird das genommen, weil es der 3. Eintrag im DB ist?
Nein. Das wird genommen, weil (#Sollfach = 3) * 16 die Adresse P#6.0 ergibt (P#6.0 = 48 dezimal, 48 = 3 * 16), und im DB am Offset 6.0 liegt die Variable "Fach_3".
"Fach_3" ist übrigens nicht der 3. Eintrag im DB, sondern der 4. Es kommt aber gar nicht darauf an wie die Variable heißt und welche und wie viele Variablen davor im DB liegen, es wird eine Adresse berechnet.

#Sollfach = 0 liefert den Wert von DB14.DBW0 "Fach_Uebergabe"
#Sollfach = 1 liefert den Wert von DB14.DBW2 "Fach_1"
#Sollfach = 2 liefert den Wert von DB14.DBW4 "Fach_2"
#Sollfach = 3 liefert den Wert von DB14.DBW6 "Fach_3"
...
#Sollfach = 18 liefert den Wert von DB14.DBW36 "Fach_18"


Da gibt es ein NW in diesem FC, welches in AWL geschrieben wird. Ich verstehe leider nicht, was dieses NW macht. Zur Zeit kann ich nicht online an die Anlage.
Du könntest den Programmcode mit PLCSIM simulieren (da brauchst und störst Du die Anlage nicht) und beobachten was der Code macht. Da sorge dafür daß der Code immer aufgerufen wird und beobachtet werden kann, und dann steuere #Sollfach auf Werte von 0..18
Tipp: beim beobachten des AWL-Codes die Spalte "Adressregister 1" einblenden, da siehst Du im AR1 die Adresse (bzw. Offset) von wo gelesen wird.

Harald
 

Anhänge

  • Sollpos_AWL_beobachten.png
    Sollpos_AWL_beobachten.png
    17,3 KB · Aufrufe: 9
Ich kenne die gezeigte Programmierung auch, und verstehe was sie macht. Ich käme nie auf die Idee statt explizit eine Multiplikation zu verwenden, SLW xy hinzuschreiben. Warum macht man das? Musste man sich früher wirklich so um Effizienz scheren?
 
hast du dir mal den link angeschaut den ich gepostet habe?
da wird gut erklärt wie das funktioniert.

z.b.
sollfach = 3
normalerweise wird der pointer mit sld3 erzeugt
also
l sollfach
sld3
lar1 // im adressregister steht nun ein pointer auf die adresse p#3.0

da in deinem db aber die variablen nicht byteweise adressiert sind sondern wortweise muss man die startadresse mit 2 multiplizieren
das könnte man 1. so machen
l sollfach
l 2 //wegen typ int (also 2 byte)
*I
t startadresse //wäre also 6
sld3
lar1 //erzeugt pointer p#6.0

oder 2. (kürzer)
sld4 //mit jedem +sld1 multiplizierst du mit 2

@TP-Inc
sehe ich genauso. für jemanden der nicht genau bescheid weiss ist das ehr verwirrend.
ichberechne startadressen auch durch multiplikationen und gegebenenfalls noch mit addition(subtraktion (falls nötig)
dann bleibt klar wo die startadresse (dint/int) ist. und danach bilde ich erst den pointer
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich käme nie auf die Idee statt explizit eine Multiplikation zu verwenden, SLW xy hinzuschreiben. Warum macht man das? Musste man sich früher wirklich so um Effizienz scheren?
Warum absichtlich uneffizient programmieren? --> "damit der Code verständlicher aussieht"
Meine Meinung: wer mit Adressberechnungen und Pointern in AWL rummacht, der sollte als Basics auch sicher verstehen, was SLW/SLD tun.

Vergleich der Effizienz von SLW/SLD gegenüber einer Multiplikation am Beispiel einer CPU 312 IFM von 1998 und aktueller CPUs 314C und 315-2
Code:
aktuelle CPU 315-2 PN/DP (315-2EH14)
aktuelle CPU 314C-2 PN/DP (314-6EH04)
CPU 312 IFM (1998)
                            312 IFM     314C       315-2
                 Codelänge, Ausführungszeit
effizient * 16:
SLW 4               1 Word, 1.8 µs     0.27 µs     0.21 µs
------------------------------------------------------------
SLD 4               1 Word, 4.9 µs     0.24 µs     0.19 µs
------------------------------------------------------------
alternativ Multiplikation:
L 16                2 Word, 1.7 µs     0.12 µs     0.09 µs
*I                  1 Word, 2.6 µs     0.15 µs     0.12 µs
------------------------------------------------------------
gesamt              3 Word, 4.3 µs     0.27 µs     0.21 µs
Fazit: der Multiplikations-Code belegt dreimal so viel Programmspeicher wie "SLW xx", und dauerte früher mehr als doppelt so lange. In aktuellen 31x-CPU dauern die Multiplikation und SLW gleich lange, nur SLD ist noch ein bisschen schneller.

Harald
 
Zuletzt bearbeitet:
was das betrifft hast du natürlich recht.
aber die performance der steuerungen hat sich enorm gesteigert. da muss man (fast nie) auf ein par ys schauen.
zu s5-zeiten sah das ganz anders aus.
wir hatten eine maschine mit einer 928b die hatte eine zykluszeit von ca 150ms.
das merkte man dann schon wenn nach einem stopbefehl nicht alles sofort stand.
 
Vor allem der Speicherverbrauch war früher oft ein Thema. Da hat man häufig gespart wo man nur konnte.
Und das SLD/SLW einer multiplikation mit 2 entsprechen sollte jeder wissen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Vor allem der Speicherverbrauch war früher oft ein Thema. Da hat man häufig gespart wo man nur konnte.
Und das SLD/SLW einer multiplikation mit 2 entsprechen sollte jeder wissen
Leute die frisch bei uns anfangen bzw. im den letzten Jahren angefangen haben, kennen kein AWL mehr.
 
Vor allem der Speicherverbrauch war früher oft ein Thema. Da hat man häufig gespart wo man nur konnte.
Und das SLD/SLW einer multiplikation mit 2 entsprechen sollte jeder wissen
Leute die frisch bei uns anfangen bzw. im den letzten Jahren angefangen haben, kennen kein AWL mehr.
SLW und SLD muss man nicht kennen, da gebe ich Dir Recht.
Aber (etwas umformuliert) ...
dass Schieben um n BitPositionen nach links einer Multiplikation mit 2^n entspricht, sollte jeder SPS-Programmierer wissen.
da gebe ich Jochen Recht.
Zumindest kann es nicht schaden, zu wissen, dass Addition, Subtraktion, Multiplikation und Division für einen Prozessor mehr darstellen als elementare "GrundBefehle" und sich mit logischen Operationen wie Negation, UND-, ODER-, XOR- und SchiebeOperationen und ProgrammSchleifen realisieren lassen.
Diese Operationen stellen also schon kleine Progrämmchen dar, die entweder bereits in der CPU bereitgestellt werden oder von einem CoProzessor oder vom BetriebsSystem oder von einem Compiler aus "einfacheren" Mitteln zusammengebastelt werden.

Um einen TaschenRechner benutzen zu können, muss man das nicht wissen.
Aber von einem SPS-Programmierer, dem man ja ohnehin schon den Umgang mit logischen Verknüpfungen zumutet, kann man solche Kenntnisse schon erwarten.
Sogar Kenntnisse über die Darstellung einer negativen Zahl im ZweierKomplement sollten vorhanden sein und auch der generelle Aufbau einer GleitKommaZahl mit ihren Vor- UND Nachteilen sollte bekannt sein.

Dass also Multiplikationen auf LinksSchieben beruhen und Divisionen auf RechtsSchieben, das sollte einen SPS-Programmierer nicht vom Hocker reissen.
Das Verschieben des Kommas bei einer DezimalZahl kennen die meisten ja auch für das Multiplizieren bzw. Dividieren mit/durch ZehnerPotenzen. Allerdings geschieht dabei das Verschieben des Kommas in genau der umgekehrten Richtung.
 
Zuletzt bearbeitet:
Zurück
Oben