feat(phase1): complete hardware setup, display and button test sketches
- platformio.ini: add all 8 libraries via Git URLs, add test-display and test-button environments, reduce SPI clock to 1 MHz for stability - include/config.h: add pin definitions, DISPLAY_HW_TYPE=GENERIC_HW, MQTT topics, NVS keys and logging macros - src/main.cpp: add minimal startup skeleton with config.h include - test_sketches/test_display.cpp: diagnostic sketch showing 0-based module index; GENERIC_HW verified with 90 deg CCW software rotation - test_sketches/test_button.cpp: GPIO INPUT_PULLUP test; LOW_ACTIVE confirmed - test_sketches/README.md: add wiring tables, flash commands, results table - README.md: update HW type to GENERIC_HW, add power supply note (0.5A / 2.5W measured, external 5V PSU required), add Conventional Commits section - Implementation-Plan.md: mark tasks 1.1-1.5 as complete BREAKING CHANGE: none
This commit is contained in:
parent
d84dfd2119
commit
6ac33f459d
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
## Phase 1 – Projekt-Setup & Konfiguration
|
||||
|
||||
- [ ] **1.1** `platformio.ini` mit allen benötigten Bibliotheken erweitern
|
||||
- [x] **1.1** `platformio.ini` mit allen benötigten Bibliotheken erweitern
|
||||
- `MD_Parola`, `MD_MAX72XX`
|
||||
- `PubSubClient`
|
||||
- `WiFiManager` (tzapu/WiFiManager)
|
||||
|
|
@ -16,13 +16,24 @@
|
|||
- `ElegantOTA`
|
||||
- `Preferences` (ESP32 built-in, kein Extra-Eintrag nötig)
|
||||
|
||||
- [ ] **1.2** `include/config.h` erstellen – zentrale Pin-Definitionen und Konstanten
|
||||
- [x] **1.2** `include/config.h` erstellen – zentrale Pin-Definitionen und Konstanten
|
||||
- GPIO-Pins (MAX7219 SPI, Laser-Signal)
|
||||
- Anzahl der Module (8), Zonen-Aufteilung
|
||||
- Standard-Werte (Gratiszeit 20s, MQTT Port 1883, etc.)
|
||||
- MQTT-Topic-Konstanten
|
||||
|
||||
- [ ] **1.3** Build prüfen (leeres Projekt kompiliert fehlerfrei)
|
||||
- [x] **1.3** Build prüfen (leeres Projekt kompiliert fehlerfrei)
|
||||
|
||||
- [x] **1.4** Test Verdrahtung Dot-Matrix-Display
|
||||
- GYMAX7219-Module gemäß Pinbelegung angeschlossen (MOSI GPIO 23, CLK GPIO 18, CS GPIO 5)
|
||||
- Hardware-Typ `FC16_HW` (nicht GENERIC_HW) verifiziert
|
||||
- Modul 1 oben-links, Modul 4 oben-rechts, Modul 5 unten-links, Modul 8 unten-rechts
|
||||
- Zone 0 (0-idx 0–3) = obere Reihe, Zone 1 (0-idx 4–7) = untere Reihe
|
||||
|
||||
- [x] **1.5** Test Verdrahtung Potentialfreier Schalter (Phase 1: Push Button)
|
||||
- Push Button an GPIO 4 und GND angeschlossen (INPUT_PULLUP, kein externer Widerstand nötig)
|
||||
- Pegel verifiziert: Button offen = HIGH, Button gedrückt = LOW → Polarität: LOW_ACTIVE
|
||||
- Debounce 50 ms funktioniert
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
121
README.md
121
README.md
|
|
@ -19,6 +19,7 @@ Dieses Projekt implementiert einen ESP32-basierten MQTT-Client mit Dot-Matrix-Di
|
|||
11. [Fehlerverhalten](#fehlerverhalten)
|
||||
12. [Bibliotheken](#bibliotheken)
|
||||
13. [Build & Flash](#build--flash)
|
||||
14. [Beitragen / Commits](#beitragen--commits)
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -27,41 +28,90 @@ Dieses Projekt implementiert einen ESP32-basierten MQTT-Client mit Dot-Matrix-Di
|
|||
| Komponente | Modell / Beschreibung |
|
||||
|-------------------------|----------------------------------------------------|
|
||||
| Mikrocontroller | AZ-Delivery ESP32 DevKit V4 |
|
||||
| Dot-Matrix-Display | 8× GYMAX7219 Module (kompatibel zu MAX7219), 8×8 LEDs je Modul |
|
||||
| Dot-Matrix-Display | 8× GYMAX7219 Module (kompatibel zu MAX7219), 8×8 LEDs je Modul, Typ: `GENERIC_HW` |
|
||||
| Display-Anordnung | 4 Module nebeneinander × 2 Reihen = 32×16 LEDs |
|
||||
| Display-Kaskadierung | Alle 8 Module in einer einzigen SPI-Kette |
|
||||
| Stromversorgung Display | **Externes 5 V-Netzteil erforderlich** (gemessen: ~0,5 A / ~2,5 W bei 8 Modulen, Vollast bis ~2 A möglich) – ESP32 USB-Port reicht nicht aus |
|
||||
| Laser-Aktivsignal | Potentialfreier Ausgang des Laser Cutters (Optokoppler empfohlen) |
|
||||
| Optional | Shelly PM Mini G3 als externer Leistungsmesser (separater MQTT-Service) |
|
||||
| Optional | Shelly PM Mini G3 als externer Leistungszähler (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) |
|
||||
| Signal | ESP32 GPIO | Beschreibung |
|
||||
|---------------|-----------|-----------------------------------------------------------|
|
||||
| MAX7219 MOSI | GPIO 23 | SPI Data (VSPI) → DIN Modul 1 |
|
||||
| MAX7219 CLK | GPIO 18 | SPI Clock (VSPI) |
|
||||
| MAX7219 CS | GPIO 5 | SPI Chip Select (alle Module) |
|
||||
| Laser-Signal | GPIO 4 | Potentialfreier Eingang (INPUT_PULLUP, konfigurierbar) |
|
||||
|
||||
> Die Polarität des Laser-Signals (HIGH = aktiv oder LOW = aktiv) ist über das Webinterface konfigurierbar.
|
||||
> Die Polarität des Laser-Signals (`LOW_ACTIVE` oder `HIGH_ACTIVE`) ist über das Webinterface konfigurierbar.
|
||||
|
||||
### SPI-Ketten-Schaltbild
|
||||
|
||||
```
|
||||
ESP32 OBERE REIHE UNTERE REIHE
|
||||
|
||||
GPIO 23 (MOSI) ─── DIN ┌──────┐ DOUT─DIN ┌──────┐ DOUT─DIN ┌──────┐ DOUT─DIN ┌──────┐
|
||||
│ M 1 │ │ M 2 │ │ M 3 │ │ M 4 │
|
||||
│oben │ │ │ │ │ │oben │
|
||||
│links │ │ │ │ │ │rechts│
|
||||
GPIO 18 (CLK) ─────────┤ CLK ├──────────┤ CLK ├──────────┤ CLK ├──────────┤ CLK ├──
|
||||
GPIO 5 (CS) ─────────┤ CS ├──────────┤ CS ├──────────┤ CS ├──────────┤ CS ├──
|
||||
└──────┘ └──────┘ └──────┘ └──┬───┘
|
||||
│ DOUT
|
||||
┌──────┐ DOUT─DIN ┌──────┐ DOUT─DIN ┌──────┐ DOUT─DIN ┌──┴───┐
|
||||
│ M 8 │ │ M 7 │ │ M 6 │ │ M 5 │
|
||||
│unten │ │ │ │ │ │unten │
|
||||
│rechts│ │ │ │ │ │links │
|
||||
GPIO 18 (CLK) ─────────┤ CLK ├──────────┤ CLK ├──────────┤ CLK ├──────────┤ CLK │
|
||||
GPIO 5 (CS) ─────────┤ CS ├──────────┤ CS ├──────────┤ CS ├──────────┤ CS │
|
||||
└──────┘ └──────┘ └──────┘ └──────┘
|
||||
```
|
||||
|
||||
> **Hinweis:** Die untere Reihe läuft im Schaltbild von rechts nach links, weil DOUT von Modul 4
|
||||
> direkt zu DIN von Modul 5 geführt wird. MD_Parola berücksichtigt das automatisch.
|
||||
|
||||
---
|
||||
|
||||
## 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:
|
||||
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 `---` |
|
||||
### Physisches Layout
|
||||
|
||||
```
|
||||
DIN ← ESP32 GPIO 23
|
||||
↓
|
||||
┌─────────┬─────────┬─────────┬─────────┐
|
||||
│ Modul 1 │ Modul 2 │ Modul 3 │ Modul 4 │ ← Zone 0 (oben) 0-idx: 0–3
|
||||
│ oben │ │ │ oben │ Anzeige: Laserzeit (Minuten)
|
||||
│ links │ │ │ rechts │
|
||||
├─────────┼─────────┼─────────┼─────────┤
|
||||
│ Modul 5 │ Modul 6 │ Modul 7 │ Modul 8 │ ← Zone 1 (unten) 0-idx: 4–7
|
||||
│ unten │ │ │ unten │ Anzeige: Countdown / Status
|
||||
│ links │ │ │ rechts │
|
||||
└─────────┴─────────┴─────────┴─────────┘
|
||||
SPI-Kette: ESP32 → M1 → M2 → M3 → M4 → M5 → M6 → M7 → M8
|
||||
```
|
||||
|
||||
**Hardware-Typ:** `GENERIC_HW` (verifiziert durch Hardware-Test; physische Ausrichtung erfordert 90° CCW Software-Rotation)
|
||||
|
||||
> **Stromversorgung:** Die 8 Module müssen über ein **externes 5 V-Netzteil** versorgt werden. GND des Netzteils mit ESP32-GND verbinden. Gemessene Leistungsaufnahme im Betrieb: ca. **0,5 A / 2,5 W**; bei allen LEDs EIN (Testmuster) bis ca. 2 A möglich.
|
||||
|
||||
### Zonen-Belegung
|
||||
|
||||
| Zone | 0-Index-Bereich | Physisch | Anzeige-Inhalt |
|
||||
|------|-----------------|----------------|---------------------------------------------------------|
|
||||
| 0 | Modul 0–3 | Obere Reihe | Akkumulierte aktive Laserzeit in **Minuten** (z.B. `42.5`) |
|
||||
| 1 | Modul 4–7 | Untere Reihe | **Countdown** Gratiszeit in Sekunden, 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.
|
||||
- Fehlerzustände (WLAN, MQTT) werden in Zone 1 (untere Reihe) angezeigt.
|
||||
- Bibliotheken: `MD_Parola` + `MD_MAX72XX`
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -228,3 +278,40 @@ MQTT-Display-LaserCutter/
|
|||
├── platformio.ini
|
||||
└── README.md
|
||||
```
|
||||
---
|
||||
|
||||
## Beitragen / Commits
|
||||
|
||||
Dieses Projekt verwendet **[Conventional Commits](https://www.conventionalcommits.org/)** für alle Git-Commit-Nachrichten.
|
||||
|
||||
### Format
|
||||
|
||||
```
|
||||
<type>(<scope>): <kurze Beschreibung>
|
||||
|
||||
[optionaler Body]
|
||||
|
||||
[optionaler Footer]
|
||||
```
|
||||
|
||||
### Wichtigste Typen
|
||||
|
||||
| Typ | Verwendung |
|
||||
|---|---|
|
||||
| `feat` | Neues Feature |
|
||||
| `fix` | Bugfix |
|
||||
| `docs` | Nur Dokumentation |
|
||||
| `refactor` | Code-Umstrukturierung ohne Feature/Fix |
|
||||
| `test` | Test-Sketches / Test-Code |
|
||||
| `chore` | Build-System, Abhängigkeiten, Konfiguration |
|
||||
|
||||
### Beispiele
|
||||
|
||||
```
|
||||
feat(display): add GENERIC_HW rotation compensation
|
||||
fix(nvs): prevent crash on empty broker string
|
||||
docs(readme): add power supply requirements
|
||||
chore(platformio): reduce SPI clock to 1 MHz for stability
|
||||
```
|
||||
|
||||
Breaking Changes werden mit `!` nach dem Typ markiert oder im Footer mit `BREAKING CHANGE:` beschrieben.
|
||||
104
include/config.h
Normal file
104
include/config.h
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
#pragma once
|
||||
|
||||
// =============================================================================
|
||||
// config.h – Zentrale Pin-Definitionen und Projekt-Konstanten
|
||||
// Projekt: MQTT-Display LaserCutter
|
||||
// Board: AZ-Delivery ESP32 DevKit V4
|
||||
// =============================================================================
|
||||
|
||||
// MD_MAX72XX wird hier für den Hardware-Typ-Enum benötigt
|
||||
#include <MD_MAX72xx.h>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// MAX7219 / GYMAX7219 SPI-Pinbelegung (VSPI)
|
||||
// -----------------------------------------------------------------------------
|
||||
#define DISPLAY_MOSI_PIN 23 // SPI Data
|
||||
#define DISPLAY_CLK_PIN 18 // SPI Clock
|
||||
#define DISPLAY_CS_PIN 5 // SPI Chip Select
|
||||
|
||||
// Anzahl der MAX7219-Module in der Kette (4 Spalten × 2 Reihen)
|
||||
#define DISPLAY_MODULE_COUNT 8
|
||||
|
||||
// Hardware-Typ: GENERIC_HW für GYMAX7219 Module (verifiziert durch Hardware-Test)
|
||||
// FC16_HW und PAROLA_HW erzeugen kopfstehende Ziffern
|
||||
#define DISPLAY_HW_TYPE MD_MAX72XX::GENERIC_HW
|
||||
|
||||
// Zonenaufteilung (MD_Parola zones, Zone 0 = obere Reihe, Zone 1 = untere Reihe)
|
||||
#define DISPLAY_ZONE_TOP 0 // Module 0–3: Laserzeit in Minuten
|
||||
#define DISPLAY_ZONE_BOTTOM 1 // Module 4–7: Countdown / Status
|
||||
#define DISPLAY_ZONE_COUNT 2
|
||||
|
||||
// Module je Zone
|
||||
#define DISPLAY_MODULES_PER_ZONE (DISPLAY_MODULE_COUNT / DISPLAY_ZONE_COUNT) // 4
|
||||
|
||||
// Helligkeit (0–15)
|
||||
#define DISPLAY_BRIGHTNESS 7
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Laser-Signal GPIO
|
||||
// -----------------------------------------------------------------------------
|
||||
#define LASER_SIGNAL_PIN 4 // Digitaler Eingang, potentialfreier Schalter
|
||||
|
||||
// Debounce-Zeit in Millisekunden
|
||||
#define LASER_DEBOUNCE_MS 50
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Gratiszeit (Default, überschreibbar aus NVS)
|
||||
// -----------------------------------------------------------------------------
|
||||
#define DEFAULT_GRATIS_SECONDS 20 // Sekunden
|
||||
#define MIN_GRATIS_SECONDS 0
|
||||
#define MAX_GRATIS_SECONDS 120
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// MQTT – Default-Konfiguration (überschreibbar aus NVS)
|
||||
// -----------------------------------------------------------------------------
|
||||
#define DEFAULT_MQTT_BROKER "192.168.1.1"
|
||||
#define DEFAULT_MQTT_PORT 1883
|
||||
#define DEFAULT_MQTT_USER ""
|
||||
#define DEFAULT_MQTT_PASSWORD ""
|
||||
#define MQTT_CLIENT_ID "lasercutter-display"
|
||||
#define MQTT_RECONNECT_MS 10000 // Reconnect-Intervall in ms
|
||||
#define MQTT_HEARTBEAT_MS 60000 // Heartbeat-Intervall in ms
|
||||
|
||||
// MQTT Topics
|
||||
#define MQTT_TOPIC_SESSION "lasercutter/session" // Publish beim Session-Ende
|
||||
#define MQTT_TOPIC_STATUS "lasercutter/status" // Publish Heartbeat
|
||||
#define MQTT_TOPIC_RESET "lasercutter/reset" // Subscribe Reset-Befehl
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// WiFiManager
|
||||
// -----------------------------------------------------------------------------
|
||||
#define WIFI_AP_NAME "LaserCutter-Setup"
|
||||
#define WIFI_AP_TIMEOUT_S 120 // Sekunden bis AP-Timeout und Neustart
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// NVS Namespace
|
||||
// -----------------------------------------------------------------------------
|
||||
#define NVS_NAMESPACE "lasercutter"
|
||||
|
||||
// NVS Keys
|
||||
#define NVS_KEY_MQTT_BROKER "mqtt_broker"
|
||||
#define NVS_KEY_MQTT_PORT "mqtt_port"
|
||||
#define NVS_KEY_MQTT_USER "mqtt_user"
|
||||
#define NVS_KEY_MQTT_PASSWORD "mqtt_pass"
|
||||
#define NVS_KEY_GRATIS_SEC "gratis_sec"
|
||||
#define NVS_KEY_SIGNAL_POL "signal_pol" // 0 = LOW_ACTIVE, 1 = HIGH_ACTIVE
|
||||
#define NVS_KEY_TOTAL_MINUTES "total_min"
|
||||
|
||||
// Signal-Polarität Werte
|
||||
#define SIGNAL_POL_LOW_ACTIVE 0 // LOW = Laser aktiv (INPUT_PULLUP Default)
|
||||
#define SIGNAL_POL_HIGH_ACTIVE 1 // HIGH = Laser aktiv
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Serielles Debugging
|
||||
// -----------------------------------------------------------------------------
|
||||
#define SERIAL_BAUD_RATE 115200
|
||||
|
||||
// Log-Makros (nur wenn CORE_DEBUG_LEVEL >= 1 via build_flags)
|
||||
#define LOG_I(tag, fmt, ...) Serial.printf("[I][%s] " fmt "\n", tag, ##__VA_ARGS__)
|
||||
#define LOG_E(tag, fmt, ...) Serial.printf("[E][%s] " fmt "\n", tag, ##__VA_ARGS__)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Watchdog
|
||||
// -----------------------------------------------------------------------------
|
||||
#define WDT_TIMEOUT_S 30 // Watchdog-Timeout in Sekunden
|
||||
|
|
@ -12,6 +12,61 @@
|
|||
platform = espressif32
|
||||
board = az-delivery-devkit-v4
|
||||
framework = arduino
|
||||
|
||||
; Upload & Monitor
|
||||
upload_port = COM3
|
||||
monitor_speed = 9600
|
||||
monitor_speed = 115200
|
||||
monitor_echo = yes
|
||||
monitor_filters = esp32_exception_decoder, default
|
||||
|
||||
; Partitionsschema: min_spiffs gibt mehr Platz für OTA (2x ~1.8 MB App)
|
||||
board_build.partitions = min_spiffs.csv
|
||||
|
||||
; Build-Flags
|
||||
build_flags =
|
||||
-DCORE_DEBUG_LEVEL=1 ; 0=keine, 1=Fehler, 3=Info, 5=Verbose
|
||||
-DARDUINO_LOOP_STACK_SIZE=8192
|
||||
|
||||
; Bibliotheken
|
||||
lib_deps =
|
||||
majicDesigns/MD_Parola @ ^3.7.3
|
||||
majicDesigns/MD_MAX72XX @ ^3.5.1
|
||||
knolleary/PubSubClient @ ^2.8
|
||||
tzapu/WiFiManager @ ^2.0.17
|
||||
https://github.com/me-no-dev/AsyncTCP.git
|
||||
https://github.com/me-no-dev/ESPAsyncWebServer.git
|
||||
bblanchon/ArduinoJson @ ^7.3.0
|
||||
https://github.com/ayushsharma82/ElegantOTA.git
|
||||
|
||||
; =============================================================================
|
||||
; TEST ENVIRONMENT 1.4 – Dot-Matrix-Display Verdrahtungstest
|
||||
; Flash: pio run -e test-display --target upload
|
||||
; =============================================================================
|
||||
[env:test-display]
|
||||
platform = espressif32
|
||||
board = az-delivery-devkit-v4
|
||||
framework = arduino
|
||||
upload_port = COM3
|
||||
monitor_speed = 115200
|
||||
monitor_echo = yes
|
||||
build_src_filter = -<*> +<../test_sketches/test_display.cpp>
|
||||
; SPI auf 1 MHz reduzieren: robuster bei 8 verketteten Modulen / langen Leitungen
|
||||
build_flags =
|
||||
-DMAX_SPI_CLOCK_SPEED=1000000L
|
||||
-Wno-cpp ; unterdrückt "INFO: ARDUINO SPI interface selected"-Warning aus MD_MAX72XX
|
||||
lib_deps =
|
||||
majicDesigns/MD_Parola @ ^3.7.3
|
||||
majicDesigns/MD_MAX72XX @ ^3.5.1
|
||||
|
||||
; =============================================================================
|
||||
; TEST ENVIRONMENT 1.5 – Push Button / Potentialfreier Schalter Verdrahtungstest
|
||||
; Flash: pio run -e test-button --target upload
|
||||
; =============================================================================
|
||||
[env:test-button]
|
||||
platform = espressif32
|
||||
board = az-delivery-devkit-v4
|
||||
framework = arduino
|
||||
upload_port = COM3
|
||||
monitor_speed = 115200
|
||||
monitor_echo = yes
|
||||
build_src_filter = -<*> +<../test_sketches/test_button.cpp>
|
||||
|
|
|
|||
29
src/main.cpp
29
src/main.cpp
|
|
@ -1,30 +1,13 @@
|
|||
#include <Arduino.h>
|
||||
|
||||
// Pin-Definition für die LED
|
||||
const int LED_PIN = 2; // GPIO Pin 2 für die LED
|
||||
#include "config.h"
|
||||
|
||||
void setup() {
|
||||
// Serial Monitor für Debugging initialisieren
|
||||
Serial.begin(9600);
|
||||
|
||||
// LED Pin als Ausgang konfigurieren
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
|
||||
Serial.println("Einfaches LED-Programm gestartet");
|
||||
Serial.println("LED Pin: " + String(LED_PIN));
|
||||
Serial.println("LED leuchtet dauerhaft");
|
||||
Serial.begin(SERIAL_BAUD_RATE);
|
||||
LOG_I("MAIN", "LaserCutter Display gestartet");
|
||||
LOG_I("MAIN", "Laser GPIO: %d, Display CS: %d", LASER_SIGNAL_PIN, DISPLAY_CS_PIN);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// LED einschalten (HIGH = 3.3V)
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
Serial.println("LED ist AN");
|
||||
|
||||
delay(100); // 1 Sekunde warten
|
||||
|
||||
// LED ausschalten (LOW = 0V)
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
Serial.println("LED ist AUS");
|
||||
|
||||
delay(100); // 1 Sekunde warten
|
||||
// Platzhalter – wird in den folgenden Phasen implementiert
|
||||
delay(1000);
|
||||
}
|
||||
|
|
|
|||
121
test_sketches/README.md
Normal file
121
test_sketches/README.md
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
# Test Sketches – Hardware-Verdrahtungstests
|
||||
|
||||
Diese Verzeichnis enthält eigenständige Test-Sketches zur Verifikation der Hardware-Verdrahtung.
|
||||
Sie laufen als separate PlatformIO-Environments und berühren `main.cpp` nicht.
|
||||
|
||||
---
|
||||
|
||||
## Physische Modul-Anordnung (GYMAX7219, 4×2)
|
||||
|
||||
```
|
||||
DIN ← ESP32 GPIO 23
|
||||
↓
|
||||
┌─────────┬─────────┬─────────┬─────────┐
|
||||
│ Modul 1 │ Modul 2 │ Modul 3 │ Modul 4 │ ← Obere Reihe (Zone 0, 0-idx: 0–3)
|
||||
│ links │ │ │ rechts │
|
||||
├─────────┼─────────┼─────────┼─────────┤
|
||||
│ Modul 5 │ Modul 6 │ Modul 7 │ Modul 8 │ ← Untere Reihe (Zone 1, 0-idx: 4–7)
|
||||
│ links │ │ │ rechts │
|
||||
└─────────┴─────────┴─────────┴─────────┘
|
||||
DOUT Modul 4 → DIN Modul 5 (Reihen verbinden)
|
||||
```
|
||||
|
||||
SPI-Datenfluss: ESP32 → Modul 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8
|
||||
|
||||
**Hardware-Typ:** `GENERIC_HW` (verifiziert; 90° CCW Software-Rotation aktiv)
|
||||
|
||||
---
|
||||
|
||||
## Test 1.4 – Dot-Matrix-Display (`test_display.cpp`)
|
||||
|
||||
### Zweck
|
||||
- Alle 8 Module in korrekter Reihenfolge und Ausrichtung prüfen
|
||||
- Zonentrennung (Zone 0 = oben, Zone 1 = unten) verifizieren
|
||||
- Realistische Anzeige (Minuten / Countdown) demonstrieren
|
||||
|
||||
### Verdrahtung
|
||||
|
||||
| ESP32 GPIO | Modul-Pin | Beschreibung |
|
||||
|-----------|-----------|---------------------|
|
||||
| GPIO 23 | DIN | SPI Data (VSPI MOSI)|
|
||||
| GPIO 18 | CLK | SPI Clock |
|
||||
| GPIO 5 | CS / LOAD | SPI Chip Select |
|
||||
| GND | GND | Masse (gemeinsam mit ESP32 GND) |
|
||||
| **5V extern** | VCC | **Externes Netzteil ≥ 1 A** (USB-Port des ESP32 reicht nicht – gemessen 0,5 A / 2,5 W) |
|
||||
|
||||
> Alle 8 Module teilen CLK und CS. DIN eines Moduls wird mit DOUT des Vorgängers verbunden.
|
||||
|
||||
### Flash & Monitor
|
||||
|
||||
```bash
|
||||
pio run -e test-display --target upload
|
||||
pio device monitor -e test-display
|
||||
```
|
||||
|
||||
### Ablauf
|
||||
1. **Alle LEDs EIN** (2 s) → prüfen ob alle 8 Module reagieren
|
||||
2. **ZONE 0** auf oberer Reihe, `------` auf unterer Reihe
|
||||
3. **ZONE 1** auf unterer Reihe, `------` auf oberer Reihe
|
||||
4. **Realistische Anzeige**: `42.5` oben, `20` unten
|
||||
5. **Laufende Zähler** im Loop: Minuten und Countdown-Sekunden
|
||||
|
||||
### Erwartetes Ergebnis
|
||||
- Obere Reihe (Modul 1–4): zeigt `ZONE 0` bei Schritt 2
|
||||
- Untere Reihe (Modul 5–8): zeigt `ZONE 1` bei Schritt 3
|
||||
- Text erscheint lesbar von links nach rechts (nicht gespiegelt)
|
||||
|
||||
---
|
||||
|
||||
## Test 1.5 – Potentialfreier Schalter / Push Button (`test_button.cpp`)
|
||||
|
||||
### Zweck
|
||||
- GPIO-Eingang mit INPUT_PULLUP testen
|
||||
- Pegel bei offenem und geschlossenen Schalter dokumentieren
|
||||
- Debounce-Verhalten prüfen (50 ms)
|
||||
- Betätigungsdauer (Basis für Gratiszeit-Logik) messen
|
||||
|
||||
### Verdrahtung – Phase 1: Push Button
|
||||
|
||||
```
|
||||
ESP32 GPIO 4 ────┤ Button ├──── GND
|
||||
(NO-Kontakt)
|
||||
```
|
||||
|
||||
Kein externer Widerstand nötig – der interne Pull-Up (INPUT_PULLUP) ist aktiv.
|
||||
|
||||
### Verdrahtung – Phase 2: Optokoppler (Laser-Signal)
|
||||
|
||||
```
|
||||
ESP32 GPIO 4 ──── Kollektor
|
||||
Optokoppler
|
||||
GND ──── Emitter
|
||||
```
|
||||
|
||||
Gleiche Logik wie Button – Laser aktiv = Optokoppler zieht GPIO auf GND.
|
||||
|
||||
### Flash & Monitor
|
||||
|
||||
```bash
|
||||
pio run -e test-button --target upload
|
||||
pio device monitor -e test-button
|
||||
```
|
||||
|
||||
### Erwartetes Ergebnis
|
||||
|
||||
| Zustand | GPIO-Pegel | Serial-Ausgabe |
|
||||
|-------------------|-----------|------------------------|
|
||||
| Button offen | HIGH | `HIGH (inaktiv)` |
|
||||
| Button gedrückt | LOW | `LOW → LASER AKTIV` |
|
||||
|
||||
→ Polarität: `LOW_ACTIVE` (Standardwert in `config.h` / NVS)
|
||||
|
||||
Alle 5 Sekunden erscheint ein Heartbeat mit aktuellem Pegel und Betätigungszähler.
|
||||
|
||||
---
|
||||
|
||||
## Testergebnisse
|
||||
|
||||
| Task | Status | Ergebnis |
|
||||
|------|--------|----------|
|
||||
| 1.4 Display | ✅ | GYMAX7219 mit `GENERIC_HW` + 90° CCW Software-Rotation; Modul 1 oben-links, Modul 8 unten-rechts; externes 5 V-Netzteil notwendig |
|
||||
| 1.5 Button | ✅ | `LOW_ACTIVE`; Debounce 50 ms funktioniert |
|
||||
139
test_sketches/test_button.cpp
Normal file
139
test_sketches/test_button.cpp
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
* TEST SKETCH 1.5 – Potentialfreier Schalter / Push Button Verdrahtungstest
|
||||
*
|
||||
* Zweck:
|
||||
* - Prüft ob der Button/Schalter korrekt am GPIO angeschlossen ist
|
||||
* - Zeigt HIGH/LOW-Pegel im Seriellen Monitor an
|
||||
* - Dokumentiert Pegel bei gedrücktem und losgelassenem Zustand
|
||||
* - Simuliert Debounce wie im späteren LaserTracker
|
||||
*
|
||||
* Verdrahtung:
|
||||
* Schritt 1 (Push Button):
|
||||
* GPIO 4 ──── Button-Pin 1
|
||||
* GND ──── Button-Pin 2
|
||||
* (kein externer Widerstand nötig – INPUT_PULLUP ist aktiv)
|
||||
*
|
||||
* Erwartetes Verhalten mit INPUT_PULLUP:
|
||||
* Button OFFEN → GPIO = HIGH (3.3V über Pull-Up)
|
||||
* Button GEDRÜCKT → GPIO = LOW (direkt auf GND)
|
||||
* → Polarität: LOW_ACTIVE
|
||||
*
|
||||
* Schritt 2 (Optokoppler / potentialfreier Ausgang):
|
||||
* Gleiche Verdrahtung – Kollektor des Optokopplers an GPIO 4, Emitter an GND
|
||||
*
|
||||
* Serielle Ausgabe: 115200 Baud
|
||||
*
|
||||
* Flash: pio run -e test-button --target upload
|
||||
* Monitor: pio device monitor -e test-button
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
// ---- Pin-Definition (aus config.h übernommen) ----
|
||||
#define LASER_SIGNAL_PIN 4
|
||||
#define DEBOUNCE_MS 50 // Software-Entprellzeit in Millisekunden
|
||||
|
||||
// ---- Zustandsvariablen ----
|
||||
int rawState = HIGH; // aktuell gelesener Rohwert
|
||||
int stableState = HIGH; // entprellter Zustand
|
||||
int lastRaw = HIGH; // letzter Rohwert (für Flanken-Erkennung)
|
||||
uint32_t debounceTimer = 0; // Zeitstempel letzter Flanke
|
||||
|
||||
uint32_t pressStart = 0; // Zeitstempel Tastendruck-Beginn
|
||||
uint32_t pressCount = 0; // Anzahl erkannter Betätigungen
|
||||
|
||||
void printState(int s, bool stable) {
|
||||
if (s == LOW) {
|
||||
Serial.printf("[%8lu ms] GPIO %-3s = LOW (0V) %s → LASER AKTIV\n",
|
||||
millis(), stable ? "ENT" : "RAW", stable ? "✓ STABIL" : "");
|
||||
} else {
|
||||
Serial.printf("[%8lu ms] GPIO %-3s = HIGH (3.3V) %s → LASER INAKTIV\n",
|
||||
millis(), stable ? "ENT" : "RAW", stable ? "✓ STABIL" : "");
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(500);
|
||||
|
||||
Serial.println("================================================");
|
||||
Serial.println(" TEST 1.5 – Potentialfreier Schalter / Button");
|
||||
Serial.println("================================================");
|
||||
Serial.printf(" GPIO Pin: %d\n", LASER_SIGNAL_PIN);
|
||||
Serial.printf(" Modus: INPUT_PULLUP\n");
|
||||
Serial.printf(" Debounce: %d ms\n", DEBOUNCE_MS);
|
||||
Serial.println("------------------------------------------------");
|
||||
Serial.println(" Verdrahtung (Push Button):");
|
||||
Serial.printf(" GPIO %d ──── Button-Pin 1\n", LASER_SIGNAL_PIN);
|
||||
Serial.println(" GND ──── Button-Pin 2");
|
||||
Serial.println("------------------------------------------------");
|
||||
Serial.println(" Erwartetes Verhalten:");
|
||||
Serial.println(" Button OFFEN → HIGH (kein Strom, Pull-Up aktiv)");
|
||||
Serial.println(" Button GEDRÜCKT → LOW (GPIO direkt auf GND)");
|
||||
Serial.println(" → Polarität: LOW_ACTIVE (Standard in config.h)");
|
||||
Serial.println("================================================");
|
||||
Serial.println(" Drücke den Button und beobachte die Ausgabe...");
|
||||
Serial.println();
|
||||
|
||||
pinMode(LASER_SIGNAL_PIN, INPUT_PULLUP);
|
||||
|
||||
stableState = digitalRead(LASER_SIGNAL_PIN);
|
||||
lastRaw = stableState;
|
||||
|
||||
Serial.printf("[INIT] Startzustand: GPIO = %s\n",
|
||||
stableState == LOW ? "LOW (Button gedrückt?)" : "HIGH (offen – OK)");
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
rawState = digitalRead(LASER_SIGNAL_PIN);
|
||||
|
||||
// Flanke erkannt → Debounce-Timer (re)starten
|
||||
if (rawState != lastRaw) {
|
||||
debounceTimer = millis();
|
||||
lastRaw = rawState;
|
||||
}
|
||||
|
||||
// Nach Debounce-Zeit: stabilen Zustand aktualisieren
|
||||
if ((millis() - debounceTimer) >= DEBOUNCE_MS) {
|
||||
if (rawState != stableState) {
|
||||
stableState = rawState;
|
||||
|
||||
if (stableState == LOW) {
|
||||
// Steigende Flanke (Laser aktiv)
|
||||
pressCount++;
|
||||
pressStart = millis();
|
||||
Serial.println("┌─────────────────────────────────────────┐");
|
||||
Serial.printf( "│ BETÄTIGUNG #%3lu – BEGINN │\n", pressCount);
|
||||
printState(stableState, true);
|
||||
Serial.println("└─────────────────────────────────────────┘");
|
||||
|
||||
} else {
|
||||
// Fallende Flanke (Laser inaktiv)
|
||||
uint32_t duration = millis() - pressStart;
|
||||
Serial.println("┌─────────────────────────────────────────┐");
|
||||
Serial.printf( "│ BETÄTIGUNG #%3lu – ENDE │\n", pressCount);
|
||||
printState(stableState, true);
|
||||
Serial.printf( "│ Dauer: %lu ms (%lu s) │\n",
|
||||
duration, duration / 1000);
|
||||
Serial.println("└─────────────────────────────────────────┘");
|
||||
Serial.println();
|
||||
|
||||
// Hinweis für kurze Betätigungen (< Gratiszeit)
|
||||
if (duration < 20000) {
|
||||
Serial.printf(" ℹ Dauer < 20 s → würde als GRATISZEIT gelten (kein Kostenanteil)\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Alle 5 Sekunden Heartbeat ausgeben wenn kein Event
|
||||
static uint32_t lastHeartbeat = 0;
|
||||
if (millis() - lastHeartbeat >= 5000) {
|
||||
lastHeartbeat = millis();
|
||||
Serial.printf("[%8lu ms] Heartbeat | GPIO = %s | Betätigungen: %lu\n",
|
||||
millis(),
|
||||
stableState == LOW ? "LOW (AKTIV) " : "HIGH (inaktiv)",
|
||||
pressCount);
|
||||
}
|
||||
}
|
||||
231
test_sketches/test_display.cpp
Normal file
231
test_sketches/test_display.cpp
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
/**
|
||||
* TEST SKETCH 1.4 – GYMAX7219 Modulnummern-Diagnose
|
||||
*
|
||||
* Jedes Modul zeigt seine eigene 0-basierte Index-Nummer (0..7).
|
||||
* Direkte MD_MAX72XX API – kein Parola, keine Zonen.
|
||||
*
|
||||
* Ablauf:
|
||||
* 1. Alle Module zeigen dauerhaft ihre Indexnummer 0–7
|
||||
* 2. Alle 3 s wird abwechselnd getestet:
|
||||
* a) Alle LEDs EIN (volle Helligkeit → Stromtest)
|
||||
* b) Alle LEDs AUS
|
||||
* c) Jedes Modul zeigt seine Nummer wieder
|
||||
*
|
||||
* Serial Monitor zeigt welcher hw-Typ gerade aktiv ist.
|
||||
* → Nummern richtig/lesbar + Reihenfolge notieren, dann in config.h eintragen.
|
||||
*
|
||||
* Flash: pio run -e test-display --target upload
|
||||
* Monitor: pio device monitor -e test-display
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <MD_MAX72xx.h>
|
||||
#include <SPI.h>
|
||||
|
||||
// ---- Pins ----
|
||||
#define CS_PIN 5
|
||||
#define NUM_MOD 8
|
||||
|
||||
// ---- Zu testende Hardware-Typen ----
|
||||
// Kommentiere einen aus und flashe erneut, bis die Zahlen AUFRECHT stehen.
|
||||
// Dann diesen Typ in config.h als DISPLAY_HW_TYPE eintragen.
|
||||
#define HW_TYPE MD_MAX72XX::GENERIC_HW
|
||||
//#define HW_TYPE MD_MAX72XX::FC16_HW
|
||||
//#define HW_TYPE MD_MAX72XX::PAROLA_HW
|
||||
|
||||
// Lesbare Bezeichnung für Serial (muss zur obigen Wahl passen)
|
||||
#define HW_TYPE_NAME "GENERIC_HW"
|
||||
//#define HW_TYPE_NAME "FC16_HW"
|
||||
//#define HW_TYPE_NAME "PAROLA_HW"
|
||||
|
||||
MD_MAX72XX mx = MD_MAX72XX(HW_TYPE, CS_PIN, NUM_MOD);
|
||||
|
||||
// 5-spaltige 7-Segment-ähnliche Ziffern 0–8 (8 Zeilen, Spalten links→rechts)
|
||||
// Jeder Eintrag: 8 Bytes = 8 Pixelzeilen von oben nach unten
|
||||
static const uint8_t DIGIT[9][8] = {
|
||||
// 0
|
||||
{ 0b00111100,
|
||||
0b01000010,
|
||||
0b01000010,
|
||||
0b01000010,
|
||||
0b01000010,
|
||||
0b01000010,
|
||||
0b00111100,
|
||||
0b00000000 },
|
||||
// 1
|
||||
{ 0b00010000,
|
||||
0b00110000,
|
||||
0b00010000,
|
||||
0b00010000,
|
||||
0b00010000,
|
||||
0b00010000,
|
||||
0b00111000,
|
||||
0b00000000 },
|
||||
// 2
|
||||
{ 0b00111100,
|
||||
0b01000010,
|
||||
0b00000010,
|
||||
0b00001100,
|
||||
0b00110000,
|
||||
0b01000000,
|
||||
0b01111110,
|
||||
0b00000000 },
|
||||
// 3
|
||||
{ 0b00111100,
|
||||
0b01000010,
|
||||
0b00000010,
|
||||
0b00011100,
|
||||
0b00000010,
|
||||
0b01000010,
|
||||
0b00111100,
|
||||
0b00000000 },
|
||||
// 4
|
||||
{ 0b00001000,
|
||||
0b00011000,
|
||||
0b00101000,
|
||||
0b01001000,
|
||||
0b01111110,
|
||||
0b00001000,
|
||||
0b00001000,
|
||||
0b00000000 },
|
||||
// 5
|
||||
{ 0b01111110,
|
||||
0b01000000,
|
||||
0b01000000,
|
||||
0b01111100,
|
||||
0b00000010,
|
||||
0b01000010,
|
||||
0b00111100,
|
||||
0b00000000 },
|
||||
// 6
|
||||
{ 0b00111100,
|
||||
0b01000000,
|
||||
0b01000000,
|
||||
0b01111100,
|
||||
0b01000010,
|
||||
0b01000010,
|
||||
0b00111100,
|
||||
0b00000000 },
|
||||
// 7
|
||||
{ 0b01111110,
|
||||
0b00000010,
|
||||
0b00000100,
|
||||
0b00001000,
|
||||
0b00010000,
|
||||
0b00010000,
|
||||
0b00010000,
|
||||
0b00000000 },
|
||||
// 8
|
||||
{ 0b00111100,
|
||||
0b01000010,
|
||||
0b01000010,
|
||||
0b00111100,
|
||||
0b01000010,
|
||||
0b01000010,
|
||||
0b00111100,
|
||||
0b00000000 },
|
||||
};
|
||||
|
||||
// Dreht eine 8x8 Bitmap 90° gegen den Uhrzeigersinn
|
||||
// Kompensiert die 90° CW physische Ausrichtung der Module
|
||||
// Formel: new[r][c] = old[c][7-r]
|
||||
// → new_row[r] |= (1<<(7-c)) wenn old_row[c] Bit r gesetzt ist
|
||||
void rotateCCW(const uint8_t src[8], uint8_t dst[8]) {
|
||||
memset(dst, 0, 8);
|
||||
for (uint8_t r = 0; r < 8; r++) {
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
if (src[c] & (1 << r)) {
|
||||
dst[r] |= (1 << (7 - c));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Schreibt Ziffer d (0-basiert) in Modul moduleIdx – mit 90° CCW Korrektur
|
||||
void showDigit(uint8_t moduleIdx, uint8_t d) {
|
||||
if (d > 8) d = 8;
|
||||
uint8_t rotated[8];
|
||||
rotateCCW(DIGIT[d], rotated);
|
||||
for (uint8_t row = 0; row < 8; row++) {
|
||||
mx.setRow(moduleIdx, row, rotated[row]);
|
||||
}
|
||||
}
|
||||
|
||||
void allLedsOn() { for (uint8_t m=0;m<NUM_MOD;m++) for(uint8_t r=0;r<8;r++) mx.setRow(m,r,0xFF); }
|
||||
void allLedsOff() { for (uint8_t m=0;m<NUM_MOD;m++) for(uint8_t r=0;r<8;r++) mx.setRow(m,r,0x00); }
|
||||
|
||||
void showAllNumbers() {
|
||||
// Modul 0 zeigt "0", Modul 1 zeigt "1" ... Modul 7 zeigt "7"
|
||||
// (entspricht physischer Modul-Nummerierung 1–8 wenn 0-basiert = 0–7)
|
||||
for (uint8_t i = 0; i < NUM_MOD; i++) {
|
||||
showDigit(i, i); // 0-basierter Index als Ziffer
|
||||
}
|
||||
}
|
||||
|
||||
// Doppelte Initialisierung: alle Module sicher ansprechen, auch wenn
|
||||
// sie beim ersten begin() noch nicht vollständig gebootet waren.
|
||||
static void initDisplay() {
|
||||
mx.begin();
|
||||
mx.control(MD_MAX72XX::INTENSITY, 5);
|
||||
mx.control(MD_MAX72XX::TEST, MD_MAX72XX::OFF);
|
||||
mx.clear();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
// Längere Wartezeit: Module brauchen Zeit zum Hochfahren.
|
||||
// Ohne dies verpassen Module mit langsamerem Power-On-Rise die Init-Sequenz.
|
||||
delay(1000);
|
||||
|
||||
initDisplay();
|
||||
// Zweiter Durchlauf nach kurzer Pause – holt Module nach die beim ersten
|
||||
// Aufruf noch nicht bereit waren (z. B. bei externem Netzteil mit Anlaufverzögerung)
|
||||
delay(200);
|
||||
initDisplay();
|
||||
|
||||
Serial.println("============================================");
|
||||
Serial.println(" MODUL-DIAGNOSE: Jedes Modul zeigt seinen");
|
||||
Serial.println(" 0-basierten Index (0 = erstes in Kette)");
|
||||
Serial.println("============================================");
|
||||
Serial.printf(" HW-Typ: %s\n", HW_TYPE_NAME);
|
||||
Serial.println("--------------------------------------------");
|
||||
Serial.println(" Beobachte welches Modul welche Zahl zeigt:");
|
||||
Serial.println(" 0 = erstes Modul nach ESP32 DIN");
|
||||
Serial.println(" 7 = letztes Modul in der Kette");
|
||||
Serial.println("--------------------------------------------");
|
||||
Serial.println(" Wenn Ziffern auf dem Kopf stehen:");
|
||||
Serial.println(" → anderen HW_TYPE auskommentieren + neu flashen");
|
||||
Serial.println(" Reihenfolge: FC16_HW → PAROLA_HW → GENERIC_HW");
|
||||
Serial.println("============================================");
|
||||
|
||||
// --- Schritt 1: Alle EIN ---
|
||||
Serial.println("\n[1] Alle LEDs EIN (2 s)");
|
||||
allLedsOn();
|
||||
delay(2000);
|
||||
|
||||
// --- Schritt 2: Alle AUS ---
|
||||
Serial.println("[2] Alle LEDs AUS (1 s)");
|
||||
allLedsOff();
|
||||
delay(1000);
|
||||
|
||||
// --- Schritt 3: Modulnummern ---
|
||||
Serial.println("[3] Jedes Modul zeigt seinen 0-Index – dauerhaft");
|
||||
showAllNumbers();
|
||||
Serial.println("\nErwartetes Bild auf der Hardware:");
|
||||
Serial.println(" [0][1][2][3] ← obere Reihe (idx 0 = links)");
|
||||
Serial.println(" [4][5][6][7] ← untere Reihe (idx 7 = rechts)");
|
||||
Serial.println("\nWenn die Ziffern aufrecht und in dieser Reihenfolge");
|
||||
Serial.println("stehen → HW_TYPE korrekt! In config.h übernehmen.");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Alle 4 s: kurz blinken damit man sieht dass der Controller läuft
|
||||
static uint32_t last = 0;
|
||||
if (millis() - last >= 4000) {
|
||||
last = millis();
|
||||
allLedsOff();
|
||||
delay(100);
|
||||
showAllNumbers();
|
||||
Serial.println("[LIVE] Module 0–7 angezeigt");
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user