// Week 14 — WS2812B web interface on XIAO ESP32-C3 // Libraries: Adafruit NeoPixel, ESP32 WebServer (built-in) #include #include #include #define PIN_NEO D3 #define NUMPIXELS 10 const char *AP_SSID = "HGN_C3"; const char *AP_PASS = "fabacademy"; static const char INDEX_HTML[] PROGMEM = R"rawliteral( WS2812B Controller

WS2812B — 10 LED Controller

Week 14 · XIAO ESP32-C3 · Week 8 board

Whole strip
Individual LEDs
)rawliteral"; Adafruit_NeoPixel pixels(NUMPIXELS, PIN_NEO, NEO_GRB + NEO_KHZ800); WebServer server(80); bool stripOn = true; uint8_t globalBrightness = 80; bool pixelOn[NUMPIXELS]; uint8_t pixelR[NUMPIXELS]; uint8_t pixelG[NUMPIXELS]; uint8_t pixelB[NUMPIXELS]; uint8_t pixelBr[NUMPIXELS]; void applyPixels() { pixels.setBrightness(globalBrightness); pixels.clear(); if (stripOn) { for (int i = 0; i < NUMPIXELS; i++) { if (pixelOn[i]) { uint32_t r = (uint32_t)pixelR[i] * pixelBr[i] / 255; uint32_t g = (uint32_t)pixelG[i] * pixelBr[i] / 255; uint32_t b = (uint32_t)pixelB[i] * pixelBr[i] / 255; pixels.setPixelColor(i, pixels.Color(r, g, b)); } } } pixels.show(); } void sendJsonOk() { server.send(200, "application/json", "{\"ok\":true}"); } void handleRoot() { server.send_P(200, "text/html", INDEX_HTML); } void handleStrip() { if (server.hasArg("on")) { stripOn = server.arg("on").toInt() != 0; applyPixels(); } sendJsonOk(); } void handleGlobalBrightness() { if (server.hasArg("val")) { globalBrightness = constrain(server.arg("val").toInt(), 0, 255); applyPixels(); } sendJsonOk(); } void handleLed() { if (!server.hasArg("id")) { server.send(400, "application/json", "{\"ok\":false}"); return; } int id = server.arg("id").toInt(); if (id < 0 || id >= NUMPIXELS) { server.send(400, "application/json", "{\"ok\":false}"); return; } if (server.hasArg("on")) pixelOn[id] = server.arg("on").toInt() != 0; if (server.hasArg("r")) pixelR[id] = constrain(server.arg("r").toInt(), 0, 255); if (server.hasArg("g")) pixelG[id] = constrain(server.arg("g").toInt(), 0, 255); if (server.hasArg("b")) pixelB[id] = constrain(server.arg("b").toInt(), 0, 255); if (server.hasArg("br")) pixelBr[id] = constrain(server.arg("br").toInt(), 0, 255); applyPixels(); sendJsonOk(); } void handleState() { String json = "{\"stripOn\":" + String(stripOn ? "true" : "false"); json += ",\"globalBrightness\":" + String(globalBrightness); json += ",\"leds\":["; for (int i = 0; i < NUMPIXELS; i++) { if (i) json += ","; json += "{\"on\":" + String(pixelOn[i] ? 1 : 0); json += ",\"r\":" + String(pixelR[i]); json += ",\"g\":" + String(pixelG[i]); json += ",\"b\":" + String(pixelB[i]); json += ",\"br\":" + String(pixelBr[i]) + "}"; } json += "]}"; server.send(200, "application/json", json); } void setupRoutes() { server.on("/", HTTP_GET, handleRoot); server.on("/api/strip", HTTP_GET, handleStrip); server.on("/api/brightness", HTTP_GET, handleGlobalBrightness); server.on("/api/led", HTTP_GET, handleLed); server.on("/api/state", HTTP_GET, handleState); server.begin(); } void setup() { Serial.begin(115200); for (int i = 0; i < NUMPIXELS; i++) { pixelOn[i] = false; pixelR[i] = 0; pixelG[i] = 80; pixelB[i] = 255; pixelBr[i] = 200; } pixels.begin(); pixels.clear(); pixels.show(); WiFi.mode(WIFI_AP); WiFi.softAP(AP_SSID, AP_PASS); Serial.print(F("AP: ")); Serial.println(AP_SSID); Serial.print(F("URL: http://")); Serial.println(WiFi.softAPIP()); setupRoutes(); } void loop() { server.handleClient(); }