LMIC.h empfangenen Daten in Integer umwandeln

Hallo zusammen,

ich nutze die Bibliothek lmic.h um Daten über LoRaWAN zu empfangen. Mein Problem ist, dass ich die letzten beiden Bytes in meinem Frame, nicht in ein integer umgewandelt bekomme.
Ich habe es schon mit atoi() versucht und es klappt leider nicht. Könnt ihr mir weiterhelfen?

Mein Code:

case EV_TXCOMPLETE:
            Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
            if (LMIC.txrxFlags & TXRX_ACK)
              Serial.println(F("Received ack"));
            if (LMIC.dataLen) {

              Serial.println(F("Received "));
              Serial.println(LMIC.dataLen);
              Serial.print(F(" bytes of payload."));
              //Serial.write(LMIC.frame+LMIC.dataBeg, LMIC.dataLen);

              int laenge = LMIC.dataLen - 2;
              laengerBytes += laenge;
              Serial.print("Länge insgesamt: ");
              Serial.println(laengerBytes);
        
              char letztenBytes[2];
              Serial.print("Die letzten beiden:\n");
              for(int k=0;k<2;k++) {
                Serial.print(laenge+k);
                letztenBytes[k] = (LMIC.frame[LMIC.dataBeg+laenge+k]);
                Serial.print("   ");
                Serial.print(letztenBytes[k]);
                Serial.print("   ");
                Serial.print(letztenBytes[k], HEX);
              }
              
              Serial.print("\nDas wert in z1:");
              Serial.print(letztenBytes[0]);
              Serial.print("\nDas wert in z2:");
              Serial.print(letztenBytes[1]);
              
              char buf[3];
              buf[0] = letztenBytes[1];
              buf[1] = letztenBytes[2];
              buf[2] = '\0';
              
              int  ni;
              ni = atoi(buf);
              Serial.print("Das wert in N:");
              Serial.print(ni);
                   
            }
            // Schedule next transmission
            os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);

Viele Grüße
Marcel

das kommt drauf an wie du auf der Senderseite das int zerteilst und schickst.

aber im Prinzip brauchst du von den zwei Bytes nur das eine shiften und das andere dazu pappen (verodern).

Teil-Sketche sind immer blöd

aber in etwa so:

int  ni = buf[1]<<8 | buf[2];

Dir fehlen die Grundlagenkenntnisse zu char-Arrays, deshalb wird das bei Dir nichts mit atoi.
Die 2 Bytes müssen mit '\0' abgeschlossen werden (also 3 Bytes sein), damit atoi damit arbeiten kann.
Infos hier.

Gruß Tommy

Ich habe es gerade versucht und es funktioniert nicht.

              char buf[2];
              buf[0] = letztenBytes[1];
              buf[1] = letztenBytes[2];
              buf[2] = '\0';

              int  ni = buf[1]<<8 | buf[2];
              Serial.print("\nbuf[1]<<8 | buf[2]: ");
              Serial.print(ni);

@Tommy, am Ende steht die ‘\0’ im dritten Byte. Oder muss das nach dem Byte am Ende?

es funktioniert nicht.

ist keine Beschreibung. Einzige Antwort darauf ist: dann machs richtig.

poste deine Serial Ausgaben, oder sollen wir es erahnen was falsch ist?

wenn du in buf[2] den nullterminator hast, ist es sinnfrei, den zu shiften.

vieleicht:

int ni = buf[0]<<8 | buf[1];

gib dir mal buf 0 und buf 1 auch aus.

In buf[2] passen nur 2 Zeichen rein. buf[2]=’\0’ ist außerhalb Deines Arrays.
Wir wissen ja auch nicht, ob Du die Daten binär oder als Text schickst.
Bei binär ist der Weg über das char-Array mit 0-Terminator natürlich nicht sinnvoll.

Gib uns mehr Info, wenn Du zu einer Lösung kommen willst. z.B. einen Link zu Deiner Lib.

