// Fab Academy 2026 — Week 14 — Individual assignment // XIAO RP2040 ↔ Node-RED over USB serial // // Hardware (Week 06 PCB): // D9 → LED (output, active HIGH) // D10 → push button via external 10k pull-down to GND, switch closes to 3V3 // → pressed = HIGH, released = LOW // // Protocol (newline-terminated plain text): // Board → host: "PRESSED\n" on rising edge (button pushed down, debounced) // "RELEASED\n" on falling edge (button let go, debounced) // Host → board: "ON\n" → LED on // "OFF\n" → LED off const int LED_PIN = D9; const int BUTTON_PIN = D10; const unsigned long DEBOUNCE_MS = 50; int lastStableState = LOW; // external pull-down: LOW = released int lastReadState = LOW; unsigned long lastChangeMs = 0; String inputBuffer = ""; void setup() { pinMode(LED_PIN, OUTPUT); pinMode(BUTTON_PIN, INPUT); // external pull-down on the PCB, no internal pull needed digitalWrite(LED_PIN, LOW); Serial.begin(9600); } void loop() { handleButton(); handleSerial(); } void handleButton() { int reading = digitalRead(BUTTON_PIN); if (reading != lastReadState) { lastChangeMs = millis(); lastReadState = reading; } if ((millis() - lastChangeMs) > DEBOUNCE_MS) { if (reading != lastStableState) { lastStableState = reading; if (lastStableState == HIGH) { Serial.println("PRESSED"); } else { Serial.println("RELEASED"); } } } } void handleSerial() { while (Serial.available() > 0) { char c = Serial.read(); if (c == '\n' || c == '\r') { if (inputBuffer.length() > 0) { if (inputBuffer == "ON") digitalWrite(LED_PIN, HIGH); else if (inputBuffer == "OFF") digitalWrite(LED_PIN, LOW); inputBuffer = ""; } } else { inputBuffer += c; } } }