Kostengünstiges LED Display was mit Daten von extern ( MQTT ) gespeist werden kann.

Hallo und willkommen in meinem neuen Beitrag.

Die besten Idee kommen spontan oder durch einen Wunsch.
In diesem Fall war es mein Sohn, der mich inspirierte dies so umzusetzen.

Was benötigen wir?

1 x Wemos D1 mini ( nicht zusammen gelötet ! ) 
1 x MAX2719 Display
1 x 3D Drucker ( Oder drucken lassen )
Solltet Ihr keinen Drucker haben, so schreibt mir einfach eine E-Mail:
p.vens-cappell(at)online.de
1 x USB Kabel 
1 x USB Netzteil 
1 x Arduino IDE 

Heißkleber, zum fixieren des Displays!

Bilder mit Erklärung :

Sobald wir die Matrix ausgepackt haben, entfernen wir erstmal die Folie.
Anschließend machen wir eine Pass probe, super, es passt 🙂
Bitte richtig einlegen, die Pfeile müssen nach rechts weggehen ( Im Gehäuse ist links, wo der Wemos platz nimmt! )

Wir benötigen 5 Lötpunkte:

// LED Matrix Pin -> Wemos D1 mini


// Vcc -> 3v / 5v
// Gnd -> Gnd
// DIN -> D7
// CS -> D8
// CLK -> D5

Nach dem löten trennen wir sauber die Überstände ab, andernfalls passt der
Wemos D1 mini nicht hinein!

Der Platz ist knapp bemessen, daher dürfen die Jumperkabel am Anschluss nur 1,2 cm messen!

Wir testen den Aufbau einmal und öffnen die Arduino IDE.

Folgende Bibliotheken werden benötigt:

#include <ESP8266WebServer.h>
#include <ESP8266WiFi.h>
#include <SPI.h>
Adafruit-GFX-Library-master
#include <Max72xxPanel.h>
#include <time.h>
#include <PubSubClient.h>

Wie man Bibliotheken einbindet ist hier:
https://www.heise.de/make/artikel/Arduino-Bibliotheken-einbinden-und-verwalten-3643786.html
gut erklärt!

Nach dem Installieren müssen wir das Board ( Wemos D1 mini ) noch über den Boardverwalter installieren.

Dazu gehen wir in die Arduino IDE und klicken auf:

Anschließend suchen wir nach : Wemos

Und installieren die neuste Version.
Beim Flashen müssen wir nun:

Wemos D1 R“ und mini

auswählen, den richtige Port wählen und anschließend “ Hochladen “

 

Folgende STL Datein müssen gedruckt werden:

Alle Druckteile müssen liegend gedruckt werden, es wird kein Support benötigt!
Bei dem Deckel kann man ein wenig Zeit einsparen ( ca 1/3 der Zeit ) wenn man die obere und untere Deckschicht auf 4 stellt!
Die Qualität leidet hierbei nicht.

Die Zip Datei beinhaltet alle drei Druckdateien.
STL_LED_Display

Wir laden uns nun das Script in die Arduino IDE:

 

//#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266WiFi.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <time.h>
#include <PubSubClient.h>
WiFiClient espClient; 
PubSubClient client(espClient); 

bool starte = false;
char tmp[50];
String Text = ""; // Variable Text wird angelegt.
char ssid[] = "FRITZ!Box 7362 SL ( Beispiel! )";  //  SSID (name)
char pass[] = "Euer Wlan SSID Passwort";       // password
const char* mqtt_server = "192.168.x.x"; //Broker IP Address
const char* mqttUser = "Benutzer"; // Broker Name
const char* mqttPassword = "Passwort"; // Broker Passwort

