Mehrere char zu einem int

Hallo,

ich habe jetzt länger nichts mehr mit Arduino gemacht und stehe furchtbar auf dem Schlauch :frowning:

Ich übertrage 4 Bytes über einen CAN Bus und möchte diese 4 Bytes wieder zu einer Variablen zusammenführen:

unsigned char canBuf[8];
<RX Routine>

uint32_t Zahl1 = canBuf[4] * 16777216 + canBuf[5] * 65535 + canBuf[6] * 256 + canBuf[7];
uint32_t Zahl2 = canBuf[4] << 24 | canBuf[5] << 16 | canBuf[6] << 8 | canBuf[7];

Serial.println (Zahl1);
Serial.println (Zahl2);

So klappt das nicht wirklich ...
Auf der Sender Seite klappt es übrigens, die uint32_t Zahl mit >> (shift) in den Buffer zu schieben.

Kann mir hier vielleicht jemand helfen? Vielen Dank im Voraus!

Gruß,
Horst

Auf beiden Seiten derselbe Prozessortype?
Dann könntest du mit "union type punning" arbeiten.
Nicht gerne gesehen, funktioniert aber mit dem gcc.

Ist natürlich klar, das funktionierende geheim halten, damit man auf keinen Fall darauf kommt, was an dem falschen falsch ist.

Welche werte willst Du zusammenführen udn was soll bei rauskommen?

Was siehst Du?

erwarten Sie Little-Endian- oder Big-Endian-Daten?

Ok,
habe mich wahrscheinlich etwas unklar ausgedrückt...

auf der Sender Seite sieht das vereinfacht so aus:

uint8_t temp[8];
uint32_t Zahl = xxxx; 

temp[4] = Zahl >> 24;
temp[5] = Zahl >> 16;
temp[6] = Zahl >> 8;
temp[7] = Zahl;
>> CAN SEND <<
<CAN RX>
unsigned char canBuf[8];
uint32_t Zahl1 = canBuf[4] * 16777216 + canBuf[5] * 65536 + canBuf[6] * 256 + canBuf[7];
uint32_t Zahl2 = canBuf[4] << 24 | canBuf[5] << 16 | canBuf[6] << 8 | canBuf[7];
Serial.println (Zahl1);
Serial.println (Zahl2);

bei Werten von
canBuf[4] = 0
canBuf[5] = 38
canBuf[6] = 87
canBuf[7] = 111

erwarte ich z.b. 2512751

bei Zahl1 erhalte ich genau dieses Ergebnis,
bei Zahl2 erhalte ich 22383


bei Werten von
canBuf[4] = 0
canBuf[5] = 0
canBuf[6] = 132
canBuf[7] = 114

erwarte ich z.b. 33906

bei Zahl1 erhalte ich 4294935666,
bei Zahl2 erhalte ich 4294935666


bei Werten von
canBuf[4] = 0
canBuf[5] = 2
canBuf[6] = 248
canBuf[7] = 250

erwarte ich z.b. 194810

bei Zahl1 erhalte ich 129274,
bei Zahl2 erhalte ich 4294965498

Gruß,
Horst

P.S. im Ersten Beispiel habe ich im Programm anstatt 65536 65535 angegeben. Das war natürlich auch falsch...

welcher Controller?

"Rechts vom =" ist zunächst mal int.
wenn int nur 16bit ist, müsstest du dein anBuf erst mal zu einem uint32_t casten damit du überhaupt um 24bit shiften kannst.

wenn das verwirrend war, mach mal einen einfachen vollständigen Sketch den man in die IDE laden kann ... dann wird sich auch eine Lösung finden.

1 Like

Controller ist der M256 bzw. Nano Every, also 8-Bit Controller.

Vielen Dank, noiasca! Das war der entscheidende Punkt. Es ist nicht möglich, die 8-Bit Werte so zusammenzuführen.

Wenn ich die empfangenen Werte zuvor in einen uint32_t großen Buffer schreibe, funktioniert es einwandfrei!

uint32_t Buf4 = canBuf[4];
uint32_t Buf5 = canBuf[5];
uint32_t Buf6 = canBuf[6];
uint32_t Buf7 = canBuf[7];


uint32_t Zahl1 = canBuf[4] * 16777216 + canBuf[5] * 65536 + canBuf[6] * 256 + canBuf[7];
uint32_t Zahl2 = canBuf[4] << 24 | canBuf[5] << 16 | canBuf[6] << 8 | canBuf[7];
uint32_t Zahl3 = Buf4 * 16777216 + Buf5 * 65536 + Buf6 * 256 + Buf7;

Zahl3 beinhaltet jetzt alle richtigen werte :slight_smile:

Gruß,
Horst

oder

uint32_t Zahl = ((uint32_t) canBuf[4]) << 24 | ((uint32_t) canBuf[5]) << 16 | ((uint32_t) canBuf[6]) << 8 | ((uint32_t) canBuf[7]);
1 Like

Es lassen sich ein paar Klammern sparen, wenn man die C++ Cast Schreibweise nutzt
uint32_t Zahl = uint32_t(canBuf[4]) << 24 | uint32_t(canBuf[5]) ......

1 Like

du musst nur das casten, dass durch das shiften zu groß wird.
Wenn auf deinem M256 annahme int 16bit hat reicht auch das:

uint32_t Zahl4 = uint32_t(canBuf[4]) << 24 | uint32_t(canBuf[5]) << 16 | canBuf[6] << 8 | canBuf[7];

P.S.: du kannst einen Beitrag als Lösung markieren und dich (auch bei mehreren) Helfern mit Herzchen bedanken. Kostet dich nichts - aber vieleicht freut es den/die andere

1 Like

gutes Argument

Hallo zusammen,
vielen Dank für Eure Unterstützung! Bin mir ziemlich sicher, das ich diesen Fehler schon einmal hatte und auch nicht drauf kam.

uint32_t Zahl4 = uint32_t(canBuf[4]) << 24 | uint32_t(canBuf[5]) << 16 | canBuf[6] << 8 | canBuf[7];

Werde auf jeden Fall diese Schreibweise benutzen, gefällt mir sehr!

Viele Grüße,
Horst

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.