Gruß Tommy

Ich sende zum Mikrocontroller folgendes: AA BB 23 41

Die letzten beiden Bytes (23 41) möchte ich als Integer haben: 2341

Teil-Programm:

              char letztenBytes[2];
              Serial.print("Die letzten beiden:\n");
              for(int k=0;k<2;k++) {
                Serial.print(laenge+k);
                letztenBytes[k] = (LMIC.frame[LMIC.dataBeg+laenge+k]);
                Serial.print("   ");
                Serial.print(letztenBytes[k]);
                Serial.print("   ");
                Serial.print(letztenBytes[k], HEX);
              }
                            
              char buf[2];
              buf[0] = letztenBytes[1];
              buf[1] = letztenBytes[2];

              Serial.print("\nbuf[0]: ");
              Serial.print(buf[0]);

              Serial.print("\nbuf[1]: ");
              Serial.print(buf[1]);
                
              int  ni = buf[1]<<8 | buf[2];
              Serial.print("\nbuf[1]<<8 | buf[2]: ");
              Serial.print(ni);

Ausgabe:

Die letzten beiden:
2   #   23
3   A   41

buf[0]: A
buf[1]: t
buf[1]<<8 | buf[2]: 29696

Ich nutze die Bibliothek Lmic.h

AA BB 23 41

zu 2341 ist aber ganz was anderes ...

dein array muss also mindestens 4 bytes groß sein,

du nimmst byte[2]=23 und multiplizierst mit 100 und dann das byte[3]=41 dazu...

Da die Reihenfolge nicht wirklich ersichtlich ist beide Möglichkeiten.

int zahl = letztenBytes[0] << 8 | letztenBytes[1];
Serial.println(zahl,HEX);
zahl = letztenBytes[1] << 8 | letztenBytes[0];
Serial.println(zahl,HEX);

Gruß Tommy

Das funktioniert soweit:

Eingabe: 12 34

Ausgabe: 1234

int zahl = letztenBytes[0] << 8 | letztenBytes[1];
Serial.println(zahl,HEX);

wie kriege ich das als Integer convertiert? Sodass ich eine if bedingung machen wie z.b.:

if ( zahl == 1234)

Das ist ein Integer. Dir fehlen wirklich sämtliche Grundlagen.

if (zahl==0x1234)

Gruß Tommy

Das ist richtig :frowning:

Danke Tommy :wink:

Wie löse ich das Problem,

wenn ich in HEX: 10 habe und dieses in Binär: 0001 0000 erkannt wird und daraus eine 16 macht?

Bei 100 und 1000 ist es das selbe.

Welchen Bitweise Operatoren kann ich für sowas nutzen?

Du stehst dir da komplett im weg.

0x10 = 0d16 = 0b00010000

DAS IST DAS GLEICHE.
Da gibts nichts zum Umwandeln.
Das was du da siehst ist nur die Representation für dich zum lesen.
Für den Micro ist das das GLEICHE.

Öffne mal am PC deinen calc, schalte ihn um auf Programmierer und spiele da mit einzelnen Zahlen in hex/dez/bin damit du ein Gefühl dafür bekommst.

noiasca:
Du stehst dir da komplett im weg.

0x10 = 0d16 = 0b00010000

DAS IST DAS GLEICHE.
Da gibts nichts zum Umwandeln.
Das was du da siehst ist nur die Representation für dich zum lesen.
Für den Micro ist das das GLEICHE.

Öffne mal am PC deinen calc, schalte ihn um auf Programmierer und spiele da mit einzelnen Zahlen in hex/dez/bin damit du ein Gefühl dafür bekommst.

das ist mir bewusst. Dann stelle ich meine Frage besser.

Ich bekomme ein Frame und die letzten beiden Bytes ist meine Folgenummer. Diese Folgenummer will ich mit der erwarteten Folgenummer verglichen.

