MQTT und die Payload

Hallo zusammen,

ich bin neu unterwegs mit den ESPs und deren Programmierung..

Bis dato habe ich auch einige hinbekommen auch wenn mir die Stings OK Array in Char doch einiges an Probleme bereitet wenn man von VB, VBA usw. kommt.

Aktuell beisse ich mir die Zähne an der MQTT Payload die Zähne aus.
Ich habe einen fhem Broker laufen und dem ich zum testen über MQTT.fx mit Topic und payload füttere.

Bei den Bespielen die ich gefunden habe findet man immer diese Zeile

void callback(char* topic, byte* payload, unsigned int length)

als Funktionsheader. Das byte* payload sagt doch eigentlich aus, dass die Rückgabe in byte sprich Zahlen 0-255 sein soll oder ?

Wenn dem so ist warum bekomme ich dann auch Text zurück ??

Bei dem folgenden Code habe ich das Problem wenn ich dem Topic die Payload mit abc mitgebe erhalte ich abc
und die Stinglänge ist 4.
Wenn ich der Payload nun abcd mitgebe erhalte ich ⸮bcd"⸮⸮?⸮⸮⸮?⸮ @
und die Stringlänge ist 16. :confused:
Bei einer Payload von 123 erhalte ich 123 und bei 1234 erhalte ich 1234"⸮⸮?⸮⸮⸮?⸮ @.

Ich verstehe es nicht.

Hier mein Beispielcode mit der Callback funktion.

void callback(char* topic, byte* payload, unsigned int length) {
    Serial.print("Received message [");
    Serial.print(topic);
    Serial.print("] ");
   
    char msg[length+1];
    Serial.println("*********************");
    for (int i = 0; i < length ; i++) {
        // Serial.print((char)payload[i]);
        msg[i] = (char)payload[i];
        Serial.print("Zähler: ");
        Serial.println(i, DEC);
        Serial.print("Zeichen: ");
        Serial.println(msg[i]);
        Serial.println();
    }
    msg[i] = '\0';
    Serial.print("*********************");
    // Serial.println(length);
   
   // Serial.println(msg.length(), DEC);
    String myString = String(msg);
    Serial.println();
    Serial.print("Payload: ");
     // msg[length] = '&#92;&#48;';
    Serial.println(myString);
    Serial.println(myString.length());
    Serial.println(sizeof(msg));    
    
    if(strcmp(topic, "MQTT/TestSystem/relais/1") == 0){
      if(strcmp(msg,"open")==0){
          digitalWrite(ledPin1, HIGH);
      } else if(strcmp(msg,"closed")==0){
          digitalWrite(ledPin1, LOW);
      }
    } else if(strcmp(topic, "MQTT/TestSystem/relais/2") == 0){
      if(strcmp(msg,"on")==0){
          digitalWrite(ledPin2, HIGH);
      } else if(strcmp(msg,"off")==0){
          digitalWrite(ledPin2, LOW);
      }
    }
    memset(msg,'\0',sizeof(msg));
}

Hier die Ausgaben vom Code mit den Unterschiedlichen Topics

abc =
18:47:25.030 -> Received message [MQTT/TestSystem/relais/1] *********************
18:47:25.030 -> Zähler: 0
18:47:25.030 -> Zeichen: a
18:47:25.030 -> 
18:47:25.030 -> Zähler: 1
18:47:25.030 -> Zeichen: b
18:47:25.030 -> 
18:47:25.030 -> Zähler: 2
18:47:25.030 -> Zeichen: c
18:47:25.030 -> 
18:47:25.030 -> *********************
18:47:25.030 -> Payload: abc
18:47:25.030 -> 3
18:47:25.030 -> 4

abcd =
18:48:40.099 -> Received message [MQTT/TestSystem/relais/1] *********************
18:48:40.099 -> Zähler: 0
18:48:40.099 -> Zeichen: a
18:48:40.099 -> 
18:48:40.099 -> Zähler: 1
18:48:40.099 -> Zeichen: b
18:48:40.099 -> 
18:48:40.099 -> Zähler: 2
18:48:40.099 -> Zeichen: c
18:48:40.099 -> 
18:48:40.099 -> Zähler: 3
18:48:40.099 -> Zeichen: d
18:48:40.099 -> 
18:48:40.099 -> *********************
18:48:40.099 -> Payload: abcd"⸮⸮?⸮⸮⸮?⸮ @
18:48:40.099 -> 16
18:48:40.099 -> 5

