107 lines
3.3 KiB
C++
107 lines
3.3 KiB
C++
#include <user_config.h>
|
|
#include <SmingCore/SmingCore.h>
|
|
#include <algorithm>
|
|
|
|
#include <SpejsNode.h>
|
|
|
|
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());
|
|
}
|