Little Endian zu Big Endian für Siemens Simatic

Hallo Zusammen,
ich nutze gerade die Arduino IDE um mit Hilfe von Ethernet bzw ein ESP8266. Mich über Profinet mit der SPS zu unterhalten. Dies Funktioniert auch bis jetzt ganz gut.
Ich möchte aber auch Real/Float Werte an die SPS Übertragen und diese hat leider, da man nicht mit dem optimierten Speicherzugriff von Arduino auf die S7 Zugreifen kann Big Endian. Im Folgenden Code:
Ich habe auf der SPS Seite einen DB absolut Adressiert zum senden und empfangen.
Ich würde gerne auf Profinet bleiben und nicht via Modbus TCP arbeiten da es dann auf der SPS Seite kompliziert wird.
Ziel ist es Remote IO´s mit Arduino und ESP8266 zu erstellen und die Heizungssteuerung damit umzusetzen.
Auf der Arduino Seite ist ein OneWire Temperaturfühler von Dallas.

/*----------------------------------------------------------------------
  Data Read Demo

  Created 12 Dec 2016
  by Davide Nardella

  ------------------------------------------------------------------------
  This demo shows how to read data from the PLC.
  A DB with at least 1024 byte into the PLC is needed.
  Specify its number into DBNum variable

  - Both small and large data transfer are performed (see DO_IT_SMALL)
  - During the loop, try to disconnect the ethernet cable.
  The system will report the error and will reconnect automatically
  when you re-plug the cable.
  - For safety, this demo *doesn't write* data into the PLC, try
  yourself to change ReadArea with WriteArea.
  - This demo uses ConnectTo() with Rack=0 and Slot=2 (S7300)
  - If you want to connect to S71200/S71500 change them to Rack=0, Slot=0.
  - If you want to connect to S7400 see your hardware configuration.
  - If you want to work with a LOGO 0BA7 or S7200 please refer to the
    documentation and change
    Client.ConnectTo(<IP>, <Rack>, <Slot>);
    with the couple
    Client.SetConnectionParams(<IP>, <LocalTSAP>, <Remote TSAP>);
    Client.Connect();

  NodeMCU 1.0 ESP-12E ESP8266 supported

  ----------------------------------------------------------------------*/
// Wifi  -> #define S7WIFI
// Cable -> #define S7WIRED
#include <ESP8266WiFi.h>
#include "Settimino.h"
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS D4

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Uncomment next line to perform small and fast data access
#define BufferSize 64

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0x90, 0xA2, 0xDA, 0x0F, 0x08, 0xE1
};

IPAddress Local(192, 168, 178, 210); // Local Address
IPAddress PLC(192, 168, 178, 200); // PLC Address

// Following constants are needed if you are connecting via WIFI
// The ssid is the name of my WIFI network (the password obviously is wrong)
char ssid[] = "Homenet";    // Your network SSID (name)
char pass[] = "LabberOnkel";  // Your network password (if any)
IPAddress Gateway(192, 168, 178, 1);
IPAddress Subnet(255, 255, 255, 0);

int DBNum = 40; // This DB must be present in your PLC
byte Bufferrecv[BufferSize];
byte Buffersent[3];

// S7Client will create a WiFiClient as TCP Client
S7Client Client(_S7WIFI);

unsigned long Elapsed; // To calc the execution time
float Temperatur = 0.0;
union float2byte {
  float f;
  byte bytes[3];
} Convert;


