#pragma once // MARK: State definition #include #include "config.h" enum class ProgramState { fadeToGreen = 1, stayGreen = 2, fadeToRed = 3, fadePulseLow = 4, fadePulseHigh = 5, fadeToSleeping = 6, sleeping = 7, toggleDemoMode = 8, }; struct FadeComponent { // Timestamps for next fade step uint32_t nextFade; // Intervals in ms for each fade step uint32_t interval; // Fade direction for each component uint8_t direction; // Indicator to alternate between LED batches uint8_t skip; // Current color uint8_t color; // Target color uint8_t endColor; uint8_t needsStep(uint32_t time) { if (isDone()) { return 0; } return time >= nextFade; } uint8_t isDone() { return color == endColor; } uint8_t nextColor() { return color + direction; } uint8_t advanceSkipAndColorIfNeeded() { skip = (skip + 1) % LED_BATCH_COUNT; nextFade += interval; if (skip) { // Only update color when all batches are done // i.e. when skip is zero return interval; } if (isDone()) { return 255; } color += direction; return interval; } void setNewColor(uint8_t newColor, uint32_t time, uint32_t duration) { endColor = newColor; nextFade = time; skip = 0; if (isDone()) { interval = 255; direction = 0; return; } uint8_t steps; if (endColor > color) { steps = endColor - color; direction = 1; } else { steps = color - endColor; direction = -1; } interval = (duration / steps) / LED_BATCH_COUNT; } };