void connect_to_MQTT() {
 client.setServer(mqtt_server, 1890);//MQTT Server, - Port
 client.setCallback(callback); // aktiviert das zuhören 
 // Solltet Ihr kein Benutzer/Passwort haben so müssen folgende Zeilen entfernt werden: 
 // (client.connect("display" , mqttUser, mqttPassword))
 // und mit folgender getauscht werden: 
 // if (client.connect("display");

  if (client.connect("display" , mqttUser, mqttPassword)) {
    Serial.println("Verbinde zum MQTT Server");
  } else {
    Serial.println("zu MQTT Server nicht verbunden ");
    if (!client.connect("display" , mqttUser, mqttPassword)) {
            Serial.print("Fehlgeschlagen, state=");
            Serial.print(client.state());
            Serial.println(" Versuch in 5 Sekunden nochmal");
            delay(5000);
        }
  }
  client.subscribe("display1/text");
  // Es könne weitere Tropics hinzugefügt werden! 
  // Alternativ steht folgende Alternative zur Verfügung: 
  //client.subscribe("tropic/#"); --> es werden dann alle tropics abonniert ( Beispiel: Wohnzimmer/# ) Es werden alle Nachrichten aus Wohnzimmer empfangen! 

  
  //client.subscribe("display1/woche");
  //client.subscribe("display1/verbraucht");
  //client.subscribe("display1/internet");
  //client.subscribe("display1/zimmertemperatur");
}
        
int pinCS = D8; // CS PIN
int numberOfHorizontalDisplays = 4; //Display Anzahl
int numberOfVerticalDisplays   = 1; // Diplay höhen Anzahl
char time_value[20];
// LED Matrix Pin -> ESP8266 Pin
// Vcc            -> 3v / 5v
// Gnd            -> Gnd 
// DIN            -> D7 
// CS             -> D8  
// CLK            -> D5

Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

int wait = 95; // In millis -> Scrollgeschwindigkeit! 
int spacer = 1;
int width  = 5 + spacer; // Die Panals haben 5 Pixel + Leerzeichen

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  
  connect_to_MQTT(); 
  
  configTime(1 * 3600, 0, "pool.ntp.org", "time.nist.gov"); // Zeitserver
  setenv("TZ", "GMT0BST,M3.5.0/01,M10.5.0/02",1);
  matrix.setIntensity(5); // Lichtstärke einstellen! Bis 8 kann man sicherlich über den Wemos D1 mini ansteuern, alles darüber sollte das Netzteil aufgeteilt werden und direkt mit Strom versorgt werden!! 
  matrix.setRotation(0, 1);    
  matrix.setRotation(1, 1);    
  matrix.setRotation(2, 1);    
  matrix.setRotation(3, 1);    
}



void loop() {
  
  matrix.fillScreen(LOW);
  time_t now = time(nullptr);
  String time = String(ctime(&now));
  time.trim();
  Serial.println(time);
  time.substring(11,19).toCharArray(time_value, 10); 
  matrix.drawChar(2,0, time_value[0], HIGH,LOW,1); // H
  matrix.drawChar(8,0, time_value[1], HIGH,LOW,1); // HH
  matrix.drawChar(14,0,time_value[2], HIGH,LOW,1); // HH:
  matrix.drawChar(20,0,time_value[3], HIGH,LOW,1); // HH:M
  matrix.drawChar(26,0,time_value[4], HIGH,LOW,1); // HH:MM
  matrix.write(); // Bitmap an das Display senden.
  
  delay(2000);
  if (!client.connected()) {
    Serial.println("Keine Verbindung zum MQTT Server");
    connect_to_MQTT();
  }
  client.loop();
}

void display_message(String message){
   for ( int i = 0 ; i < width * message.length() + matrix.width() - spacer; i++ ) {
    //matrix.fillScreen(LOW);
    int letter = i / width;
    int x = (matrix.width() - 1) - i % width;
    int y = (matrix.height() - 8) / 2; // Zentriert die Ausgabe.
    while ( x + width - spacer >= 0 && letter >= 0 ) {
      if ( letter < message.length() ) {
        matrix.drawChar(x, y, message[letter], HIGH, LOW, 1); // HIGH LOW 
      }
      letter--;
      x -= width;
    }
    matrix.write(); // Bitmap an das Display senden.
    delay(wait/2);
  }
}



