/* WS2812FX Webinterface. Harm Aldick - 2016 www.aldick.org FEATURES * Webinterface with mode, color, speed and brightness selectors LICENSE: The MIT License (MIT) Copyright (c) 2016 Harm Aldick CHANGELOG 2016-11-26 initial version Tanner Collin: 2017-09-14 Create Wifi AP to anyone can configure the LEDs. Set up captive portal so web interface auto opens. Clean up. */ #include #include #include #include #include #include #include "index.html.h" #include "main.js.h" const char *ssid = "ADD SSID HERE"; const char *myHostname = "ws2812"; #define HTTP_PORT 80 #define DNS_PORT 53 // QUICKFIX...See https://github.com/esp8266/Arduino/issues/263 #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) #define LED_PIN D7 // 0 = GPIO0, 2=GPIO2 #define LED_COUNT 80 #define DEFAULT_COLOR 0xFF5900 #define DEFAULT_BRIGHTNESS 255 #define DEFAULT_SPEED 200 #define DEFAULT_MODE FX_MODE_STATIC #define BRIGHTNESS_STEP 15 // in/decrease brightness by this amount per click #define SPEED_STEP 10 // in/decrease brightness by this amount per click String modes = ""; WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); ESP8266WebServer server(HTTP_PORT); DNSServer dnsServer; IPAddress apIP(192, 168, 4, 1); IPAddress netMsk(255, 255, 255, 0); void setup(){ Serial.begin(115200); Serial.println(); Serial.println(); Serial.println("Starting..."); modes.reserve(5000); modes_setup(); Serial.println("WS2812FX setup"); ws2812fx.init(); ws2812fx.setMode(DEFAULT_MODE); ws2812fx.setColor(DEFAULT_COLOR); ws2812fx.setSpeed(DEFAULT_SPEED); ws2812fx.setBrightness(DEFAULT_BRIGHTNESS); ws2812fx.start(); Serial.println("Wifi setup"); WiFi.softAPConfig(apIP, apIP, netMsk); WiFi.softAP(ssid); delay(500); IPAddress myIP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(myIP); dnsServer.setErrorReplyCode(DNSReplyCode::NoError); dnsServer.start(DNS_PORT, "*", apIP); Serial.println("HTTP server setup"); server.on("/", srv_handle_index_html); server.on("/main.js", srv_handle_main_js); server.on("/modes", srv_handle_modes); server.on("/set", srv_handle_set); server.on("/generate_204", srv_handle_index_html); //Android captive portal. Maybe not needed. Might be handled by notFound handler. server.on("/fwlink", srv_handle_index_html); //Microsoft captive portal. Maybe not needed. Might be handled by notFound handler. server.onNotFound(srv_handle_not_found); server.begin(); Serial.println("HTTP server started."); Serial.println("ready!"); } void loop() { dnsServer.processNextRequest(); server.handleClient(); ws2812fx.service(); } /* * Build
  • string for all modes. */ void modes_setup() { modes = ""; for(uint8_t i=0; i < ws2812fx.getModeCount(); i++) { modes += "
  • "; modes += ws2812fx.getModeName(i); modes += "
  • "; } } /* ##################################################### # Webserver Functions ##################################################### */ void srv_handle_not_found() { server.send(404, "text/plain", "File Not Found"); } void srv_handle_index_html() { server.send_P(200,"text/html", index_html); } void srv_handle_main_js() { server.send_P(200,"application/javascript", main_js); } void srv_handle_modes() { server.send(200,"text/plain", modes); } void srv_handle_set() { for (uint8_t i=0; i < server.args(); i++){ if(server.argName(i) == "c") { uint32_t tmp = (uint32_t) strtol(&server.arg(i)[0], NULL, 16); if(tmp >= 0x000000 && tmp <= 0xFFFFFF) { ws2812fx.setColor(tmp); } } if(server.argName(i) == "m") { uint8_t tmp = (uint8_t) strtol(&server.arg(i)[0], NULL, 10); ws2812fx.setMode(tmp % ws2812fx.getModeCount()); } if(server.argName(i) == "b") { if(server.arg(i)[0] == '-') { ws2812fx.decreaseBrightness(BRIGHTNESS_STEP); } else { ws2812fx.increaseBrightness(BRIGHTNESS_STEP); } } if(server.argName(i) == "s") { if(server.arg(i)[0] == '-') { ws2812fx.decreaseSpeed(SPEED_STEP); } else { ws2812fx.increaseSpeed(SPEED_STEP); } } } server.send(200, "text/plain", "OK"); }