Was muss ich hier verändern damit die Texte die ich der Payload mitgebe auch hier richtig angezeigt werden ?
Dann kann ich in der weiteren Verarbeitung auch richtig z.B. meine Relais schalten.

Wo kann ich mich als Anfänger gut einlesen ?

Vielen Dank schon mal

Sven

svenscherf:
Ich verstehe es nicht.

Hallo Sven, ich auch nicht, denn der Code kompiliert nicht:

error: 'i' was not declared in this scope
   msg[i] = '\0';

Mit einer kleinen Änderung bekomme ich (getestet mit UNO):

22:10:49.992 -> Received message [MQTT/TestSystem/relais/1] *********************
22:10:50.039 -> Zähler: 0
22:10:50.039 -> Zeichen: a
22:10:50.093 -> 
22:10:50.093 -> Zähler: 1
22:10:50.093 -> Zeichen: b
22:10:50.093 -> 
22:10:50.093 -> Zähler: 2
22:10:50.093 -> Zeichen: c
22:10:50.140 -> 
22:10:50.140 -> *********************
22:10:50.140 -> Payload: abc
22:10:50.193 -> 3
22:10:50.193 -> 4
22:10:50.193 -> Received message [MQTT/TestSystem/relais/1] *********************
22:10:50.240 -> Zähler: 0
22:10:50.240 -> Zeichen: a
22:10:50.293 -> 
22:10:50.293 -> Zähler: 1
22:10:50.293 -> Zeichen: b
22:10:50.293 -> 
22:10:50.293 -> Zähler: 2
22:10:50.293 -> Zeichen: c
22:10:50.340 -> 
22:10:50.340 -> Zähler: 3
22:10:50.340 -> Zeichen: d
22:10:50.340 -> 
22:10:50.340 -> *********************
22:10:50.394 -> Payload: abcd
22:10:50.394 -> 4
22:10:50.394 -> 5

Der Fehler liegt also im unbekannten Teil Deines Programms.

Hallo,

ich habe noch einiges versucht komme hier aber nicht an das Ziel.

Hier stelle ich den kpl. Code ein.
Bei SSID, Password und MQTT Broker müssen dann Realdaten rein.

#include <ESP8266WiFi.h> // Klasse für WiFi Verbindungen
#include <PubSubClient.h> // Klasse für MQTT Verbindungen
#undef MQTT_KEEPALIVE
#define MQTT_KEEPALIVE 60

const int ledPin1 = 12;
const int ledPin2 = 4;
const int tasterPin1 = 5;
const int tasterPin2 = 14;
const int blaueLED = 2;
int i;
int rssi;
int startup = 0;
int cnt = 10;

const char* versionstr = "0.1"; // Programmverion
const char* ssid = "xxxxxxxxxxxxxxxxxxxx";
const char* password = "xxxxxxxxxxxxxxxxxxx";
const char* mqtt_brocker = "000.000.000.000";
char* clientname = "TestSystem";

char rssistring[4];
char myIpString[24];
char mqttB_str[40] = "MQTT";
char mqtt_str[40] = "hallo";

WiFiClient espClient; // Deklarieren vom Object espClient mit dem ein Verbindung zu einer bestimmten IP Adresse hergestellt werden kann
PubSubClient client(espClient); // Deklarieren vom Object client welcher den Konstruktor vom zuvor erstellen WiFiClient empfängt

void setup_wifi(){
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password); 
  while (WiFi.status() != WL_CONNECTED) {
    cnt = cnt - 1;
    Serial.print(".");
    if (cnt < 1 ){
      ESP.restart();
    }
    delay(2000);
  }
  cnt = 10; // reset cnt nach erfolgreichem reconnect
  rssi = WiFi.RSSI(); 
  Serial.println(rssi);
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());  

}

