Datenübertragung zwischen Siemens und Rockwell

miroblaz

Level-2
Beiträge
47
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo an alle,

ich habe ein Problem mit der Darstellung der übertragenen Daten zwischen einer Siemens und einer Rockwell Steuerung.

Die Verbindung zwischen Profibus DP und der Ethernet/IP Schnittstelle findet mit Hilfe eines Anybus Gateways.
Die Datenpakete sind für I/Os jeweils 32 BYTE groß.
Auf der AB Steuerung empfange ich somit 32 SINT.
Das Problem bekomme ich, wenn die Siemens Steuerung einen reellen Wert schickt.
Auf der AB Steuerung bekomme ich natürlich für diesen Float Wert 4 SINT Bytes.

Wie kann ich diese 4 SINT als reellen Wert anzeigen?

Ich bedanke mich für die Hilfe im Voraus.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich glaube eher, dass dir hier die Byte-Reihenfolge einen Strich durch die Rechnung macht.
Siemens organisiert seine Daten ja im Motorola-Standard, während Rockwell mit Intel-Standard arbeitet.

http://de.wikipedia.org/wiki/Byte_order

Wenn du auf Rockwell-Seite wieder einen gültigen 4-Byte REAL-Wert (Float) darstellen willst, dann musst du die 4 Bytes auf ein DWORD bzw. einen REAL abbilden, und die Bytes dann darin wieder entsprechend richtig anordnen.
Rotier- und Schiebefunktionen funktionieren aber nur mit dem Datentyp DWORD und nicht mit REAL.
Mit Rockwell hatte ich bisher noch nicht das vergnügen, mit Beckhoff habe ich soetwas schon mal gemacht.
Mit Beckhoff habe ich das ganze dann mittels Pointer gelöst.
Bei Rockwell gibt´s ja meines Wissens keine Pointer.
Vielleicht gibt es ja aber wenigstens eine MEMCPY (also Speicherbereiche umkopieren) Funktion. Dann könntest du die 4-Bytes in einem DWORD richtig anordnen, und dann mittels MEMCPY auf die REAL-Variable umkopieren.
 
Das ist jetzt nicht der eleganteste Code, aber so muß es auf der S7-Seite gehen. Ein DB mit mindestens 8Byte vorausgesetzt:
Code:
L littleEndianDwordVonRockwell
T DBx.DBD0

L DBx.DBB0
T DBx.DBB7
L DBx.DBB1
T DBx.DBB6
L DBx.DBB2
T DBx.DBB5
L DBx.DBB3
T DBx.DBB4

L DBD 4 // das Konvertierte Real

[code]
Da die Vertauschung symmetrisch ist, kann man oben auch mit einem S7-Real beginnen und erhält es für Rockwell konvertiert.
Wie es bei Rockwell geht, weiß ich nicht. Ich meine, die hatten getrennte Soeicherbereiche "files" für verschiedene Datentypen...
 
Na Zottel, da hat dein Gedächtnis wohl ein wenig nachgelassen. Es gibt genau für diesen Zweck einen Befehl auf der S7:

Aus der Simatic Hilfe:
TAD kehrt die Reihenfolge der Bytes in AKKU 1 um. Das Ergebnis wird in AKKU 1 gespeichert. AKKU 2 wird nicht verändert.
Inhalt AKKU1-H-H AKKU1-H-L AKKU1-L-H AKKU1-L-L
Vor der Ausführung von TAD Wert A Wert B Wert C Wert D
nach der Ausführung von TAD Wert D Wert C Wert B Wert A

Zottels Code rewritten:
Code:
L littleEndianDwordVonRockwell

TAD  // das Konvertierte Real

Grüße, hovonlo
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Bytes kommen bei der Rockwellsteuerung verdreht an.
Nachdem ich die in die richtige Reihenfolge in einem DINT gebracht habe, habe ich diese aus dem IEEE754-Format in die reelle Zahl umgerechnet.

Jetzt bin ich dabei die reelle Zahl wieder zurück zu rechnen und lesbar zur Siemens Steuerung zu schicken.
 
Die Bytes kommen bei der Rockwellsteuerung verdreht an.
Nachdem ich die in die richtige Reihenfolge in einem DINT gebracht habe, habe ich diese aus dem IEEE754-Format in die reelle Zahl umgerechnet.

