ESP32 E-Paper 2.9" Display MQTT Daten von ESP01 (Tasmota) anzeigen

Hi Leute,
ich bin absoluter Neuling in sachen Arduino, wollte es aber mit einem E-Paper Display mal ausprobieren.
Ich habe mir ein E-Paper Display 2.9" WeAct gekauft um eine Überwachung von einem Akku der an einem ESP01 mit Tasmota und Solar läuft die aktuelle Spannung über MQTT anzeigen zu lassen.

Hardware:

ESP01 mit Tasmota 14.0

ESP32 DEVKIT V4

WeAct Display 2.9"

Beispiele wie "Hello World" funktioniert.
Ich habe dann einen Sketch im Netz gefunden "mqqt _epaper" mit dem ich es hinbekommen habe das die Ausgabe im Seriellen Monitor vorhanden ist.

Sketch

// PartialUpdateTest : example for Waveshare 1.54", 2.31" and 2.9" e-Paper and the same e-papers from Dalian Good Display Inc.
//
// Created by Jean-Marc Zingg based on demo code from Good Display for GDEP015OC1.
//
// The e-paper displays are available from:
//
// https://www.aliexpress.com/store/product/Wholesale-1-54inch-E-Ink-display-module-with-embedded-controller-200x200-Communicate-via-SPI-interface-Supports/216233_32824535312.html
//
// http://www.buy-lcd.com/index.php?route=product/product&path=2897_8363&product_id=35120
// or https://www.aliexpress.com/store/product/E001-1-54-inch-partial-refresh-Small-size-dot-matrix-e-paper-display/600281_32815089163.html
//

// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
// Good Dispay ePaper for Arduino : https://forum.arduino.cc/index.php?topic=436411.0

// mapping from Waveshare 2.9inch e-Paper to Wemos D1 mini
// BUSY -> D2, RST -> D4, DC -> D3, CS -> D8, CLK -> D5, DIN -> D7, GND -> GND, 3.3V -> 3.3V

// mapping example for AVR, UNO, NANO etc.
// BUSY -> 7, RST -> 9, DC -> 8, C S-> 10, CLK -> 13, DIN -> 11

// include library, include base class, make path known
#include <GxEPD.h>

// select the display class to use, only one

//#include <GxGDEW042T2/GxGDEW042T2.h>      // 4.2" b/w
//#include <GxGDEH0154D67/GxGDEH0154D67.h>    // 1.54" b/w
#include <GxDEPG0290BS/GxDEPG0290BS.h>        // 2.9" b/w WE
//#include <ESP8266WiFi.h>
#include <WiFi.h>
#include <ArduinoOTA.h>
#include <PubSubClient.h>

#ifndef STASSID
#define STASSID "Sxxxxx"
#define STAPSK  "9xxxxxxxxxx"
#endif

const char* ssid = STASSID;
const char* password = STAPSK;

char* mqtt_client_id = "Solar6";
const char* mqtt_server = "192.168.xxx.xxx";
const int mqtt_port = 1883;
const char* mqtt_user = "Sxxxxxxx";
const char* mqtt_password = "Jxxxxxx";

WiFiClient espClient;
PubSubClient mqttClient(espClient);

#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>

// FreeFonts from Adafruit_GFX
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>

// for SPI pin definitions see e.g.:
// C:\Users\xxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.2\variants\generic\common.h

  //GxIO_Class io(SPI, /*CS=D0*/ 16, /*DC=D3*/ 0, /*RST=D4*/ 2); // arbitrary selection of D3(=0), D4(=2), selected for default of GxEPD_Class
  //GxEPD_Class display(io /*RST=D4*/ /*BUSY=D2*/); // default selection of D4(=2), D2(=4)
GxIO_Class io(SPI, SS, 22, 21);
GxEPD_Class display(io, 16, 4);

