struct und Array (Arduino)

Gast #5587182
Lesenswert?

Hallo zusammen,

ich spiele gerade ein ein wenig mit UDP herum. Ich empfange per UDP 
nacheinander mehrere Array's zwischen 25-1341 Bytes. Diese möchte ich in 
entsprechende Strukturen ablegen, die auch definiert sind. Nur stehe ich 
auf dem Schlauch, da ich nicht weiß wie ich es umkopieren soll.

memcpy funktioniert ja nicht, da das jeweilige Struct, aus verschiedenen 
Datentypen besteht, wie int16, float etc.

Wie stelle ich das am besten an?

Gruß Anfänger
Gast #5587188
Lesenswert?

Entweder schreibst Du Dir entsprechende Konverter, die jedes Byte 
einzeln bearbeiten, ....

Oder du stellst sicher, dass endianess, allignment und packing gleich 
sind, dann  memcpy oder Struktur-zuweisung.
Persönliche Seite #5587326
Lesenswert?

Arduino Anfänger schrieb:
> memcpy funktioniert ja nicht, da das jeweilige Struct, aus verschiedenen
> Datentypen besteht, wie int16, float etc.

Wieso sollte es das nicht tun? Natürlich kann man Strukturen per memcpy 
kopieren.

Das geht nur dann nicht, wenn das empfangene Strukturabbild nicht dem 
Deiner Zielstruktur entspricht.

Daß Du Deine Daten zunächst als uint8_t-Array empfängst, hat nichts mit 
der Art des Strukturabbildes zu tun.
Gast #5592080
Lesenswert?

> Nur stehe ich
> auf dem Schlauch, da ich nicht weiß wie ich es umkopieren soll.

Du koenntest das automatisch im Hintergrund vom Compiler machen lassen.
Hier mal ein Beispiel wie ich das mache:

struct HeaderType
{
  uint32_t crc32;         //Prüfsumme des Datenstructes
  uint16_t length;        //Laenge des Datenstructes
  uint8_t  UsedDataType;  //Type des Datenstructes
  uint8_t  Version;       //Version des Datenformates
  uint32_t UpCounter;     //Ein Zaehler den der Sender bei jedem Paket 
um 1 erhoeht
  uint8_t  encoding;      //0= keine Verschluesselung
  uint8_t  unused1;       //fuer zukuenftige Erweiterungen
  uint8_t  unused2;       //fuer zukuenftige Erweiterungen
  uint8_t  crc8;          //Pruefsumme das HeaderTypes
} _attribute_ ((packed));

union HeaderUnion
{
  struct HeaderType Header;
  uint8_t           Byte[16];
};

[..]

  HeaderUnion UDP_Header;

[..]

        //Den Header kopieren
        for(i=0; i<sizeof(HeaderUnion); i++)
          {
                UDP_Header.Byte[i] =    *UDP_Paket++;
          }

[..]

        //Pruefsumme des Header okay?
        if (UDP_Header.Header.crc8 != CRC8(UDP_Header.Byte, 
sizeof(HeaderUnion) -1 ) ) return ( UDP_HEADER_\
CRC);


Das funktioniert, sieht elegant aus, setzt aber voraus das du verstehst 
was du machst weil es abhaengig von Compiler und Wordbreite im 
Controller sein kann. Aber bei der geeigneten Wahl von Pruefsummen von 
Header und Daten faellt man nicht so schnell auf die Nase.

Olaf
Gast #5592105
Lesenswert?

> Ist in C aber unportabel und in C++ (Arduino!) ganz verboten (siehe den
> Artikel).

Auf die Probleme hab ich hingewiesen.

Lustigerweise ist das ein Codeausschnitt den ich verwende um von meinem 
PC aus (Qt) die Helligkeit meiner Schreibtischlampe (ESP8266/Arduino) 
einzustellen. Es ist also wohl doch nicht ganz verboten und nicht ganz 
unportabel. Und da ich sowohl fuer header wie auf fuer Daten jeweils 
eine Pruefsumme verwende wuerde es mir auffallen sollte es doch 
irgendwann mal ein Problem geben.

p.s: die Methode zur en/dekodierung meiner Daten in/aus einem UDP-Paket 
verwende ich 1:1 kopiert, sowohl in Arduino wie auch im Qt-Programm.

Olaf
Persönliche Seite #5592113
Lesenswert?

Olaf schrieb:
> Es ist also wohl doch nicht ganz verboten und nicht ganz
> unportabel.

Das ist ja die Tücke an Undefined Behaviour (d.h. "verbotenen" Dingen) - 
es kann den Anschein haben zu funktionieren, und wenn du eine 
Kleinigkeit änderst (Compiler, -Version, -Optionen, Plattform, ...) 
klappt es nicht mehr. Das Argument "funktioniert doch" zieht hier also 
nicht. In Serialisierung ist das alles erläutert und begründet, 
inklusive korrekter Lösungen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren