Dynamically switch between animation framework and UDP control

This commit is contained in:
Thomas Kolb 2019-12-09 23:25:04 +01:00
parent 1bfee92aec
commit c33a5fcade
3 changed files with 97 additions and 14 deletions

View file

@ -16,7 +16,10 @@ public:
UDPProto(Fader *fader);
bool start(uint16_t port);
bool check(void);
bool loop(void);
private:

View file

@ -23,6 +23,22 @@ bool UDPProto::start(uint16_t port)
return true;
}
bool UDPProto::check(void)
{
int packetSize = m_udpServer.parsePacket();
if(packetSize) {
byte buf[1024];
int len;
while((len = m_udpServer.read(buf, 1024)) == 1024) {
// do nothing
}
m_udpServer.endPacket();
return true;
} else {
return false;
}
}
bool UDPProto::loop(void)
{
byte cmd[WS2801_CMD_LEN];

View file

@ -87,6 +87,82 @@ bool initLEDs()
return true;
}
enum LEDState {
UDP,
ANIMATION,
TRANSITION
};
static void ledFSM(void)
{
static bool stateEntered = true;
static LEDState ledState = ANIMATION;
static LEDState nextState;
static unsigned long lastUDPUpdate = 0;
LEDState lastState = ledState;
switch(ledState) {
case ANIMATION:
Serial.print("A");
if(stateEntered) {
animController.restart();
}
animController.loop();
if(animController.isIdle()) {
animController.changeAnimation(std::unique_ptr<Animation>(new FireAnimation(&ledFader, false)));
}
if(((WiFi.status() == WL_CONNECTED) || (WiFi.getMode() == WIFI_MODE_AP)) &&
udpProto.check()) {
// UDP packet received -> transition to UDP state
nextState = UDP;
ledState = TRANSITION;
}
break;
case UDP:
Serial.print("U");
if((WiFi.status() != WL_CONNECTED) && (WiFi.getMode() != WIFI_MODE_AP)) {
// WiFi disconnected -> switch to animation immediately to show reconnect animation
ledState = ANIMATION;
break;
}
if(udpProto.loop()) {
lastUDPUpdate = millis();
ledFader.update();
} else if(millis() - lastUDPUpdate > 3000) {
// seems like no more UDP data arrives -> transition to ANIMATION state
nextState = ANIMATION;
ledState = TRANSITION;
}
break;
case TRANSITION:
Serial.print("T");
if(stateEntered) {
ledFader.set_fadestep(2);
ledFader.fade_color(Fader::Color{0, 0, 0, 0});
}
ledFader.update();
if(!ledFader.something_changed()) {
// transition finished
ledState = nextState;
lastUDPUpdate = millis();
}
break;
}
stateEntered = (lastState != ledState);
}
static void ledTask( void * parameter )
{
uint64_t frame = 0;
@ -96,15 +172,7 @@ static void ledTask( void * parameter )
uint32_t start_time = micros();
animController.loop();
if(animController.isIdle()) {
animController.changeAnimation(std::unique_ptr<Animation>(new FireAnimation(&ledFader, false)));
}
if((WiFi.status() == WL_CONNECTED) || (WiFi.getMode() == WIFI_MODE_AP)) {
udpProto.loop();
}
ledFSM();
led_idx++;
if(led_idx >= STRANDS[0].numPixels) {
@ -117,10 +185,6 @@ static void ledTask( void * parameter )
strands[i] = &STRANDS[i];
}
if(animController.isIdle()) {
ledFader.update();
}
if(ledFader.something_changed()) {
const std::vector<Fader::Color> &colors = ledFader.get_color_values();