• Hallo zusammen,
    Besten Dank für die Aufnahme in eurem Forum. Ich bin neu hier im Forum und habe die Erklärungen von Nick zu MQTT (Quelle: https://makesmart.net/esp8266-d1-mini-mqtt/) regelrecht verschlungen. An dieser Stelle großes Dankeschön an Nick, das ist eine supper Erklärung. 👏

    Über den Serielmonitor kann ich auch alle msg.topics anzeigen. Nun wollte ich gern die msg auch auf ein Display anzeigen lassen, z.B. das OLED SSD1306.
    Damit alle wissen was ich meine möchte ich gern hier den Code von Nick anhängen. Hier sieht man, dass das msg auf den Serienmonitor über “Serial.println(msg)” angezeigt wird und auch klasse funktioniert, aber leider bekomme ich es nich auf das OLED. 😥
    Danke Euch schonmal im voraus für die Unterstützung. 👍

    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
     
    const char* SSID = "WIFI_SSID";
    const char* PSK = "WIFI_KEY";
    const char* MQTT_BROKER = "test.mosquitto.org";
     
    WiFiClient espClient;
    PubSubClient client(espClient);
     
    void setup() {
        Serial.begin(115200);
        setup_wifi();
        client.setServer(MQTT_BROKER, 1883);
        client.setCallback(callback);
    }
     
    void setup_wifi() {
        WiFi.begin(SSID, PSK);
     
        while (WiFi.status() != WL_CONNECTED) {
            delay(100);
        }
        
        Serial.println(WiFi.localIP());
    }
    void loop() {
        if (!client.connected()) {
            while (!client.connected()) {
                client.connect("ESP8266Client");
                client.subscribe("test/test/baum");
                delay(100);
            }
        }
        client.loop();
    }
    void callback(char* topic, byte* payload, unsigned int length) {
        String msg;
        for (byte i = 0; i < length; i++) {
            char tmp = char(payload[i]);
            msg += tmp;
        }
        Serial.println(msg);
    }
    
    

  • Hallo @Dr-Wolle und damit natürlich auch ein herzliches Willkommen von mir. 😄

    Hast du denn schon mal ein OLED angesteuert?
    Denn so oder so solltest du die beiden Sketche einfach kombinieren können.

    Hier habe ich ein Codeschnipsel gefunden von draeger-it.blog

    #include <SPI.h>
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    
    #define OLED_RESET 0  // GPIO0
    
    Adafruit_SSD1306 display(OLED_RESET);
    
    String name1 = "Stefan";
    String name2 = "Anna";
    
    void setup()   {
      //initialisieren mit der I2C Adresse 0x3C für das 64 x 48 Pixel große Display.
      display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
      //display starten
      display.display();
      //kleine Pause von 2 sek.
      //Das Display und die Bibliothek startet, auf dem Display erscheint arda.....
      delay(2000);
      //Alle Zeichen auf dem Display löschen.
      display.clearDisplay(); 
      
      //Textgröße auf 1 (das kleinste) setzen
      display.setTextSize(1);
      //Textfarbe weiß
      display.setTextColor(WHITE);
    
      display.setCursor(38,8);
      display.println(name1);
    
      display.setCursor(70,25);
      display.println(name2);
    
      display.display();
    }
    
    
    void loop(){
    
    }
    

    Ich habe es nicht getestet und kein OLED zum Prüfen aber er verwendet dort ebenfalls Variablen.

    String name1 = "Stefan";
    

    Das könntest du vermutlich mit deiner Variable Serial.println(msg); ersetzen.

    display.setCursor(38,8);
    display.println(msg);
    

    Die Position des Cursors musst du aber dann sehr wahrscheinlich anpassen. Aber vielleicht testest du den Codeschnipsel auch besser erstmal ohne dein MQTT-Setup.

    Aber da dein MQTT-Setup ohnehin schon funktioniert würde ich deine Frage eher zusätzlich noch unter der Kategorie #ESP8266 und #OLED laufen lassen. Nicht unter MQTT. 🙂

    Viel Erfolg! Wenn es was neues gibt gerne mit Rückmeldung.

    Liebe Grüße


  • @dieterh Hey, besten Dank für den Tipp.
    Leider zeigt das Display aber nicht die Werte aus msg im SerielMonitor. Ich zeige mal den aktuellen Code. Vielleicht hat jemand noch eine Idee? VG und Besten Dank Dirk

    
    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_GFX.h>
    
    #define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
    #define SCREEN_WIDTH 128 // OLED display Breite, in pixels
    #define SCREEN_HEIGHT 64 // OLED display Höhe, in pixels
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
    
    const char* SSID = "ssid";
    const char* PSK = "psw";
    const char* MQTT_BROKER = "ip";
    
    WiFiClient espClient;
    PubSubClient client(espClient);
    
    String msg = "";
    //float msg = 0.0;
    
    // ###########################################
    
    void setup() {
        Serial.begin(115200);
        setup_wifi();
        client.setServer(MQTT_BROKER, 1883);
        client.setCallback(callback);
    
        display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // I2C address = 0x3C
        delay(1000);
        display.clearDisplay();
        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(0, 0);
        display.print("Lueften?");
        display.setCursor(0,30);
        display.println(msg);
        display.display(); 
    }
    
    void setup_wifi() {
        WiFi.begin(SSID, PSK);
        while (WiFi.status() != WL_CONNECTED) {
            delay(100);
        }
    
        Serial.println(WiFi.localIP());
    }
    
    void updateDisplay(){
      display.setTextSize(2); 
      display.setTextColor(WHITE);
      display.setCursor(0,30);
      display.println(msg);
      display.display(); 
    }
    
    // ##########################################
    
    void loop() {
        if (!client.connected()) {
            while (!client.connected()) {
                client.connect("Klima");
                client.subscribe("Klima/Kueche/Schimmel");
                delay(100);
            }
        }
    
        client.loop();
    }
    
    void callback(char* topic, byte* payload, unsigned int length) {
        String msg;
        for (byte i = 0; i < length; i++) {
            char tmp = char(payload[i]);
            msg += tmp;
        }
    
        Serial.println(msg);
        updateDisplay();
    }
    
    
  • ESP8266

    Lief das Display denn ohne MQTT? Passt die Verdrahtung etc?
    Zeigt er display.print("Lueften?"); an?


    Also ich denke es liegt daran:

    String msg = "";
    

    wird zu:

    String msg;
    

    Und dann den MQTT-Part anpassen:

    void callback(char* topic, byte* payload, unsigned int length) {
        // Die Variable leeren
        msg = "";
        for (byte i = 0; i < length; i++) {
            char tmp = char(payload[i]);
            // Wird in die Globale-Variable `msg` geschrieben.
            msg += tmp;
        }
     
        Serial.println(msg);
        updateDisplay();
    }
    

  • Guten Morgen Cooper,
    Juhuuuuuuu … ALER … Besten Dank für Eure Hilfe.
    Anbei für den der es nachbauen möchte hier der Code:
    Ändern muss man nur die Zugangsdaten und das Topic was man sehen möchte …
    Cooles Forum …
    Bis bald mal wieder hier bei Euch Gruß Dirk

    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_GFX.h>
    #include <Fonts/FreeSansBold9pt7b.h>
    
    #define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
    #define SCREEN_WIDTH 128 // OLED display width, in pixels
    #define SCREEN_HEIGHT 64 // OLED display height, in pixels
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
    
    const char* SSID = "ssid";
    const char* PSK = "psw";
    const char* MQTT_BROKER = "ip";
    
    String msg;
    
    WiFiClient espClient;
    PubSubClient client(espClient);
     
    void setup() {
        Serial.begin(115200);
        setup_wifi();
        client.setServer(MQTT_BROKER, 1883);
        client.setCallback(callback);
    
         // Display
         display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // I2C address = 0x3C
         delay(1000);
         display.clearDisplay();
         display.display();
         display.setTextSize(1);  // Schriftgröße 1-6
         display.setTextColor(WHITE); // WHITE = volle Farbe; BLACK = keine Farbe
         display.setCursor(5, 14); // (x, y) oben links (0,0) unten rechts (63,127)
         display.setFont(&FreeSansBold9pt7b);
         display.print("Kueche");
         display.drawLine(0, 34, 127, 18, WHITE);
         display.setCursor(33, 55);
         display.print("Lueften");
         display.display();
         delay(7000);
         display.clearDisplay();
         display.display();
    
    }
    
    
    void setup_wifi() {
        WiFi.begin(SSID, PSK);
     
        while (WiFi.status() != WL_CONNECTED) {
            delay(100);
        }
        
        Serial.println(WiFi.localIP());
    }
    
    //Display
    void updateDisplay() {
      display.clearDisplay();
      display.setTextSize(1);  // Schriftgröße 1-6
      display.setTextColor(WHITE); // WHITE = volle Farbe; BLACK = keine Farbe
      display.setCursor(5, 14); // (x, y) oben links (0,0) unten rechts (63,127)
      display.setFont(&FreeSansBold9pt7b);
      display.print("Lueften ?");
      display.drawLine(0, 18, 127, 18, WHITE);
      display.setCursor(33, 51);
      display.println(msg);
      display.display();
    }
    
    void loop() {
        if (!client.connected()) {
            while (!client.connected()) {
                client.connect("Sudhaus");
                client.subscribe("Sudhaus/kesseltemp");
                delay(100);
            }
        }
        client.loop();
    }
    void callback(char* topic, byte* payload, unsigned int length) {
      
        // Die Variable leeren
        msg = "";
      
        for (byte i = 0; i < length; i++) {
            char tmp = char(payload[i]);
    
            // Wird in die Globale-Variable `msg` geschrieben.
            msg += tmp;
        }
    
        Serial.println(msg);
        updateDisplay();
    }
    

  • Hey Cooper,
    ich habe jetzt probiert ob man andere Topics auf dem Oled in verschiedenen Zeilen anzeigen kann, leider scheitere ich da wahrscheinlich an der callback Schleife.
    Ich poste hier mal den erweiterten Code (OTA ist auch schon drin und funktioniert) ich hoffe ihr könnt mir einen Tip geben…
    Beste Grüße Dirk

    
    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    
    #include <WiFiUdp.h>
    #include <ArduinoOTA.h>
    
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_GFX.h>
    #include <Fonts/FreeSansBold9pt7b.h>
    
    #define ESPHostname "OLED_Kueche"
    
    #define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
    #define SCREEN_WIDTH 128 // OLED display width, in pixels
    #define SCREEN_HEIGHT 64 // OLED display height, in pixels
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
    
    const char* SSID = "ssid";
    const char* PSK = "psw";
    const char* MQTT_BROKER = "ip";
    
    String msg1;
    String msg2;
    
    WiFiClient espClient;
    PubSubClient client(espClient);
    
    void setup() {
      Serial.begin(115200);
      setup_wifi();
    
      ArduinoOTA.setHostname(ESPHostname);
      // ArduinoOTA.setPassword("admin");
      ArduinoOTA.begin();
    
      client.setServer(MQTT_BROKER, 1883);
      client.setCallback(callback);
    
      // Display
      display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // I2C address = 0x3C
      delay(1000);
      display.clearDisplay();
      display.display();
      display.setTextSize(1);  // Schriftgröße 1-6
      display.setTextColor(WHITE); // WHITE = volle Farbe; BLACK = keine Farbe
      display.setCursor(0, 6); // (x, y) oben links (0,0) unten rechts (63,127)
      display.setFont(&FreeSansBold9pt7b);
      display.print("Kueche");
      display.drawLine(0, 34, 127, 18, WHITE);
      display.setCursor(33, 55);
      display.print("Lueften");
      display.display();
      delay(3000);
      display.clearDisplay();
      display.display();
    
    }
    
    
    void setup_wifi() {
      WiFi.begin(SSID, PSK);
    
      while (WiFi.status() != WL_CONNECTED) {
        delay(100);
      }
    
      Serial.println(WiFi.localIP());
    }
    
    //Display
    void updateDisplay() {
      display.clearDisplay();
      display.setTextSize(1);  // Schriftgröße 1-6
      display.setTextColor(WHITE); // WHITE = volle Farbe; BLACK = keine Farbe
      display.setCursor(0, 14); // (x, y) oben links (0,0) unten rechts (63,127)
      display.setFont(&FreeSansBold9pt7b);
      display.print("Kueche:");
      display.setCursor(0, 28);
      display.println(msg1);
      display.setCursor(0, 42);
      display.println(msg2);
      display.display();
    }
    
    void loop() {
      if (!client.connected()) {
        while (!client.connected()) {
          client.connect(ESPHostname);
          client.subscribe("Klima/Kueche/#");
          delay(200);
        }
      }
      client.loop();
    
      ArduinoOTA.handle();
    }
    void callback(char* topic, byte* payload, unsigned int length) {
    
      // Die Variable leeren
      msg1 = "";
      msg2 = "";
    
      for (byte i = 0; i < length; i++) {
        char tmp1 = char(payload[i]);
        char tmp2 = char(payload[i]);
        delay(500);
        
        // Wird in die Globale-Variable `msg` geschrieben.
        msg1 += tmp1;
        msg2 += tmp2;
      }
    
      Serial.println(msg1);
      Serial.println(msg2);
      updateDisplay();
    }
    
    
  • ESP8266

    @dr-wolle

    Hab noch nie richtig was mit MQTT gemacht…

    void callback(char* topic, byte* payload, unsigned int length) {
     
      // Die Variable leeren
      msg1 = "";
      msg2 = "";
     
      for (byte i = 0; i < length; i++) {
        char tmp1 = char(payload[i]);
        char tmp2 = char(payload[i]);
        delay(500);
        
        // Wird in die Globale-Variable `msg` geschrieben.
        msg1 += tmp1;
        msg2 += tmp2;
      }
     
      Serial.println(msg1);
      Serial.println(msg2);
      updateDisplay();
    }
    

    aber was gibt dir denn char* topic innerhalb der callback Funktion aus? Vielleicht kannst du darüber unterscheiden, ob es von Topic A oder B kommt und den Code wie gewohnt verwenden nur mit einer weiteren Abfrage für den Topic?

    Gruß


  • @cooper besten Dank… werde ich auch mal testen.
    Habe hier was zum Thema Multiple MQTT Topics mit PubSubClient gefunden. Hier gibt es einen zusätzlichen Befehl strcmp() - heißt so viel wie „String compare“. Das muss ich jetzt nur noch verstehen… uffff
    von James Lewis

    VG Dirk

  • ESP8266

    Sieht an sich ja nicht wirklich kompliziert aus.

    Vermute aber bei der Lösung musst du deinen Placeholder streichen. Weil das subben auf ne Wildcard wir ja nicht als Wildcard zurückgegeben oder?

    Also ein sub auf Klima/Kueche/# returned ja nicht Klima/Kueche/# sondern z.B Klima/Kueche/Zimmer, Klima/Kueche/Aussen, … oder hab ich da was falsch verstanden?

    Dementsprechend müsstest du das dann comparen, und nicht die Wildcard.

    if (strcmp(topic,"Klima/Kueche/Zimmer")==0) {
        // sub auf Klima Küche Zimmer
    } 
    

  • @cooper … cool wir hatten beide den selben Gedanken lieben Dank … soweit zeigt er es richtig an. Jetzt löscht er das leider noch aber das liegt am msg = „“ muss ich an die richtige Stelle setzen … beste Grüße melde mich


  • Hat es geklappt @Dr-Wolle?

    Ich denke so könnte es auch funktionieren:

    String msg1; // Für Topic A
    String msg2; // Für Topic B
    // ....
    
    void callback(char* topic, byte* payload, unsigned int length) {
     
      String buffer;
     
      for (byte i = 0; i < length; i++) {
        char tmp = char(payload[i]);
        delay(500);
        buffer += tmp;
      }
     
      // Buffer enthält alle Messages von allen Topics die Subscribed wurden
      Serial.println(buffer);
    
     // Jetzt abfragen, zu welchem Topic der Payload gehört
     // und die entsprechende Variable überschreiben
    
      if (strcmp(topic,"Klima/Kueche/Zimmer")==0) {
          // Message kommt von Klima Kueche Zimmer
         // also msg1 wird überschrieben
         msg1 = buffer;
      }
    
      if (strcmp(topic,"Klima/Kueche/Aussen")==0) {
          // Message kommt von Klima Kueche Außen
         // also msg2 wird überschrieben
         msg2 = buffer;
      } 
    
     // ... und alle weiteren Topics
    
      // Dann das Display wie gewohnt updaten, da nur die erhaltenen msg überschrieben wurden
      updateDisplay();
    }
    

    Nicht getestet aber sollte so auch klappen. 👍
    Mann kann ja den Topic auch erst mit strcmp() vergleichen, wenn man die Message schon zwischengespeichert hat.
    Und erst dann wird verglichen und die entsprechende Variable überschrieben.

    Liebe Grüße


  • @dieterh lieben Dank für den Vorschlag. Ich komme leider erst heute Abend zum Testen. Melde mich dann. Beste Grüße Dirk


  • @dieterh … Guten Abend … es hat perfekt funktioniert . Echt klasse und lieben Dank für Deine klasse ergänzende Beschreibung. In diesem kleinen Projekt hab ich echt viel gelernt. So das man jetzt alle Möglichkeiten hat mit RedMatic/NideRed über MQTT sich alles anzeigen lassen kann was das Smarte Herz begehrt.
    Lieben Dank bis bald Dirk

Ähnliche Themen

  • 35
  • 5
  • 7
  • 1
  • 4