#include #include #include #include extern "C" { #include "ws2812_i2s.h" } #define LEDS_CNT 150 enum LEDMode { IDLE, OFF, WHITE, STROBE, BRIGHT, TEST, }; class LEDEndpoint : public Endpoint { private: struct __attribute__((packed)) { uint8_t g; uint8_t r; uint8_t b; } leds[LEDS_CNT]; enum LEDMode currentMode = LEDMode::IDLE; Timer animationTimer; void animate() { /*if (i % 50 == 0) WDT.alive();*/ static int frameCounter = 0; frameCounter++; for(int i = 0; i < LEDS_CNT; i++) { switch(currentMode) { case LEDMode::IDLE: leds[i].r = std::max(sin(i * 2*PI/LEDS_CNT - millis() / 1000.0)/2 * 255, 0.0); leds[i].g = std::max(sin(i * 2*PI/LEDS_CNT + millis() / 500.0)/2 * 255, 0.0); leds[i].b = std::max(sin(i * 2*PI/LEDS_CNT + millis() / 420.0)/2 * 255, 0.0); break; case LEDMode::TEST: leds[i].r = std::min(std::max((sin(i * 2*PI/LEDS_CNT - millis() / 1000.0)/2 + 0.2) * 255, 0.0), 255.0); leds[i].g = std::min(std::max((sin(i * 2*PI/LEDS_CNT + millis() / 500.0)/2 + 0.2) * 255, 0.0), 255.0); leds[i].b = std::min(std::max((sin(i * 2*PI/LEDS_CNT + millis() / 420.0)/2 + 0.2) * 255, 0.0), 255.0); break; case LEDMode::BRIGHT: leds[i].r = std::min(std::max((sin(i * 2*PI/LEDS_CNT - millis() / 1000.0)/4 + 0.5) * 255, 0.0), 255.0); leds[i].g = std::min(std::max((sin(i * 2*PI/LEDS_CNT + millis() / 500.0)/4 + 0.5) * 255, 0.0), 255.0); leds[i].b = std::min(std::max((sin(i * 2*PI/LEDS_CNT + millis() / 420.0)/4 + 0.5) * 255, 0.0), 255.0); break; case LEDMode::OFF: leds[i].r = leds[i].g = leds[i].b = 0; break; case LEDMode::WHITE: leds[i].r = leds[i].g = leds[i].b = 255; break; case LEDMode::STROBE: leds[i].r = leds[i].g = leds[i].b = (frameCounter % 2) ? 255 : 0; break; } } ws2812_push((uint8_t*) leds, sizeof(leds)); } public: LEDEndpoint() : Endpoint("leds", { {"mode", "enum", true, "idle,off,white,strobe,bright,test", "Current LED mode"}, }) { animationTimer.initializeMs(50, TimerDelegate(&LEDEndpoint::animate, this)).start(); ws2812_init(); } EndpointResult onValue(String property, String value) { if (property != "mode") { return 400; } if (value == "idle") currentMode = LEDMode::IDLE; else if (value == "off") currentMode = LEDMode::OFF; else if (value == "white") currentMode = LEDMode::WHITE; else if (value == "strobe") currentMode = LEDMode::STROBE; else if (value == "bright") currentMode = LEDMode::BRIGHT; else if (value == "test") currentMode = LEDMode::TEST; else { return 400; } notify("mode", value); return 200; } }; SpejsNode node("ledcontroller"); void init() { node.init(); node.registerEndpoint("leds", new LEDEndpoint()); }