MQTT LED-Matrix 8x32
Funktionsweise des Codes
Dieser Code steuert eine LED-Matrix (basierend auf dem MAX7219-Treiber) mit einem ESP8266 (z. B. D1 Mini) und ermöglicht die Anzeige von Text, der über MQTT empfangen wird.
Hauptmerkmale:
WLAN-Verbindung:
- Der ESP8266 verbindet sich mit einem WLAN-Netzwerk basierend auf der angegebenen SSID und dem Passwort.
MQTT-Kommunikation:
- Über MQTT können Befehle an die LED-Matrix gesendet werden:
- Textanzeige: Der an das Topic
matrix_001/text
gesendete Text wird auf der Matrix angezeigt. - Scrollgeschwindigkeit: Die Geschwindigkeit der Anzeige kann über das Topic
matrix_001/speed
angepasst werden. - Anzahl der Wiederholungen: Die Anzahl der Textdurchläufe kann über das Topic
matrix_001/scrollcount
festgelegt werden.
- Textanzeige: Der an das Topic
- Über MQTT können Befehle an die LED-Matrix gesendet werden:
EEPROM-Speicherung:
- Die zuletzt eingestellten Werte für die Scrollgeschwindigkeit und die Anzahl der Wiederholungen werden im EEPROM gespeichert und beim Neustart automatisch wieder geladen.
Umlaut-Unterstützung:
- Deutsche Umlaute (
ä
,ö
,ü
, etc.) werden automatisch in ihre ASCII-Darstellungen (ae
,oe
,ue
, etc.) umgewandelt, um eine korrekte Anzeige zu gewährleisten.
- Deutsche Umlaute (
Automatische Leeranzeige:
- Nach Abschluss der angegebenen Anzahl an Wiederholungen wird ein Leerzeichen an das MQTT-Topic gesendet, um die Matrix zu löschen.
Vorteile:
- Flexibilität: Die Matrix kann einfach über MQTT aus der Ferne gesteuert werden.
- Energiesparend: Nach der Animation wird die Matrix geleert.
- Robust: Einstellungen bleiben auch nach einem Neustart erhalten.
#include
#include
#include // Für EEPROM-Speicher
#include
#include
#include
// --- WLAN-Konfiguration ---
const char* ssid = "WLAN SSID";
const char* password = "WLAN-Passwort";
// --- MQTT-Konfiguration ---
const char* mqtt_server = "192.168.x.xxx";
const char* mqtt_user = "MQTT-Name";
const char* mqtt_pass = "MQTT-Passwort";
const uint16_t mqtt_port = 1885;
const char* matrix_name = "matrix_001"; // Name der Matrix
String mqtt_topic_text = String(matrix_name) + "/text";
String mqtt_topic_speed = String(matrix_name) + "/speed";
String mqtt_topic_scrollcount = String(matrix_name) + "/scrollcount";
WiFiClient espClient;
PubSubClient client(espClient);
// --- LED-Matrix-Konfiguration ---
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN D8
MD_Parola display = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// --- Globale Variablen ---
uint8_t scrollSpeed = 150; // Standardgeschwindigkeit
uint8_t maxScrolls = 5; // Standardmäßige Anzahl der Wiederholungen
textEffect_t scrollEffect = PA_SCROLL_LEFT;
textPosition_t scrollAlign = PA_LEFT;
uint16_t scrollPause = 0; // Keine Pause zwischen den Scroll-Zyklen
String message = ""; // Zuletzt angezeigte Nachricht
bool displayActive = true; // Flag für die aktive Animation
uint8_t scrollCount = 0; // Zähler für das Scrollen
// --- EEPROM-Adressen ---
#define EEPROM_SCROLL_SPEED_ADDR 0
#define EEPROM_MAX_SCROLLS_ADDR 1
// Dynamischer MQTT-Client-Name
String client_name = "MatrixDisplayClient_" + String(ESP.getChipId());
// --- Funktion zum Speichern der Werte im EEPROM ---
void saveSettingsToEEPROM() {
EEPROM.begin(512);
EEPROM.write(EEPROM_SCROLL_SPEED_ADDR, scrollSpeed);
EEPROM.write(EEPROM_MAX_SCROLLS_ADDR, maxScrolls);
EEPROM.commit();
EEPROM.end();
Serial.println("Einstellungen im EEPROM gespeichert.");
}
// --- Funktion zum Laden der Werte aus dem EEPROM ---
void loadSettingsFromEEPROM() {
EEPROM.begin(512);
scrollSpeed = EEPROM.read(EEPROM_SCROLL_SPEED_ADDR);
maxScrolls = EEPROM.read(EEPROM_MAX_SCROLLS_ADDR);
EEPROM.end();
if (scrollSpeed < 10 || scrollSpeed > 150) scrollSpeed = 150;
if (maxScrolls > 100) maxScrolls = 5; // Annahme: maxScrolls > 100 ist ungültig
Serial.println("Einstellungen aus dem EEPROM geladen:");
Serial.println("ScrollSpeed: " + String(scrollSpeed));
Serial.println("MaxScrolls: " + String(maxScrolls));
}
// --- Funktion zum Ersetzen von Umlauten ---
String replaceUmlauts(String input) {
input.replace("ä", "ae");
input.replace("ö", "oe");
input.replace("ü", "ue");
input.replace("Ä", "Ae");
input.replace("Ö", "Oe");
input.replace("Ü", "Ue");
input.replace("ß", "ss");
return input;
}
// --- WLAN-Verbindung herstellen ---
void setup_wifi() {
Serial.println("Verbinde mit WLAN...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("\nWLAN verbunden. Signalstärke (RSSI): " + String(WiFi.RSSI()) + " dBm");
}
// --- MQTT Callback-Funktion ---
void callback(char* topic, byte* payload, unsigned int length) {
if (length == 0) {
Serial.println("Leere Nachricht empfangen, ignoriert.");
return;
}
String msg = "";
for (int i = 0; i < length; i++) {
msg += (char)payload[i];
}
Serial.println("Empfangenes Topic: " + String(topic));
Serial.println("Empfangene Nachricht: " + msg);
if (String(topic) == mqtt_topic_text) {
message = replaceUmlauts(msg);
scrollCount = 0;
displayActive = true;
display.displayClear();
display.begin();
display.displayText(message.c_str(), scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);
Serial.println("Text nach Ersetzen der Umlaute: " + message);
} else if (String(topic) == mqtt_topic_speed) {
uint8_t newSpeed = msg.toInt();
if (newSpeed >= 10 && newSpeed <= 150) {
scrollSpeed = newSpeed;
display.setSpeed(scrollSpeed);
saveSettingsToEEPROM();
Serial.println("Neue Geschwindigkeit: " + String(scrollSpeed));
} else {
Serial.println("Ungültige Geschwindigkeit: " + String(newSpeed));
}
} else if (String(topic) == mqtt_topic_scrollcount) {
uint8_t newScrolls = msg.toInt();
maxScrolls = newScrolls; // Speichere auch 0 für unendliche Durchläufe
saveSettingsToEEPROM();
Serial.println("Neue maximale Wiederholungen: " + String(maxScrolls));
}
}
// --- MQTT erneut verbinden ---
void reconnect() {
while (!client.connected()) {
Serial.println("MQTT-Verbindung verloren. Versuche erneut...");
if (client.connect(client_name.c_str(), mqtt_user, mqtt_pass)) {
Serial.println("Mit MQTT-Server verbunden!");
client.subscribe(mqtt_topic_text.c_str());
client.subscribe(mqtt_topic_speed.c_str());
client.subscribe(mqtt_topic_scrollcount.c_str());
} else {
Serial.print("Fehler bei MQTT-Verbindung: ");
Serial.println(client.state());
delay(5000);
}
}
}
// --- Setup ---
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
client.setKeepAlive(60);
loadSettingsFromEEPROM();
display.begin();
display.setIntensity(3);
display.displayClear();
display.setSpeed(scrollSpeed);
}
// --- Loop ---
void loop() {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WLAN getrennt, versuche erneut zu verbinden...");
setup_wifi();
}
if (!client.connected()) {
reconnect();
}
client.loop();
if (displayActive && display.displayAnimate()) {
if (maxScrolls > 0) { // Begrenzte Wiederholungen
scrollCount++;
if (scrollCount >= maxScrolls) {
displayActive = false;
display.displayClear();
Serial.println("Animation abgeschlossen. Leerzeichen wird gesendet.");
client.publish(mqtt_topic_text.c_str(), " ");
return;
}
} else {
// Unendlicher Modus: Animation einfach zurücksetzen
display.displayReset();
}
display.displayReset();
Serial.println("Animation Durchlauf: " + String(scrollCount));
}
}