231 lines
9.3 KiB
Markdown
231 lines
9.3 KiB
Markdown
# Laser Cutter Dot Matrix Display und MQTT Client
|
||
|
||
Dieses Projekt implementiert einen ESP32-basierten MQTT-Client mit Dot-Matrix-Display für einen Laser Cutter. Es misst und visualisiert die aktive Laserzeit, sendet Session-Daten an einen MQTT-Broker und bietet ein Browser-Webinterface zur Konfiguration und Steuerung.
|
||
|
||
---
|
||
|
||
## Inhaltsverzeichnis
|
||
|
||
1. [Hardware](#hardware)
|
||
2. [Pinbelegung](#pinbelegung)
|
||
3. [Display](#display)
|
||
4. [Laser-Signaldetektion](#laser-signaldetektion)
|
||
5. [Zeit-Tracking & Gratiszeit](#zeit-tracking--gratiszeit)
|
||
6. [MQTT Client](#mqtt-client)
|
||
7. [Webinterface](#webinterface)
|
||
8. [Konfiguration & Persistenz](#konfiguration--persistenz)
|
||
9. [WiFi-Setup (WiFiManager)](#wifi-setup-wifimanager)
|
||
10. [OTA Firmware-Update](#ota-firmware-update)
|
||
11. [Fehlerverhalten](#fehlerverhalten)
|
||
12. [Bibliotheken](#bibliotheken)
|
||
13. [Build & Flash](#build--flash)
|
||
|
||
---
|
||
|
||
## Hardware
|
||
|
||
| Komponente | Modell / Beschreibung |
|
||
|-------------------------|----------------------------------------------------|
|
||
| Mikrocontroller | AZ-Delivery ESP32 DevKit V4 |
|
||
| Dot-Matrix-Display | 8× GYMAX7219 Module (kompatibel zu MAX7219), 8×8 LEDs je Modul |
|
||
| Display-Anordnung | 4 Module nebeneinander × 2 Reihen = 32×16 LEDs |
|
||
| Display-Kaskadierung | Alle 8 Module in einer einzigen SPI-Kette |
|
||
| Laser-Aktivsignal | Potentialfreier Ausgang des Laser Cutters (Optokoppler empfohlen) |
|
||
| Optional | Shelly PM Mini G3 als externer Leistungsmesser (separater MQTT-Service) |
|
||
|
||
---
|
||
|
||
## Pinbelegung
|
||
|
||
| Signal | ESP32 GPIO | Beschreibung |
|
||
|---------------|-----------|------------------------------------------------|
|
||
| MAX7219 MOSI | GPIO 23 | SPI Data (VSPI) |
|
||
| MAX7219 CLK | GPIO 18 | SPI Clock (VSPI) |
|
||
| MAX7219 CS | GPIO 5 | SPI Chip Select |
|
||
| Laser-Signal | GPIO 4 | Potentialfreier Eingang (INPUT_PULLUP, konfigurierbar invertierbar) |
|
||
|
||
> Die Polarität des Laser-Signals (HIGH = aktiv oder LOW = aktiv) ist über das Webinterface konfigurierbar.
|
||
|
||
---
|
||
|
||
## Display
|
||
|
||
Das Display besteht aus 8 GYMAX7219-Modulen in einer 4×2-Anordnung (32×16 LEDs gesamt).
|
||
Es ist in **zwei Zonen** aufgeteilt, die unabhängig voneinander beschrieben werden:
|
||
|
||
| Zone | Module (Kette) | Anzeige-Inhalt |
|
||
|------|----------------|----------------------------------------|
|
||
| Oben | Module 0–3 | Akkumulierte aktive Laserzeit in **Minuten** (z.B. `42.5 min`) |
|
||
| Unten | Module 4–7 | Laufender **Countdown** in Sekunden der Gratiszeit, danach `---` |
|
||
|
||
- Die Anzeige aktualisiert sich sekündlich, solange der Laser aktiv ist.
|
||
- Bei inaktivem Laser bleibt die letzte gemessene Zeit dauerhaft sichtbar.
|
||
- Fehlerzustände (WLAN, MQTT) werden in der **unteren Zeile, erstes Modul** angezeigt.
|
||
- Die Bibliotheken `MD_Parola` + `MD_MAX72XX` werden für die Ansteuerung verwendet.
|
||
|
||
---
|
||
|
||
## Laser-Signaldetektion
|
||
|
||
Der ESP32 überwacht einen **digitalen GPIO-Eingang** mit internem Pull-Up-Widerstand (`INPUT_PULLUP`).
|
||
Der potentialfreie Ausgang des Laser Cutters (z.B. Schließer-Kontakt über Optokoppler) wird an diesen Pin angeschlossen.
|
||
|
||
- **Polarität konfigurierbar**: Im Webinterface einstellbar, ob `LOW` oder `HIGH` den aktiven Zustand bedeutet.
|
||
- **Debounce**: Software-Entprellung, um Fehlmessungen bei Schaltflanken zu vermeiden.
|
||
- Eine **Session** beginnt, wenn der Laser aktiv wird, und endet, wenn er inaktiv wird.
|
||
|
||
---
|
||
|
||
## Zeit-Tracking & Gratiszeit
|
||
|
||
- Die Laserzeit wird **akkumulativ** in Minuten gezählt und über Neustarts hinaus im **NVS (Non-Volatile Storage)** des ESP32 gespeichert.
|
||
- **Gratiszeit**: Eine konfigurierbare Zeitspanne (0–120 Sekunden) am Anfang jeder Session wird **nicht** zur akkumulierten Zeit gezählt. Dies erlaubt kurze Testläufe zum Einstellen des Laser Cutters ohne Kosten.
|
||
- Standard: 20 Sekunden
|
||
- Einstellbar über das Webinterface
|
||
- Die untere Display-Zeile zeigt während der Gratiszeit einen Countdown an.
|
||
|
||
---
|
||
|
||
## MQTT Client
|
||
|
||
Der ESP32 verbindet sich mit einem MQTT-Broker (konfigurierbar über Webinterface).
|
||
|
||
### Topics
|
||
|
||
| Richtung | Topic | Format | Beschreibung |
|
||
|------------|---------------------------|---------|-------------------------------------------|
|
||
| Publish | `lasercutter/session` | JSON | Wird beim **Ende einer Session** gesendet |
|
||
| Subscribe | `lasercutter/reset` | `"1"` | Setzt die akkumulierte Laserzeit auf 0 |
|
||
| Publish | `lasercutter/status` | JSON | Heartbeat alle 60 Sekunden (online/offline)|
|
||
|
||
### JSON-Format `lasercutter/session`
|
||
```json
|
||
{
|
||
"session_s": 125,
|
||
"total_min": 42.5,
|
||
"gratiszeit_s": 20,
|
||
"ts": "2026-02-22T10:30:00Z"
|
||
}
|
||
```
|
||
|
||
### JSON-Format `lasercutter/status`
|
||
```json
|
||
{
|
||
"online": true,
|
||
"total_min": 42.5,
|
||
"ip": "192.168.1.100",
|
||
"uptime_s": 3600
|
||
}
|
||
```
|
||
|
||
### Verhalten
|
||
- Reconnect im Hintergrund, falls MQTT-Broker nicht erreichbar.
|
||
- Bei aktivem Laser läuft die Zeitmessung unabhängig vom MQTT-Status weiter.
|
||
- QoS 1 für Session- und Reset-Topics.
|
||
|
||
---
|
||
|
||
## Webinterface
|
||
|
||
Das Webinterface ist über die IP-Adresse des ESP32 im Browser erreichbar.
|
||
|
||
| Seite | URL | Funktion |
|
||
|------------------|-------------|--------------------------------------------------------------|
|
||
| Status | `/` | Aktuelle Laserzeit, letzter Session-Wert, Systemstatus |
|
||
| Konfiguration | `/config` | MQTT-Broker (IP, Port, User, Passwort), Gratiszeit, Polarität |
|
||
| Reset | `/reset` | Setzt akkumulierte Laserzeit zurück |
|
||
| OTA Update | `/update` | Firmware-Update über Browser |
|
||
|
||
---
|
||
|
||
## Konfiguration & Persistenz
|
||
|
||
Alle Einstellungen werden im **NVS (Non-Volatile Storage)** des ESP32 gespeichert und sind über das Webinterface änderbar:
|
||
|
||
| Einstellung | Standard | Beschreibung |
|
||
|-----------------------|---------------|-----------------------------------------|
|
||
| MQTT Broker IP | `192.168.1.1` | IP-Adresse des MQTT-Brokers |
|
||
| MQTT Port | `1883` | Port des MQTT-Brokers |
|
||
| MQTT User | *(leer)* | MQTT Benutzername (optional) |
|
||
| MQTT Passwort | *(leer)* | MQTT Passwort (optional) |
|
||
| Gratiszeit | `20` | Sekunden, 0–120 |
|
||
| Signal-Polarität | `LOW_ACTIVE` | `LOW_ACTIVE` oder `HIGH_ACTIVE` |
|
||
| Akkumulierte Zeit | `0.0` | Gespeicherte Laserzeit in Minuten (NVS) |
|
||
|
||
---
|
||
|
||
## WiFi-Setup (WiFiManager)
|
||
|
||
Beim ersten Start (oder wenn keine gespeicherten WLAN-Daten vorhanden) öffnet das Gerät einen **Access Point** mit Captive Portal:
|
||
|
||
- SSID: `LaserCutter-Setup`
|
||
- Im Browser öffnet sich automatisch die Konfigurationsseite.
|
||
- WLAN-Credentials werden nach erfolgreicher Verbindung im NVS gespeichert.
|
||
|
||
---
|
||
|
||
## OTA Firmware-Update
|
||
|
||
Firmware-Updates können kabellos über die Weboberfläche unter `/update` eingespielt werden (ElegantOTA).
|
||
|
||
---
|
||
|
||
## Fehlerverhalten
|
||
|
||
| Zustand | Display-Anzeige (untere Zeile, Modul 1) | Verhalten |
|
||
|----------------------|----------------------------------------|----------------------------------------|
|
||
| WLAN getrennt | `WiFi ERR` | Zeiterfassung läuft weiter, Reconnect |
|
||
| MQTT nicht erreichbar| `MQTT ERR` | Zeiterfassung läuft weiter, Reconnect |
|
||
| WLAN + MQTT OK | Normaler Betrieb (Countdown/`---`) | – |
|
||
|
||
---
|
||
|
||
## Bibliotheken
|
||
|
||
| Bibliothek | Zweck |
|
||
|-----------------------|--------------------------------------|
|
||
| `MD_Parola` | Dot-Matrix-Display Textausgabe |
|
||
| `MD_MAX72XX` | Treiber für MAX7219/GYMAX7219 |
|
||
| `PubSubClient` | MQTT Client |
|
||
| `WiFiManager` | WiFi Captive Portal |
|
||
| `ESPAsyncWebServer` | Asynchroner Webserver |
|
||
| `AsyncTCP` | TCP-Basis für ESPAsyncWebServer |
|
||
| `ArduinoJson` | JSON Serialisierung/Deserialisierung |
|
||
| `Preferences` | NVS-Zugriff (built-in ESP32 Arduino) |
|
||
| `ElegantOTA` | OTA-Update über Webinterface |
|
||
|
||
---
|
||
|
||
## Build & Flash
|
||
|
||
```bash
|
||
# PlatformIO CLI
|
||
pio run --target upload
|
||
|
||
# Serieller Monitor
|
||
pio device monitor
|
||
```
|
||
|
||
Ziel-Board: `az-delivery-devkit-v4` (ESP32), Upload-Port: `COM3`
|
||
|
||
---
|
||
|
||
## Projektstruktur
|
||
|
||
```
|
||
MQTT-Display-LaserCutter/
|
||
├── src/
|
||
│ └── main.cpp # Hauptprogramm
|
||
├── include/
|
||
│ ├── config.h # Pin-Definitionen, Konstanten
|
||
│ ├── display_manager.h # Display-Logik (MD_Parola)
|
||
│ ├── laser_tracker.h # Signal-Detektion & Zeiterfassung
|
||
│ ├── mqtt_client.h # MQTT-Wrapper (PubSubClient)
|
||
│ ├── web_server.h # Webinterface (ESPAsyncWebServer)
|
||
│ └── settings.h # NVS-Persistenz (Preferences)
|
||
├── parser/
|
||
│ └── shelly_parser.py # Separater Python-Parser für Shelly PM G3
|
||
├── platformio.ini
|
||
└── README.md
|
||
```
|