//----------------------------------------------------------------------
// Setup : Init Ethernet and Serial port
//----------------------------------------------------------------------
void setup() {
  sensors.begin();  // Start the Tempsensor Pin
  // Open serial communications and wait for port to open:
  Serial.begin(9600);

  //--------------------------------------------- ESP8266 Initialization
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, pass);
  WiFi.config(Local, Gateway, Subnet);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("Local IP address : ");
  Serial.println(WiFi.localIP());
}
//----------------------------------------------------------------------
// Connects to the PLC
//----------------------------------------------------------------------
bool Connect()
{
  int Result = Client.ConnectTo(PLC,
                                0,  // Rack (see the doc.)
                                0); // Slot (see the doc.)
  Serial.print("Connecting to "); Serial.println(PLC);
  if (Result == 0)
  {
    Serial.print("Connected ! PDU Length = "); Serial.println(Client.GetPDULength());
  }
  else
    Serial.println("Connection error");
  return Result == 0;
}
//----------------------------------------------------------------------
// Dumps a buffer (a very rough routine)
//----------------------------------------------------------------------
void Dump(void *Bufferrecv, int Length)
{
  int i, cnt = 0;
  pbyte buf;

  if (Bufferrecv != NULL)
    buf = pbyte(Bufferrecv);
  else
    buf = pbyte(&PDU.DATA[0]);

  Serial.print("[ Dumping "); Serial.print(Length);
  Serial.println(" bytes ]===========================");
  for (i = 0; i < Length; i++)
  {
    cnt++;
    if (buf[i] < 0x10)
      Serial.print("0");
    Serial.print(buf[i], HEX);
    Serial.print(" ");
    if (cnt == 16)
    {
      cnt = 0;
      Serial.println();
    }
  }
  Serial.println("===============================================");
}
//----------------------------------------------------------------------
// Prints the Error number
//----------------------------------------------------------------------
void CheckError(int ErrNo)
{
  Serial.print("Error No. 0x");
  Serial.println(ErrNo, HEX);

  // Checks if it's a Severe Error => we need to disconnect
  if (ErrNo & 0x00FF)
  {
    Serial.println("SEVERE ERROR, disconnecting.");
    Client.Disconnect();
  }
}
//----------------------------------------------------------------------
// Profiling routines
//----------------------------------------------------------------------
void MarkTime()
{
  Elapsed = millis();
}
//----------------------------------------------------------------------
void ShowTime()
{
  // Calcs the time
  Elapsed = millis() - Elapsed;
  Serial.print("Job time (ms) : ");
  Serial.println(Elapsed);
}
//----------------------------------------------------------------------
// Main Loop
//----------------------------------------------------------------------
void loop()
{
  sensors.requestTemperatures(); // Send the command to get temperatures
  Convert.f = sensors.getTempCByIndex(0);

  int Sizercv, Resultrcv;
  int Sizesent, Resultsent;
  void *Targetrcv;
  void *Targetsent;

  Sizesent = 4;
  Targetsent = &Convert.bytes;

  Sizercv = BufferSize;
  Targetrcv = &Bufferrecv; // Uses a larger buffer


  // Connection
  while (!Client.Connected)
  {
    if (!Connect())
      delay(500);
  }

  Serial.print("Reading "); Serial.print(Sizercv); Serial.print(" bytes from DB"); Serial.println(DBNum);
  // Get the current tick
  MarkTime();
  Resultrcv = Client.ReadArea(S7AreaDB, // We are requesting DB access
                           DBNum,    // DB Number
                           0,        // Start from byte N.0
                           Sizercv,     // We need "Size" bytes
                           Targetrcv);  // Put them into our target (Buffer or PDU)
  if (Resultrcv == 0)
  {
    ShowTime();
    Dump(Targetrcv, Sizercv);
  }
  else
    CheckError(Resultrcv);
    
  Serial.println("Sending");
  Serial.print(" Byte1: ");
  Serial.print(Convert.bytes[0],HEX);
  Serial.print(" Byte2: ");
  Serial.print(Convert.bytes[1],HEX);
  Serial.print(" Byte3: ");
  Serial.print(Convert.bytes[2],HEX);
  Serial.print(" Byte4: ");
  Serial.println(Convert.bytes[3],HEX);
  Serial.print(" Float: ");
  Serial.println(Convert.f); 
  
  Client.WriteArea(S7AreaDB, // We are requesting DB access
                   DBNum,    // DB Number
                   64,        // Start from byte N.0
                   Sizesent,     // We need "Size" bytes
                   Targetsent);  // Put them into our target (Buffer or PDU)

  delay(3000);
}

Teil 2 da >9000

Ich mache mir auf dem Float via einem Union 4 Bytes die dann über dann über Client.Write Area übertragen werden
Leider halt im falschen Endian. Wie kann ich am einfachsten schon auf der Arduino Seite da ändern. Da es in der SPS leider zu komlpiziert wird das dann alles zu ändern für die Kommazahlen. Leider gibt es auf der CPU den Befehlt Little_to_BigEndian und zurück nicht, da diese eine Version <4.0 ist.

Es Funktioniert alles bis auf die Endian Reihenfolge hat jemand einen Input wie ich dies einfach im Union bzw ein Befehl mit dem ich es direkt tauschen kann also 4321 => 1234?
Gruß
DerDani

Link zur Lib >Hier<

Schau mal hier. Das geht in beide Richtungen.

Gruß Tommy

union float2byte {
  float f;
  byte bytes[3]; // muesste hier nicht 4 stehen?
} Convert;

"They are stored as 32 bits (4 bytes) of information."

float Temperatur = 3.14159;
union float2byte {
  float f;
  byte bytes[4];
} Convert;


void setup() {
  Serial.begin(9600);
  Convert.f = Temperatur;
  Serial.println("Sending");
  Serial.print(" Byte1: ");
  Serial.print(Convert.bytes[0], HEX);
  Serial.print(" Byte2: ");
  Serial.print(Convert.bytes[1], HEX);
  Serial.print(" Byte3: ");
  Serial.print(Convert.bytes[2], HEX);
  Serial.print(" Byte4: ");
  Serial.println(Convert.bytes[3], HEX);
  Serial.print(" Float: ");
  Serial.println(Convert.f,6);
  Serial.println("andere Reihenfolge");
  Serial.print(" Byte4: ");
  Serial.print(Convert.bytes[3], HEX);
  Serial.print(" Byte3: ");
  Serial.print(Convert.bytes[2], HEX);
  Serial.print(" Byte2: ");
  Serial.print(Convert.bytes[1], HEX);
  Serial.print(" Byte1: ");
  Serial.println(Convert.bytes[0], HEX);
}

void loop() {
}