/** * 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 // ---- 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); } }