Umwandlung einer Zeichenkette in mehrere Zahlen funktioniert nicht richtig

Hallo zusammen,

für eine Lichtsteuerung übergebe ich von meinem Raspberry über mqtt einen Sting mit den benötigten Parametern an den Sketch (liegt dann in payload).
Dort soll der Sting in die einzelnen Parameter (Lichtfarbe, Modus und Helligkeit) zerlegt werden.
Mein Code dazu sieht wie folgt aus:

  int i;
  byte LiFa[6];
  for (i=0; i<6; i++){
    LiFa[i]=payload[i];
  }
  LICHTFARBE = strtol((char* ) LiFa, NULL, 16);

  byte Modus[1];
  Modus[0] = payload[6];

  BETRIEBSMODUS = strtol((char* ) Modus, NULL, 16);

  byte Hell[3];
  for (i=7; i<10; i++){
    Hell[i-7]=payload[i];
   }
  BRIGHT = strtol((char* ) Hell, NULL, 10);

  Serial.print("Lichtfarbe: ");
  Serial.println(LICHTFARBE);

  Serial.print("Betriebsmodus: ");
  Serial.println(BETRIEBSMODUS);

  Serial.print("Helligkeit: ");
  Serial.println(BRIGHT);

Lichtfarbe und Betriebsmodus funktionieren, Bei der Helligkeit wird an den erwarteten Wert eine "1" angehängt.

Hier die Ausgabe des seriellen Monitors:

Nachricht empfangen [Topic] c51fff1200
Lichtfarbe: 12918783
Betriebsmodus: 1
Helligkeit: 2001

c51fff Lichtfarbe
1 Modus
200 Helligkeit

aus c51ffff wird 12918783 stimmt
Betriebsmodus passt auch

Nur bei der Helligkeit wird die 1 angehängt.
Woher kommt die, zumal das Array ja auch nur 3 Zeichen hat?
Alle meine Versuche diese letzte Ziffer wegzubekommen sind bis jetzt fehlgeschlagen.
Den falschen Wert nachträglich behandeln (die zusätzliche 1 "abschneiden") möchte ich vermeiden.

aus deiner Payload bzw. aus einer falschen Index-Berechnung.

Kann man aber kaum mit deinem verstümmelten Codeteil feststellen wenn man nicht sieht was aktuell in deiner payload drinnen steht.

Mach einen Standalone Sketch inkl. einer befüllten Payload und dann kann man dir das besser zeigen.

Danke erst mal für deine Hilfe.

in der payload steht: c51fff1200

Ich hab mal den reduzierten Sketch erstellt, mit dem das Problem nachvollziehbar ist.

int BETRIEBSMODUS;    
uint32_t LICHTFARBE;  
uint16_t BRIGHT;
const char* payload = "c51fff1200";

void setup() {
  Serial.begin(115200);
  int i;
  byte LiFa[6];
  for (i=0; i<6; i++){
    LiFa[i]=payload[i];
  }
  LICHTFARBE = strtol((char* ) LiFa, NULL, 16);

  byte Modus[1];
  Modus[0] = payload[6];
  BETRIEBSMODUS = strtol((char* ) Modus, NULL, 16);

  byte Hell[3];
  for (i=7; i<10; i++){
    Hell[i-7]=payload[i];
  }
  BRIGHT = strtol((char* ) Hell, NULL, 10);

}

void loop() {
  Serial.print("payload: ");
  Serial.println(payload);
  Serial.print("Lichtfarbe: ");
  Serial.println(LICHTFARBE);
  Serial.print("Betriebsmodus: ");
  Serial.println(BETRIEBSMODUS);
  Serial.print("Helligkeit: ");
  Serial.println(BRIGHT);
  delay(20000);
}

strtol() erwartet ein c-String übliches Ende.
Das ignorierst du durchgängig.

Bin in dem Gebiet noch ein absoluter Anfänger :frowning:
Was kann ich besser machen?

wenn combie sagt, es liegt daran strtol c-Strings braucht, dann könntest du eben die Nullterminatoren setzen.

int BETRIEBSMODUS;
uint32_t LICHTFARBE;
uint16_t BRIGHT;
const char* payload = "c51fff1200";

void setup() {
  Serial.begin(115200);
  int i;
  byte LiFa[7];
  for (i = 0; i < 6; i++) {
    LiFa[i] = payload[i];
  }
  LiFa[6]='\0';
  LICHTFARBE = strtol((char* ) LiFa, NULL, 16);

  byte Modus[2];
  Modus[0] = payload[6];
  Modus[1] = '\0';
  BETRIEBSMODUS = strtol((char* ) Modus, NULL, 16);

  byte Hell[4];
  for (i = 7; i < 10; i++) {
    Hell[i - 7] = payload[i];
  }
  Hell[3] = '\0';
  BRIGHT = strtol((char* ) Hell, NULL, 10);

}

void loop() {
  Serial.print("payload: ");
  Serial.println(payload);
  Serial.print("Lichtfarbe: ");
  Serial.println(LICHTFARBE);
  Serial.print("Betriebsmodus: ");
  Serial.println(BETRIEBSMODUS);
  Serial.print("Helligkeit: ");
  Serial.println(BRIGHT);
  delay(20000);
}

Lichtfarbe: 12918783

Betriebsmodus: 1

Helligkeit: 200

Schönheit ist es keine.

Allgemein: Ein klein wenig über C-Strings lesen.

Speziell: LiFa und Hell jeweils ein Byte länger definieren und nach dem Kopieren aus der Payload die erforderliche Null \0 anhängen.

Edit: Da war @noiasca (mit Tastatur ?) schneller als ich mit dem Daumen.

1 Like
int BETRIEBSMODUS;
uint32_t LICHTFARBE;
uint16_t BRIGHT;
const char *payload = "c51fff1200";

void setup()
{
  Serial.begin(9600);
  Serial.print("payload: ");
  Serial.println(payload);

  
  char buffer[10];
  
  strncpy(buffer, payload, 6);
  LICHTFARBE = strtol(buffer, NULL, 16);
  Serial.print("Lichtfarbe: ");
  Serial.println(LICHTFARBE,HEX);
  
  buffer[0] = payload[6];
  buffer[1] = 0;
  BETRIEBSMODUS = strtol(buffer, NULL, 16);
  Serial.print("Betriebsmodus: ");
  Serial.println(BETRIEBSMODUS);

  BRIGHT = strtol(payload + 7, NULL, 10);
  Serial.print("Helligkeit: ");
  Serial.println(BRIGHT);
}

void loop()
{

}

Auch keine Schönheit.

Danke euch beiden,

  1. funktioniert perfekt.
  2. noch besser: habe etwas dabei gelernt

Schön, dass du die Lösung selber gefunden hast...
Das nenne ich mal: Schnell gelernt!

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