Serial.print() eines uint8_t gibt 4 Bytes aus?!

#5732852
Lesenswert?

Hallo,

ich habe folgende Structs:
1
#define RF69_MAX_DATA_LEN 61
2

3
struct nodePacketTH {
4
  uint8_t command;
5
  uint8_t serialNumber[6];
6
  float temperature;
7
  float humidity;
8
};
9

10
struct RF69dataPacket {
11
  uint8_t len;
12
  uint8_t senderID;
13
  uint8_t targetID;
14
  uint8_t rssi;
15
  char buffer[RF69_MAX_DATA_LEN];
16
  bool ackRequested;
17
};
18

19
RF69dataPacket packet;
20
nodePacketTH nodePacket;

und folgenden Code:
1
for (uint8_t n = 0; n < 15; n++)
2
{
3
  Serial.print(n);
4
  Serial.print(": ");
5
  Serial.println(packet.buffer[n], HEX);
6
}

Die Ausgabe sieht so aus:
0: 54
1: 30
2: FFFFFFBC
3: 77
4: 14
5: 73
6: FFFFFF90
7: FFFFFFB0
8: FFFFFFB6
9: FFFFFFDB
10: 41
11: 10
12: FFFFFFF9
13: FFFFFFA7
14: 41


µC ist ein Atmega328p, Arduino Framework wird genutzt.
Wie ist denn das möglich, dass bei der Ausgabe eines Bytes plötzlich 4 
Bytes ausgegeben werden? Der Inhalt des Buffers passt, ich übertrage 
genau 15 Byte dieses Buffers auf eine andere Node (per Funk) und dort 
kommen die Daten ohne den führenden drei FF Bytes an.

Bug in der Serial.print? Hat das möglicherweise etwas mit dem Alignment 
der Struct aufgrund der floats darin zu tun?

Braucht ihr mehr Infos, oder ist der Fehler schon offensichtlich?

Danke!


edit:
1
for (uint8_t n = 0; n < 15; n++)
2
{
3
  snprintf(printbuf, sizeof(printbuf), "%u: %x", n, packet.buffer[n]);
4
  Serial.println(printbuf);
5
}

Gibt übrigens folgendes aus:
0: 54
1: 30
2: ffbc
3: 77
4: 14
5: 73
6: ff90
7: ff84
8: 24
9: ffdc
10: 41
11: 10
12: ffff
13: ffa6
14: 41

also nur mehr ein führendes Byte. wtf?
#5732868
Lesenswert?

Walter schrieb:
> wie ist packet definiert??

sorry, hab ich grad ergänzt, steht jetzt oben.

Walter schrieb:
> Hast du schon in der Doku von serial.printf nachgesehen?

Naja, die Arduino Doku zu Serial.print ist sehr spärlich. Arduino halt.
Wenn ich einen int16 oder int ausgeben würde, würde ich es ja verstehen, 
aber char? char ist doch 1 byte groß.

Das hier hab ich gefunden:
https://electronics.stackexchange.com/questions/49662/arduino-why-does-serial-printlnint-hex-display-4-bytes

wirft aber nur noch mehr Rätsel auf, da ich ja eben einen char 
verwende...
#5732881
Lesenswert?

A. S. schrieb:
> char ist (vielleicht) signed und nicht uint8_t.

hmm, wenn ich packet so definiere:
1
struct RF69dataPacket {
2
  uint8_t len;
3
  uint8_t senderID;
4
  uint8_t targetID;
5
  uint8_t rssi;
6
  uint8_t buffer[RF69_MAX_DATA_LEN];
7
  bool ackRequested;
8
};
9

10
RF69dataPacket packet;

dann bekomme ich keine führenden Bytes bei der Ausgabe (passt also), 
dafür natürlich Compilerwarnungen bei
1
snprintf(packet.buffer, 8, "P%s", settingsObj.serialNumber);

á la:
invalid conversion from 'uint8_t* {aka unsigned char*}' to 'char*' 
[-fpermissive]
Moderator #5733006
Lesenswert?

Ja, die Ausgabe negativer Zahlen (char ist beim GCC defaultmäßig 
vorzeichenbehaftet) in einer von 10 verschiedenen Basis erfolgt immer im 
32-Bit-Zweierkomplement, bei 8-Bit-Werten in hex also in der Form 
FFFFFFxx. Um das zu vermeiden, musst den Wert in ein unsigned char oder 
uint8_t casten:

1
Serial.println((uint8_t)packet.buffer[n], HEX);
#5733015
Lesenswert?

Yalu X. schrieb:
> Ja, die Ausgabe negativer Zahlen (char ist beim GCC defaultmäßig
> vorzeichenbehaftet) in einer von 10 verschiedenen Basis erfolgt immer im
> 32-Bit-Zweierkomplement, bei 8-Bit-Werten in hex also in der Form
> FFFFFFxx. Um das zu vermeiden, musst den Wert in ein unsigned char oder
> uint8_t casten:
>
> Serial.println((uint8_t)packet.buffer[n], HEX);

Vielen Dank. Du hast in sinnvolle Worte gefasst, was ich mir im Groben 
schon gedacht habe, nach den letzten Posts.

Wenn hier Threads geschlossen werden können, gäbe es kaum einen 
passenderen Zeitpunkt als jetzt. Frage beantwortet :-)

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