Jetzt bin ich dabei die reelle Zahl wieder zurück zu rechnen und lesbar zur Siemens Steuerung zu schicken.
Das interessiert mich nun aber brennend, was es da noch groß zu rechnen gibt... ich meine es reicht die Bytereihenfolge umzudrehen und fertig... Kannst Du uns Deinen Code zeigen?
Mit "reelle Zahl" meinst Du doch wohl die üblichen Gleitkommazahlen nach IEEE754-Format, auch REAL oder FLOAT genannt? Oder verstehe ich Dich und Mobi total falsch - wieso meint Ihr, man müsse da was "umrechnen"?

Harald
 
PN/DP
Bei der Simatic ist es selbstverständlich dein Floatwert, der 4 Bytes die in einer DB belegt, binär, hexadezimal, dezimal oder als Gleitkommazahl anzuzeigen.
Bei der AB Steuerung ist ein DINT-Wert dezimal und der bleibt so. Um eine Gleitkommazahl zu kriegen musst du die Umrechnung selber vornehmen.
Siehe: http://de.wikipedia.org/wiki/IEEE_75...92_Dezimalzahl

Oder kennst du vielleicht eine Funktion bei RSLogix 5000, die DINT nach Float und umgekehrt wandelt?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es ist nicht direkt DINT, sondern eher DWORD. Um Real-Zahlen zu speichern reicht es nicht, wenn man es in ein DWORD schiebt. Eine Real-Zahl kann ja vor dem Komma und nach dem Komma ganz viele Stellen haben. Und es wird immer als DWORD gespeichert. Also musste man sich ein Format überlegen, sodass es immer in ein DWORD passt. Und das ist das IEEE754-Format. In diesem Format speichert das Simatic. Der S7-Programmierer merkt davon, was im Hintergund passiert, natürlich nichts, solange er in seiner Siemens-Welt bleibt. Erst wenn er mit anderen Herstellern Daten austauschen will, fällt es auf. Das hatte ich auch schonmal, wo ich Real-Zahlen zwischen einer S7 und einer Phoenix ILC hin und her transferieren musste.
Somit hab ich mir diese beiden Bausteine geschrieben:

