Sonstiges Siemens MSB to Codesys LSB

byt0x

Level-1
Beiträge
9
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Servus,

erneut eine Frage.

Nun ist es so, dass Siemens wohl meint seine Werte als MSB(yte) in den DWORD's zu speichern.
Codesys tut dies nun als LSB(yte).

Um ein DWORD aus zwei Modbus-Registern in einen REAL o.Ä zu speichern habe ich bisher in Codesys die Funktion MEM.ReverseWORDsInDWORD genutzt.

Meine Frage nun: Wie sind denn die Bytes bei Siemens angeordnet bei Datentypen die 64Bit breit sind wie z.B ein LREAL und wie kann ich das in das entsprechende Codesys LSB umwandeln?

Gruß und Danke
 
Kommt drauf an was Du mit "Siemens" meinst... Die Siemens-Welt ist groß und entsprechend gibt es viele verschiedene Lösungswege, die natürlich nicht alle in allen Siemens-Geräten gehen...

Wenn eine Siemens-SPS mehrere Modbus-Register empfängt, dann muß sie in der Regel gar keine Bytes tauschen. Höchstens wenn sie die Register an eine Codesys-SPS weiterreichen soll und dem armen Codesys-Programmierer freundlicherweise etwas helfen will. Weil ja die Codesys-Steuerungen meinen, das Speichern als Little-endian wäre so viel besser als Big-endian, deshalb macht Siemens das jetzt heimlich nach und nennt es Marketing-gerecht "optimiert" ;)

Harald
 
Da Du keine Details zu der Siemens-Komponente verrätst, sage ich nun, das ist eh' egal. Haltet Euch einfach an die bei Modbus übliche Network Byte order Big-endian. Dann muß die Siemens-Komponente nichts beachten. In Deiner Codesys SPS musst Du auch bei 64-Bit-Datentypen die Reihenfolge der 4 Words komplett umkehren, also aus der Word-Reihenfolge 1234 musst Du 4321 machen. Vermutlich gibt es dafür in Codesys eine fertige Funktion, da kenne ich mich aber nicht aus.

Harald
 
Servus,

PAC3200.
Eine Funktion habe ich bisher nicht finden können, aber so muss ich wohl den Speicher selber herumkopieren um zum Ergebnis zu kommen.

Was ich nicht verstehe, warum sind dann die Bytes und/oder die Bits nicht auch entsprechend codiert, sondern nur die Words?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was ich nicht verstehe, warum sind dann die Bytes und/oder die Bits nicht auch entsprechend codiert, sondern nur die Words?
Mit irgendeinem Baustein (welcher?) holst Du die Register vom Modbus-Gerät.
Wenn Du danach mit MEM.ReverseWORDsInDWORD lediglich die beiden Words tauschst, um die benötigte Byte-Reihenfolge für einen REAL zu erhalten, dann hat anscheinend der Modbus-Lese-Baustein schon vorsorglich die Bytes der Modbus-Register/Words getauscht, weil er weiß daß die Bytes bei Modbus Big-Endian sind und die Codesys-SPS Little-Endian verwendet. Daß/welche mehrere Modbus-Register einen höheren Datentyp ergeben, weiß der Modbus-Lese-Baustein nicht.

Um aus 4 Word-Registern einen 64-Bit-LREAL zu machen brauchst Du dann lediglich das 1. mit dem 4. Register/Word zu tauschen und das 2. mit dem 3. Register. Das Word-Tauschen kannst Du nun mithilfe eines WORD-Arrays veranstalten, und für die Zuweisung an den LREAL eine UNION verwenden, z.B. etwa so:
Code:
TYPE MB_REG4:
  STRUCT
    R1 : WORD;
    R2 : WORD;
    R3 : WORD;
    R4 : WORD;
  END_STRUCT
END_TYPE

TYPE MB_LREAL:
  UNION
    l : LREAL;
    r : MB_REG4;
  END_UNION
END_TYPE

MBLReal  : MB_LREAL;
lrResult : LREAL;
awBuf    : ARRAY [0..3] OF WORD; //die 4 Register vom Modbus-Lesen


//die 4 Word-Register in umgekehrter Reihenfolge in die UNION kopieren ...
MBLReal.r.R1 := awBuf[3];
MBLReal.r.R2 := awBuf[2];
MBLReal.r.R3 := awBuf[1];
MBLReal.r.R4 := awBuf[0];
//... und als LREAL herausholen
lrResult := MBLReal.l;

Harald
 
Das Prinzip ist verstanden und die Funktion auch und die Tatsache das der Codesys-Modbus-Baustein bereits die Bytes (nicht die Bits?) tauscht auch. Nur für mich um wirklich zu verstehen fehlt folgendes Hintergrundwissen:

Bezieht sich das Big-Endian bei Modbus auf die Bytes, oder die Bits? Also sind die Bytes BigEndian und die Bits darin LittleEndian? Oder beides BigEndian?

Hast Du ggf. aus der RFC einen Auszug parat wo man das nachlesen kann?
 
Das Problem in Deinem Fall ist, dass
Bezieht sich das Big-Endian bei Modbus auf die Bytes, oder die Bits? Also sind die Bytes BigEndian und die Bits darin LittleEndian? Oder beides BigEndian?
Hääää, ach so, jetzt versteh ich es. Big Endian und Little Endian fallen unter die Gruppe Byteorder, damit sollte Deine Frage beantwortet sein. Eine Zahl in hexadezimaler Schreibweise von 2A3F wird bei Big Endian 2A 3F im Speicher abgelegt und bei Little Endian als 3F 2A. Bei vier Bytes 2A3FDE4C entsprechend 2A 3F De 4C und 4C DE 3F 2A.
Bitte auch den Hinweis von Harald beachten bezüglich der Problematik der 2 und 4 Word-Register.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Bezieht sich das Big-Endian bei Modbus auf die Bytes, oder die Bits?
Endian = Byte-Order
Bits werden nicht gedreht

Beispiel:
Modbus Register 1: 16#1A2B
Modbus Register 2: 16#3C4D
zusammen Wert: 16#1A2B3C4D

Modbus transportiert die 2 Register als 4 Bytes so: 1A2B|3C4D
Der Modbus Empfangs-Baustein macht daraus 2B1A|4D3C
Für die Codesys-SPS für DWORD (oder größer) aus >= 2 Registern braucht man aber 4D3C|2B1A

LREAL 64 Bit aus 4 Registern = 8 Bytes:
Modbus sendet: 1A2B|3C4D|5162|7384 ---> Empfangsbaustein liefert: 2B1A|4D3C|6251|8473 ---> SPS braucht: 8473|6251|4D3C|2B1A

Harald
 
Zurück
Oben