Nutze ich dafür strtol?

              char letztenBytes[2];
              Serial.print("Die letzten beiden:\n");
              for(int k=0;k<2;k++) {
                Serial.print(laenge+k);
                letztenBytes[k] = (LMIC.frame[LMIC.dataBeg+laenge+k]);
                Serial.print("   ");
                Serial.print(letztenBytes[k], HEX);
                Serial.print("   ");
                Serial.print(letztenBytes[k], BIN);
                Serial.print("\n");
              }
              
              int zahl = letztenBytes[0] << 8 | letztenBytes[1];

              Serial.print("\nZahl: ");
              Serial.print(zahl);

              if(zahl == folgenummer) {
                Serial.println("\nDas reinschreiben klappt");
              }

@TO: Ich gebs wegen Lernresistenz deinerseits auf.

Gruß Tommy

Hm sorry für die "dummen" fragen, aber so komme nicht weiter. Ich verstehe es nicht..

Ich bekomme eine Zahl 10:

0x10 = 0d16 = 0b00010000

das habe ich soweit verstanden.

Durch das Bitshiften und verodern wird daraus eine 16. Das habe ich auch verstanden.

Beide zahlen sind somit nicht gleich und ich weiß nicht, nach was ich suchen muss.

Könnt ihr mir bitte ein Tipp geben?

vorletzter Versuch

Wenn du glaubst, dass du 10 bekommst, bekommst du 0x10.
0x10=0d16

nein, durch das Bitschiften wird daraus kein “16” … das bitschiften multipliziert mit 256.
Darum habe ich vorhin gesagt du sollst mal deinen Calc anwerfen.

gib in dec 1 ein und LSH 8 … na was kommt raus???
Du hast das Byte um 8 stellen verschoben. also mit 256 multipliziert.

jetzt machst das ganze mal mit deiner 23 nach was kommt raus?
Was kommt raus wenn du nun 41 dazu zählst?

Du das sind wirklich Basics.

nächster Schritt nach dem calc.exe:

lade das mal hoch und schau dir an, was der Serial Monitor ausgibt.

void setup() {
  Serial.begin(115200);
  Serial.println(F("HEX DEC Nachhilfe"));

  byte myArray[4];
  myArray[0] = 0xAA;
  myArray[1] = 0xBB;
  myArray[2] = 0x23;
  myArray[3] = 0x41;

  //a Darstellung in HEX
  Serial.println(F("Darstellung in HEX"));
  Serial.print(myArray[2], HEX); Serial.print(" "); Serial.println (myArray[3], HEX);

  int zahl = myArray[2] << 8 | myArray[3];
  Serial.println(F("ein Zahl in HEX"));
  Serial.print(F("0x")); Serial.println(zahl, HEX);
  Serial.println(F("ein Zahl in dec"));
  Serial.print(F("0d")); Serial.println(zahl);

  Serial.println(F("positiv Beispiele"));
  if (zahl == 0x2341) Serial.println(F("True in hex")); else Serial.println(F("false in hex"));
  if (zahl == 9025) Serial.println(F("True in dec")); else Serial.println(F("false in dec"));

  Serial.println(F("negativ Beispiele"));
  if (zahl == 0x42) Serial.println(F("True in hex")); else Serial.println(F("false in hex"));
  if (zahl == 42) Serial.println(F("True in dec")); else Serial.println(F("false in dec"));  
}

void loop() {

}

wenn du noch fragen hast, dann bringe ein kompilierbares Beispiel. Codefetzen schaue ich mir von dir nicht mehr an.

Danke für das kleine Programm.

Ich habe etwas Schwierigkeiten mich deutlich auszudrücken. Da ich noch nicht so der Programmierer bin...

Ich sehe jetzt nur eine Lösung und zwar auf der Sendeseite aus, ein A zu versenden anstatt eine 10.

Oder gibt es in C/Arduino noch eine andere Möglichkeit?

Man kann auch ein 'B' senden ... meintest Du aber wohl nicht ...

WAS willst Du WIRKLICH??

MfG