void setup(void)
{
  Serial.begin(115200);

  // Per WLAN mit dem Netzwerk verbinden
  Serial.print("Verbinden mit ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  ///////////////////////////////////////////
  // Anfang Update über Wlan
  ///////////////////////////////////////////

  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_FS
      type = "filesystem";
    }

    // NOTE: if updating FS this would be the place to unmount FS using FS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) {
      Serial.println("Auth Failed");
    } else if (error == OTA_BEGIN_ERROR) {
      Serial.println("Begin Failed");
    } else if (error == OTA_CONNECT_ERROR) {
      Serial.println("Connect Failed");
    } else if (error == OTA_RECEIVE_ERROR) {
      Serial.println("Receive Failed");
    } else if (error == OTA_END_ERROR) {
      Serial.println("End Failed");
    }
  });
  ArduinoOTA.begin();

  ///////////////////////////////////////////
  // Ende Update über Wlan
  ///////////////////////////////////////////

  // Die IP vom Webserver auf dem seriellen Monitor ausgeben
  Serial.println("");
  Serial.println("WLAN verbunden.");
  Serial.println("IP Adresse: ");
  Serial.println(WiFi.localIP());

  // MQTT Brocker
  // Mit ioBroker Mqtt verbinden
  mqttClient.setServer(mqtt_server, mqtt_port);//MQTT Server, - Port
  mqttClient.setCallback(callback);
  
  Serial.println();
  Serial.println("setup");
  //display.init(115200); // enable diagnostic output on Serial
  display.init(); // disable diagnostic output on Serial
  Serial.println("setup done");
  display.setTextColor(GxEPD_BLACK);
  display.setRotation(1);
  // draw background
  display.setFont(&FreeMonoBold12pt7b);
  display.update();
  display.fillScreen(GxEPD_WHITE);

}

void loop()
{


  ArduinoOTA.handle();
  ArduinoOTA.setHostname("SOLAR6");
  
  // MQTT Broker
  mqttClient.loop();
  if (!mqttClient.connected()) {
    reconnectToMQTT();
  }


}

// MQTT Funktion
// *************
void reconnectToMQTT() {

  if (mqttClient.connect(mqtt_client_id , mqtt_user, mqtt_password)) {
    Serial.println("Per MQTT mit openhab verbunden");

mqttClient.subscribe("tele/Solar6/DEEPSLEEP");
mqttClient.subscribe("tele/Solar6/LWT");
mqttClient.subscribe("tele/Solar6/SENSOR");
        
  } else {
    Serial.print("mqtt-Verbindung fehlgeschlagen ");
    Serial.print(mqttClient.state());
    Serial.println(" versuchen es in 5 Sekunden erneut");
    // Wait 5 seconds before retrying
    delay(5000);
  }
}



// MQTT Callback
void callback(char* topic, byte* payload, unsigned int length)
{

  payload[length] = '\0';
  String strTopic = String(topic);
  String strPayload = String((char * ) payload);

  Serial.print("Nachricht angekommen [");
  Serial.print(strTopic);
  Serial.print("----");
  Serial.print(strPayload);
  Serial.print("] ");
  Serial.println();
  

  if (strTopic == "tele/Solar6/SENSOR")
  {
  Serial.println(strPayload);
  uint16_t box_x = 10;
  uint16_t box_y = 15;
  uint16_t box_w = 200;//380;
  uint16_t box_h = 20;
  uint16_t cursor_y = box_y + 16;
  display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
  display.setCursor(box_x, cursor_y);
  display.print("Spannung "); display.setCursor(box_x + 180, cursor_y);   display.print(strPayload.toFloat()); display.print(" V");
  display.updateWindow(box_x, box_y, box_w, box_h, true);
    }


  if (strTopic == "tele/Solar6/DEEPSLEEP")
  {
  Serial.println(strPayload);
  uint16_t box_x = 10;
  uint16_t box_y = 50;
  uint16_t box_w = 200;//380;
  uint16_t box_h = 20;
  uint16_t cursor_y = box_y + 16;
  display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
  display.setCursor(box_x, cursor_y);
  display.print("Zeit "); display.setCursor(box_x + 180, cursor_y);   display.print(strPayload.toFloat()); display.print(" H");
  display.updateWindow(box_x, box_y, box_w, box_h, true);  
    }


  if (strTopic == "tele/Solar6/LWT")
  {
  Serial.println(strPayload);
  uint16_t box_x = 10;
  uint16_t box_y = 85;
  uint16_t box_w = 200;//380;
  uint16_t box_h = 20;
  uint16_t cursor_y = box_y + 16;
  display.fillRect(box_x, box_y, box_w, box_h, GxEPD_WHITE);
  display.setCursor(box_x, cursor_y);
  display.print("Status "); display.setCursor(box_x + 180, cursor_y);   display.print(strPayload.toFloat()); display.print(" S");
  display.updateWindow(box_x, box_y, box_w, box_h, true);  
    }

}

Ausgabe Serieller Monitor

Verbinden mit Sxxxxxxx
.....
WLAN verbunden.
IP Adresse:

192.168.xxx.xxx

setup
setup done
Per MQTT mit openhab verbunden
Nachricht angekommen [tele/Solar6/DEEPSLEEP----{"DeepSleep":{"Time":"2024-06-02T17:30:00","DeepSleep":1717348544,"Wakeup":1717349400}}] 
{"DeepSleep":{"Time":"2024-06-02T17:30:00","DeepSleep":1717348544,"Wakeup":1717349400}}
Nachricht angekommen [tele/Solar6/LWT----Online] 
Online
Nachricht angekommen [tele/Solar6/SENSOR----{"Time":"2024-06-02T17:23:04","ANALOG":{"Range":4184}}] 
{"Time":"2024-06-02T17:23:04","ANALOG":{"Range":4184}}

