127 lines
4.5 KiB
C++
127 lines
4.5 KiB
C++
#pragma once
|
||
|
||
// =============================================================================
|
||
// display_manager.h – Dot-Matrix-Display Ausgabe (8× GYMAX7219, 4×2 Layout)
|
||
// Projekt: MQTT-Display LaserCutter
|
||
//
|
||
// Implementierung mit rohem MD_MAX72XX (kein MD_Parola), damit die physische
|
||
// 90°-CW Verdrehung der Module per Software (rotateCCW) zuverlässig kompensiert
|
||
// werden kann – ohne dass MD_Parola Zonenlogik interferiert.
|
||
//
|
||
// Modul-Aufteilung (oben links = Index 0):
|
||
// Modul 0 : WiFi-Fehler-Indikator (showWifiError)
|
||
// Modul 1–3 (oben) : Laserzeit in ganzen Minuten, 3 Stellen rechtsbündig
|
||
// Modul 4 : MQTT-Fehler-Indikator (showMqttError)
|
||
// Modul 5–7 (unten) : Countdown-Sekunden, 3 Stellen rechtsbündig / showIdle
|
||
//
|
||
// Verwendung:
|
||
// display.begin(); // einmalig in setup()
|
||
// display.showLaserTime(42.5f); // Modul 1-3
|
||
// display.showCountdown(18); // Modul 5-7
|
||
// display.showIdle(); // Modul 5-7
|
||
// display.showWifiError(true); // Modul 0
|
||
// display.showMqttError(true); // Modul 4
|
||
// display.update(); // in loop() aufrufen (Pflicht)
|
||
// =============================================================================
|
||
|
||
#include <Arduino.h>
|
||
#include <MD_MAX72xx.h>
|
||
#include <SPI.h>
|
||
#include "config.h"
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Maximale Textlänge je Zone (= Anzahl Module pro Zone)
|
||
// ---------------------------------------------------------------------------
|
||
#define DISP_CHARS_PER_ZONE DISPLAY_MODULES_PER_ZONE // 4
|
||
|
||
class DisplayManager {
|
||
public:
|
||
DisplayManager();
|
||
|
||
// Initialisierung (einmalig in setup())
|
||
void begin();
|
||
|
||
// Helligkeit setzen 0–15
|
||
void setBrightness(uint8_t level);
|
||
|
||
// ---- Anzeige-Methoden ---------------------------------------------------
|
||
|
||
// Modul 1–3 (oben): Laserzeit in ganzen Minuten, 3 Stellen rechtsbündig
|
||
// 0–9 → " x" z.B. " 7"
|
||
// 10–99 → " xx" z.B. " 42"
|
||
// 100–999 → "xxx" z.B. "123"
|
||
// ≥ 1000 → "!!!" (Überlauf, wird laut Anforderung nie erreicht)
|
||
// Modul 0 bleibt unberührt.
|
||
void showLaserTime(float minutes);
|
||
|
||
// Modul 5–7 (unten): Countdown-Sekunden, 3 Stellen rechtsbündig
|
||
// 0–9 → " x"
|
||
// 10–99 → " xx"
|
||
// 100–999 → "xxx"
|
||
// ≥ 1000 → "!!!"
|
||
// Modul 4 bleibt unberührt.
|
||
void showCountdown(int seconds);
|
||
|
||
// Modul 5–7 (unten): Leerlauf-Anzeige (" --")
|
||
// Modul 4 bleibt unberührt.
|
||
void showIdle();
|
||
|
||
// Modul 5–7 (unten): Sekunden-Kreisanzeige (wie analoge Uhr)
|
||
// seconds = 0–60: Rand der 3 Module wird sekündlich befüllt
|
||
// 60 LEDs = Perimeter des 24×8-Feldes (24 oben + 6 rechts + 24 unten + 6 links)
|
||
// Richtung: Uhrzeigersinn, Start oben-links
|
||
// seconds = 0 → alle LEDs aus (= Idle)
|
||
// seconds ≥ 60 → alle 60 Rand-LEDs an
|
||
// Modul 4 bleibt unberührt.
|
||
void showSessionRing(int seconds);
|
||
|
||
// Modul 5–7 (unten): Statustext (max. 3 Zeichen, wird abgeschnitten / aufgefüllt)
|
||
// Modul 4 bleibt unberührt.
|
||
void showStatus(const char* msg);
|
||
|
||
// Modul 0 (oben links): WiFi-Fehler-Indikator
|
||
// error=true → 'W' Symbol
|
||
// error=false → leer
|
||
void showWifiError(bool error);
|
||
|
||
// Modul 4 (unten links): MQTT-Fehler-Indikator
|
||
// error=true → 'M' Symbol
|
||
// error=false → leer
|
||
void showMqttError(bool error);
|
||
|
||
// Beide Zonen löschen
|
||
void clear();
|
||
|
||
// Muss in loop() aufgerufen werden (reserviert für zukünftige Scroll-Animation)
|
||
void update() {}
|
||
|
||
// Alle LEDs ein / aus (Testfunktion)
|
||
void allLedsOn();
|
||
void allLedsOff();
|
||
|
||
// Debug-Ausgabe auf Serial
|
||
void printToSerial() const;
|
||
|
||
private:
|
||
MD_MAX72XX _mx;
|
||
|
||
// Schreibt genau DISP_CHARS_PER_ZONE Zeichen auf eine Zone
|
||
// zone 0 → Module 0..3 (oben)
|
||
// zone 1 → Module 4..7 (unten)
|
||
// str muss exakt DISP_CHARS_PER_ZONE Zeichen enthalten (kein Null-Terminator nötig)
|
||
void writeZone(uint8_t zone, const char* str);
|
||
|
||
// Schreibt ein Zeichen auf ein einzelnes Modul
|
||
void writeChar(uint8_t moduleIdx, char c);
|
||
|
||
// 90° CCW Rotation – kompensiert physische 90° CW Verdrehung der Module
|
||
static void rotateCCW(const uint8_t src[8], uint8_t dst[8]);
|
||
|
||
// Gibt Zeiger auf 8-Byte-Bitmap für ASCII-Zeichen zurück
|
||
// Unterstützt: '0'–'9', ' ', '-', '.', '!', 'E', 'r', 'o', 'n', 'A', 'P'
|
||
static const uint8_t* charBitmap(char c);
|
||
};
|
||
|
||
// Globale Instanz
|
||
extern DisplayManager display;
|