MQTT-Display-LaserCutter/include/display_manager.h
MaPaLo76 4349b37f05 feat(display): implement DisplayManager with raw MD_MAX72XX
- Add include/display_manager.h: DisplayManager class declaration
  - Two-zone layout: Zone 0 (top, laser time), Zone 1 (bottom, countdown/status)
  - showLaserTime(), showCountdown(), showIdle(), showStatus(), setBrightness()
  - rotateCCW() bitmap transformation for 90 deg physical module rotation
  - charBitmap() for 17-character set (0-9, space, dash, dot, special chars)

- Add src/display_manager.cpp: full implementation
  - Double-init pattern for SPI power stability
  - showLaserTime() format: <10 -> ' x.x', <100 -> 'xx.x', <1000 -> ' xxx', else 'xxxx'
  - showCountdown() right-aligned 4-char format
  - All methods use writeZone() -> writeChar() -> rotateCCW() -> MD_MAX72XX

- Add test_sketches/test_display_manager.cpp: 6-step verification test
  - allLedsOn/Off, showLaserTime (12 boundary values), showCountdown 5->0
  - showIdle, showStatus (Err/AP/WiFi/oF), live simulation loop

- Update platformio.ini: add test-display-mgr environment
- Update src/main.cpp: integrate display.begin/showIdle/update
- Update Implementation-Plan.md: mark Phase 4 tasks 4.1-4.3 complete

Tested on hardware: all 6 test steps passed
2026-02-22 14:00:54 +01:00

98 lines
3.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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.
//
// Zone-Aufteilung:
// Zone 0 (top): Module 03 → akkumulierte Laserzeit (Float, Minuten)
// Zone 1 (bottom): Module 47 → Countdown / Status
//
// Verwendung:
// display.begin(); // einmalig in setup()
// display.showLaserTime(42.5f);
// display.showCountdown(18);
// display.showIdle();
// 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 015
void setBrightness(uint8_t level);
// ---- Anzeige-Methoden ---------------------------------------------------
// Obere Zone: Laserzeit in Minuten
// < 10 → " x.x" z.B. " 9.5"
// < 100 → "xx.x" z.B. "42.5"
// < 1000 → " xxx" z.B. " 123"
// < 10000 → "xxxx" z.B. "1234"
// >= 10000 → "!!!!" (Überlauf)
void showLaserTime(float minutes);
// Untere Zone: Countdown-Sekunden (rechtsbündig)
// 0999s werden dargestellt, > 999 → " !!!"
void showCountdown(int seconds);
// Untere Zone: Leerlauf-Anzeige (" --")
void showIdle();
// Untere Zone: Statustext (max. 4 Zeichen, wird abgeschnitten / aufgefüllt)
void showStatus(const char* msg);
// 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;