REAL_TO_IEEE754 sieht dann so aus:
Code:
REAL_TO_BUF_1(REQ:=xReq,BUF_FORMAT:=FALSE,BUF_OFFS:=DINT#0,BUF_CNT:=DINT#4,SRC:=IN,BUFFER:=aTmp);
IN := REAL_TO_BUF_1.SRC;
aTmp := REAL_TO_BUF_1.BUFFER;
    
IF IN <> rINLast THEN
    xReq := TRUE;
END_IF;
    
IF REAL_TO_BUF_1.DONE THEN
    xReq := FALSE;
END_IF;
    
dwTmp.B0 := aTmp[0];
dwTmp.B1 := aTmp[1];
dwTmp.B2 := aTmp[2];
dwTmp.B3 := aTmp[3];
    
OUT := dwTmp;
    
rINLast := IN;

Und IEEE754_TO_REAL sieht so aus:
Code:
BUF_TO_REAL_1(REQ:=xReq,BUF_FORMAT:=FALSE,BUF_OFFS:=DINT#0,BUF_CNT:=DINT#4,BUFFER:=aTmp,DST:=OUT);
aTmp := BUF_TO_REAL_1.BUFFER;
OUT:=BUF_TO_REAL_1.DST;
      
IF IN <> dwINLast THEN
    xReq := TRUE;
END_IF;
      
IF BUF_TO_REAL_1.DONE THEN
    xReq := FALSE;
END_IF;
      
aTmp[0] := IN.B0;
aTmp[1] := IN.B1;
aTmp[2] := IN.B2;
aTmp[3] := IN.B3;
      
dwINLast := IN;

Als Datentyp musst du dannoch diesen hier anlegen:
Code:
TYPE
    ARRAY_OF_BYTE_0_3 : ARRAY [0..3] OF BYTE;
END_TYPE
 
Auf der Siemens-Seite packst Du einen 32-Bit-REAL-Wert in 4 Bytes und sendest diese zur AB-Steuerung.
Auf der Rockwell-Seite müßtest Du doch dann den (binären) Inhalt der empfangenen 4 Bytes nach der Byte-Vertauschung auch direkt als REAL-Wert interpretieren und nicht als DINT.

Wie kommst Du auf DINT? Wo kommt Dein DINT her? :confused:

Harald
 
REALs in Siemens S7 und Rockwell Controllogix sind beide IEE754 REALs.
Konvertierung soll also nicht notwendig sein, vielleicht ausser umtauschen von die bytes, wegen Little Endian und Big Endian (S7 / Controllogix).
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Jesper,

Von der Siemens Steuerung habe ich z.B. einen Realwert 50,3 geschickt
Auf der Rockwell habe ich 4 SINTs bekommen. Richtig gedreht und einen binären Wert 2#0100_0010_0100_1001_0011_0011_0011_0011 bekommen.
Dezimal entspricht das dem Wert: L#1112093491
Wie bekomme ich daraus den Wert 50.3 auf der Rockwellsteuerung ohne Umrechnung??

Die Rockwellsteuerung ist eine Compactlogix, wenn das von Bedeutung ist.

Miro
 
Zuletzt bearbeitet:
Es ist nicht direkt DINT, sondern eher DWORD. Um Real-Zahlen zu speichern reicht es nicht, wenn man es in ein DWORD schiebt. Eine Real-Zahl kann ja vor dem Komma und nach dem Komma ganz viele Stellen haben. Und es wird immer als DWORD gespeichert. Also musste man sich ein Format überlegen, sodass es immer in ein DWORD passt. Und das ist das IEEE754-Format. In diesem Format speichert das Simatic. Der S7-Programmierer merkt davon, was im Hintergund passiert, natürlich nichts, solange er in seiner Siemens-Welt bleibt. Erst wenn er mit anderen Herstellern Daten austauschen will, fällt es auf. Das hatte ich auch schonmal, wo ich Real-Zahlen zwischen einer S7 und einer Phoenix ILC hin und her transferieren musste.
Somit hab ich mir diese beiden Bausteine geschrieben:

REAL_TO_IEEE754 sieht dann so aus:
Code:
REAL_TO_BUF_1(REQ:=xReq,BUF_FORMAT:=FALSE,BUF_OFFS:=DINT#0,BUF_CNT:=DINT#4,SRC:=IN,BUFFER:=aTmp);
IN := REAL_TO_BUF_1.SRC;
aTmp := REAL_TO_BUF_1.BUFFER;
    
IF IN <> rINLast THEN
    xReq := TRUE;
END_IF;
    
IF REAL_TO_BUF_1.DONE THEN
    xReq := FALSE;
END_IF;
    
dwTmp.B0 := aTmp[0];
dwTmp.B1 := aTmp[1];
dwTmp.B2 := aTmp[2];
dwTmp.B3 := aTmp[3];
    
OUT := dwTmp;
    
rINLast := IN;

Und IEEE754_TO_REAL sieht so aus:
Code:
BUF_TO_REAL_1(REQ:=xReq,BUF_FORMAT:=FALSE,BUF_OFFS:=DINT#0,BUF_CNT:=DINT#4,BUFFER:=aTmp,DST:=OUT);
aTmp := BUF_TO_REAL_1.BUFFER;
OUT:=BUF_TO_REAL_1.DST;
      
IF IN <> dwINLast THEN
    xReq := TRUE;
END_IF;
      
IF BUF_TO_REAL_1.DONE THEN
    xReq := FALSE;
END_IF;
      
aTmp[0] := IN.B0;
aTmp[1] := IN.B1;
aTmp[2] := IN.B2;
aTmp[3] := IN.B3;
      
dwINLast := IN;

Als Datentyp musst du dannoch diesen hier anlegen:
Code:
TYPE
    ARRAY_OF_BYTE_0_3 : ARRAY [0..3] OF BYTE;
END_TYPE
Wozu muß dieser Datentyp angelegt werden???*:confused: :roll: :ROFLMAO: ;)
Ohne die zugehörigen Deklarationen sieht der Code einfach nur verworren aus...
Mobi, kann es sein, daß Du damit REAL-to-STRING- und STRING-to-REAL-Wandlungen machst oder meinst? Das war hier irgendwie gar nicht gefragt...

PS:
Ein REAL-Wert wird "eher wie" im REAL-Format gespeichert. Zufällig belegt das REAL-Format genausoviel Speicherplatz wie ein DWORD - mehr haben diese Datentypen nicht miteinander zu tun...

Gesendet von Harald's Galaxy Tab
 
Von der Siemens Steuerung habe ich z.B. einen Realwert 50,3 geschickt
Auf der Rockwell habe ich 4 SINTs bekommen. Richtig gedreht und einen binären Wert 2#0100_0010_0100_1001_0011_0011_0011_0011 bekommen.
Dezimal entspricht das dem Wert: L#1112093491
Wie bekomme ich daraus den Wert 50.3 auf der Rockwellsteuerung ohne Umrechnung??
Na, ist doch bereits alles bestens! In der Ansicht als REAL-Wert ist 2#0100_0010_0100_1001_0011_0011_0011_0011 = 50.3

Harald
 
Zurück
Oben