void reconnect() {
    while (!client.connected()) {
        Serial.println("MQTT Verbindungsversuch...");
        if (client.connect(clientname)) {
          Serial.println("MQTT Verbindung hergestellt");
          cnt = 10; // reset cnt nach erfolgreichem connect
          
          if (startup == 1) {
            strcpy(mqtt_str,mqttB_str);
            strcat(mqtt_str,"startup");
            client.publish(mqtt_str,"StartUp");
            startup = 2;
          }
          strcpy(mqtt_str,mqttB_str);
          strcat(mqtt_str,"version");
          client.publish(mqtt_str,versionstr);
          strcpy(mqtt_str,mqttB_str);
          strcat(mqtt_str,"relais/1");
          client.subscribe(mqtt_str);
          strcpy(mqtt_str,mqttB_str);
          strcat(mqtt_str,"relais/2");
          client.subscribe(mqtt_str);



          IPAddress myIp = WiFi.localIP();
          sprintf(myIpString, "%d.%d.%d.%d", myIp[0], myIp[1], myIp[2], myIp[3]);
          strcpy(mqtt_str,mqttB_str);
          strcat(mqtt_str,"ip");
          client.publish(mqtt_str,myIpString);
          sprintf(rssistring, "%d",rssi);
          strcpy(mqtt_str,mqttB_str);
          strcat(mqtt_str,"rssi");          
          client.publish(mqtt_str, rssistring);


          
         } else {         
            Serial.print("failed, rc=");
            Serial.print(client.state());
            Serial.println(" retrying in 5 seconds");
            cnt = cnt - 1;
            if (cnt < 1 ){
              ESP.restart();
            }
            digitalWrite(LED_BUILTIN, LOW);
            delay(2000);
            digitalWrite(LED_BUILTIN, HIGH);
            delay(2000);
        }
    }
}

void callback(char* topic, byte* payload, unsigned int length) {
    Serial.print("Received message [");
    Serial.print(topic);
    Serial.print("] ");
   
    char msg[length+1];
    Serial.println("*********************");
    for (int i = 0; i < length ; i++) {
        // Serial.print((char)payload[i]);
        msg[i] = (char)payload[i];
        Serial.print("Zähler: ");
        Serial.println(i, DEC);
        Serial.print("Zeichen: ");
        Serial.println(msg[i]);
        Serial.println();
    }
    msg[i] = '\0';
    Serial.print("*********************");
    // Serial.println(length);
   
   // Serial.println(msg.length(), DEC);
    String myString = String(msg);
    Serial.println();
    Serial.print("Payload: ");
     // msg[length] = '&#92;&#48;';
    Serial.println(myString);
    Serial.println(myString.length());
    Serial.println(sizeof(msg));    
    
    if(strcmp(topic, "MQTT/TestSystem/relais/1") == 0){
      if(strcmp(msg,"open")==0){
          digitalWrite(ledPin1, HIGH);
      } else if(strcmp(msg,"closed")==0){
          digitalWrite(ledPin1, LOW);
      }
    } else if(strcmp(topic, "MQTT/TestSystem/relais/2") == 0){
      if(strcmp(msg,"on")==0){
          digitalWrite(ledPin2, HIGH);
      } else if(strcmp(msg,"off")==0){
          digitalWrite(ledPin2, LOW);
      }
    }
    memset(msg,'\0',sizeof(msg));
}  


void setup()
{
  Serial.begin(115200);
  Serial.println();
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(blaueLED, OUTPUT);
  pinMode(tasterPin1, INPUT);
  pinMode(tasterPin2, INPUT);
  digitalWrite(blaueLED,HIGH);
  strcat(mqttB_str,"/");
  strcat(mqttB_str,clientname);
  strcat(mqttB_str,"/");      

  
  setup_wifi();
  
  client.setServer(mqtt_brocker, 1883);
  client.setCallback(callback);
  reconnect();
}



void blinker(int a, int b) {
  for(i=4;i>=0;i--){
    digitalWrite(blaueLED,LOW);
    delay(a);
    digitalWrite(blaueLED,HIGH);
    delay(b);  
  }
}

void startDeepSleep(){
  Serial.println("Going to deep sleep...");
  ESP.deepSleep(0);
}


void loop(){


  if (!client.connected()) {
      reconnect();
  }

  if (digitalRead(tasterPin1)  == LOW){
    //Serial.println("Taster 1 = low");
    digitalWrite(ledPin1,HIGH);
    delay(1000);
    digitalWrite(ledPin1,LOW);
  }else{
    Serial.println("Taster 1 = high");
  
  }
  if (digitalRead(tasterPin2) == LOW){
    digitalWrite(ledPin2,HIGH);
    delay(1000);
    digitalWrite(ledPin2,LOW);
  }
  blinker(200,100);
  client.loop();

  // startDeepSleep();




    
}

Der Sketch läuft bei mir auf einem ModeMCU.

Vielleicht kann somit mein Skriptfehler gefunden werden denn ich bin hier ziemlich Ratlos.

Viele Grüße

Sven

Einen ESP8266 habe ich nicht, daher kommt von mir keine Antwort.

Hi,

wenn Du bei deinem Arduino ? die gleichen Bibliotheken nutzt sollte es ja keine Probleme geben.

Die Bibliotheken sind zwar unter Umständen an die ESPs angepasst und wenn es bei dir geht und bei mir nicht weiß ich dann woran es liegt :slight_smile:

Viele Grüße

Sven

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