Nur weiß ich jetzt nicht wie und wo ich etwas in dem Sketch eingeben/einfügen muss um die Spannung (Range) auf dem Display angezeigt zu bekommen.
Der ESP01 geht im Moment in DeepSleep und wacht alle 15 Minuten auf um mir die Daten zu senden.

Ich hoffe ihr könnt mir helfen es zum laufen zu bekommen.

Danke

Gruß
Sven

Da ist mir jetzt allerdings nicht ganz klar, wozu du dann noch einen weiteren Controller brauchst, wenn du die Spannung des ESP01 per MQTT anzeigen willst.
Evtl. kannst du das noch etwas deutlicher beschreiben.

Hi,
ich habe vor den ESP01 draussen im Schuppen zu betreiben mit Batterie und Solar.
Den ESP32 wollte ich im Haus zur schnellen Kontrolle der Spannung des Akku's mit dem E-Paper Display hinstellen.
Später soll dann auch etwas geschaltet werden draussen, wobei ich dann den ESP01 gegen einen zb. Wemos austauschen werde.
Ich hoffe es hilft Dir.

Ich denke hier ist der Fehler verborgen, wie gesagt habe es so aus dem Netz übernommen und bekomme es nicht angepasst.

display.print(strPayload.toFloat()); display.print(" V");

Auf dem Display bekomme ich

Spannung
Zeit
Status

angezeigt ohne Werte

Ok, jetzt ist es klar.
Dein ESP01 überträgt per MQTT an den ESP32.
Da muss ich passen, bei MQTT fehlt mir die Erfahrung.

ok,
trotzdem danke

Wird das als Serial angezeigt?

Du meinst im Seriellen Monitor ?
Wenn ja, die Ausgabe vom Monitor steht im Anfangspost.

Ok dann schalte mall in der IDE alle Warnungen ein, vermute ist ein Wandlungfehler bei der Ausgabe.
Du kannst ja versuchen so was

float volt = strPayload.toFloat(); 
display.print(volt);

wo ich aber denke es kommt Fehler bei umsetzen

War alles Falsch, deshalb geändert :neutral_face:

Hi fony,
hat sich leider nichts geändert, Fehler kommen auch keine.

ich denke es muss hier das richtige Topic eingeben werden, leider weiß ich nicht wie man es eingeben muss.
Es kommt per mqtt

Nachricht angekommen [tele/Solar6/SENSOR----{"Time":"2024-06-03T19:59:24","ANALOG":{"Range":4023}}]

und ich benötige die Range. In OpenHab gebe ich unter "Incoming Value Transformations" folgendes ein "JSONPATH:$.ANALOG.Range" damit mir der Wert angezeigt wird.
Das muss man doch auch in Arduino unter Topic irgendwie eingeben können.

Leider habe ich noch nicht den richtigen Hinweis gefunden.

Formatierungsfehler werden in der Regel auch angezeigt.
Du musst aber auch die Einstellungen in der IDE entsprechend vorgenommen haben.

Was schreibt dir Serial.println(strPayload);?
Kommt ein wert, string oder irgend was?
oder ganzer Telegramm "Time":"2024-06-03T19:59:24","ANALOG":{"Range":4023}}]

Habe aber auch 0 Ahnung vom dem Telegramm und wie man den zerlegt

Wenn ein String, dann geht das doch auch mit strok.

Warte was der TO schreibt.
Wen sowas wie oben habe gezeigt müsste gehen.

Ich muss eh warten, da ich von MQTT kein Ahnung habe.

Bin im gleichem Club :wink:

Hier sieht man doch, dass es ein String ist.
Oder liege ich total falsch.

Hier kommt das alles und wen ich gut verstanden habe geht es um das 4184}}]
Somit ist die Zeile

display.print(strPayload.toFloat()); display.print(" V");

falsch, den strPavload gibt den ganzen String aus
"Time ....

Wo möglich wird zu viel gesendet, aber wie gesagt keine Ahnung

Richtig und das kann man doch mit "strok" trennen.
Man muss nur den richtigen Trenner auswählen, evtl. mehrfach aufteilen.

Da der TO hat keine Lust Info liefern, lasse das fallen.
Wes mich Wundert das man so alles senden muss, ok habe die Komponenten nicht, dann nehme an dass das hat sein Recht.