void callback(char* topic, byte* payload, unsigned int length) {
 // Zähler
 int i = 0;
 // Hilfsvariablen für die Convertierung der Nachricht in ein String
 char message_buff[100];
 
 Serial.println("Message arrived: topic: " + String(topic));
 Serial.println("Length: " + String(length,DEC));
 
 // Kopieren der Nachricht und erstellen eines Bytes mit abschließender \0
 for(i=0; i<length; i++) {
 message_buff[i] = payload[i];
 }
 message_buff[i] = '\0';
 
 // Konvertierung der nachricht in ein String
 String msgString = String(message_buff);
 Serial.println("Payload: " + msgString);
 if (strcmp(topic,"display1/text/set")==0){
    Text = msgString;
  display_message(Text);
  display_message(Text);
  }
  if (strcmp(topic,"display1/text")==0){
    Text = msgString;
  display_message(Text);
  display_message(Text);
  }
  /*
  Zum freimachen, das "/*" und am ende "* /" entfernen!
    

  ################################################ 
  ## Tropic filtern und etwas bestimmtes machen!#
  ################################################
  
  if (strcmp(topic,"display1/verbraucht")==0){
    Text = "Internet verbraucht: " + msgString + "Std.";
  display_message(Text);
  display_message(Text);
  }
  if (strcmp(topic,"display1/woche")==0){
    Text = "Woche Gesamt: " + msgString + "Std.";
  display_message(Text);
  display_message(Text);
  }
  if (strcmp(topic,"display1/zimmertemperatur")==0){
    Text = msgString + " Grad";
    display_message(Text);
    display_message(Text);
    long rssi = WiFi.RSSI();
    itoa(rssi,tmp,10);
    client.publish("display1/rssi",tmp);
  //display_message(Text);
  }
   
*/
 
}

BITTE, einmal durchlesen, und die Kommentare beachten!
Ändert die erforderlichen Zeilen auf euer System ab!

ACHTUNG, es wird empfohlen VCC vor dem Flashen abzuziehen!
Das Display schaltet sonst alle LED auf HIGH und  belastet den Wemos zu stark!

Nach dem Flashen meldet sich der Wemos an eurem Broker an und teilt seine Tropics mit ( legt diese auch selbstständig an )


Wir können jetzt mittels unseren Broker Nachrichten an das Display senden.
( Datenpunkt im Originalscript: text )

Fast geschafft 🙂 

Jetzt benötigen wir Heißkleber, wir fixieren dass Display mit 4 Punkten , zwei oben, zwei unten.
Die Füße habe ich auch mit Heißkleber fixiert!
So bleibt alles an seinem Platz.

Den Deckel, drücken wir mit bedacht in das Gehäuse!
Man merkt ob alles passt! oder nicht!
Nicht mit gewallt, es würde keinen Sinn machen, da man mehr beschädigt als einem Lieb ist.. 😉

UPDATE:

Ich habe ein kleines Video und 2 Bilder von einem User bekommen der das ganze in einen Hevo Evolution eingebaut hat:

 

Vielen Dank für das einsenden 🙂


Im Zweiten Teil behandel ich das Automatisieren bestimmter Nachrichten mittels ioBroker.

Zum Beispiel:

bei Temperatur Änderungen
Zeiten messen
Eben kleine Beispiel-Scripte.
Eventuell die integration von Telegram + text to command Adapter.

 

*
Alle meine Links führen zu Amazon.
Durch den Kauf bei Amazon bekomme ich eine kleine Provision, es entstehen keine weiteren Kosten wenn Ihr über diesen Link kauft!

8 Replies to “LED Display ( MAX 7219 ) mit MQTT Rückkanal ( ioBroker )”

    1. Leider nein.
      Es lassen sich nicht alle Buchstaben und Sonderzeichen auf einer Siebensegment-Anzeige darstellen.

      Was ähnlich aussieht, ist dass Zeichen “ ` “ Es suggeriert durch seine Position und Anordnung ein °

      Siehe Bild:

      Display

  1. Hallo
    Sehr guter Ansatz den ich auch nachbaue. Danke für deine Bemühungen.
    Da du fast alles gut beschreibst auch im Skript, konnte ich mich einfach reindenken.
    Tut auch was es soll.
    Nur eines von mir, die Uhrzeit passt nicht und hängt wohl an der Winterzeit.
    Muss dies im abholen von der Serverzeit geändert werden oder ist das irgendwo beim Berechnen aus der time.h.
    Ich würde gern noch das Datum mit reinpacken hast du da einen Ansatz für mich.
    Gruß
    Ralf

  2. Danke für Deinen Kommentar,

    ich habe dieses Problem jetzt nicht wirklich gehabt, versuche mal bitte folgende Zeile :

    configTime(1 * 3600, 0, „pool.ntp.org“, „time.nist.gov“); // Zeitserver
    setenv(„TZ“, „GMT0BST,M3.5.0/01,M10.5.0/02“,1);

    gegen

    configTime(1 * 3600, 0, „de.pool.ntp.org“, „time.nist.gov“); // Zeitserver
    setenv(„TZ“, „CET-1CEST,M3.5.0,M10.5.0/3“,1); // BERLIN, Amsterdam

    zu tauschen.

    Datum wird auch vom Zeitserver geholt, bin gerade nur etwas kurz angebunden, ich versuche es zeitnah im „Code“ zur Verfügung zu stellen.

  3. Guten Tag,
    habe alles nach Anleitung zusammengebaut und Scetch geladen,
    Datenpunkt in ioBroker ist da kann ich aber nicht steuern, an Display ändert sich auch nichts, nur die Uhr Läuft
    in Serielle Monitor sieht gut aus, Zeit wird aktualisiert und Text was ich in Datenpunkt schreibe sehe ich auch
    aber an Display nicht.
    was mache ich falsch?
    LG Andreas.

    1. Hallo Andreas,

      entschuldige die verzögerte Antwort.

      Versuche in dem Eltern-Objekt einen Text reinzuschreiben.
      Ein Bild sende ich später nach.

      Grüße

  4. Hallo,
    es funktioniert soweit, nur die Uhr hat die Winterzeit, wo kann ich das umstellen.
    Das die Sekunden auch angezeigt werden habe ich hinbekommen,
    aber ich bekomme sonst nichts angezeigt, im Monitor wird alles angezeigt,
    aber leider nicht auf den Matrix Display.
    Wo bitte liegt der Fehler, im serieller Monitor funktioniert alles ?

    1. Hallo Dirk,

      die Zeile „configTime(1 * 3600, 0, „pool.ntp.org“, „time.nist.gov“);“ im Code muss zu
      „configTime(2 * 3600, 0, „pool.ntp.org“, „time.nist.gov“);“

      Die Standard UTC Zeit ist 0 ( Heute den 18.08.2023 = 19:14 Uhr )
      + 1 = 20:14 ( MEZ )
      + 2 = 21:14 ( MEZ + 1 )

      Man könnte jetzt im IoBroker eine Variable hinterlegen die dann bei Bedarf geändert wird.

      Wieso er auf dem Display nichts anzeigt, ist erst einmal komisch.
      Das Array[0] – [4] müsstest Du Dir mal im SerialMonitor mal ansehen. Wenn das Array größer geworden ist, muss das Array auch erweitert werden.

      Kannst Du mir mal den Code an:

      p.vens-cappell@online.de

      senden?

      Kann Dir nichts versprechen, ich kann es mir aber gerne mal ansehen.

      Grüße
      Pascal

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.