From 505367d6a89ef02b8b6a2919565b023cd0c21632 Mon Sep 17 00:00:00 2001 From: Jean Jacques Avril Date: Sat, 4 Oct 2025 11:20:49 +0200 Subject: [PATCH] led state applier --- lib/hardware/hardware_led.cpp | 121 ++++++++++++++++++++++++++++++++++ lib/hardware/hardware_led.hpp | 37 +++++++++++ src/main.cpp | 64 +++++++++++++++--- 3 files changed, 213 insertions(+), 9 deletions(-) create mode 100644 lib/hardware/hardware_led.cpp create mode 100644 lib/hardware/hardware_led.hpp diff --git a/lib/hardware/hardware_led.cpp b/lib/hardware/hardware_led.cpp new file mode 100644 index 0000000..f33d04b --- /dev/null +++ b/lib/hardware/hardware_led.cpp @@ -0,0 +1,121 @@ +#include "hardware_led.hpp" +#include + +HardwareLed::HardwareLed(uint8_t pin, uint8_t numPixels) + : _strip(numPixels, pin, NEO_GRB + NEO_KHZ800), _isActive(false) {} + +void HardwareLed::begin() { + _strip.begin(); + _strip.show(); // Turn off +} + +void HardwareLed::end() { + _strip.clear(); + _strip.show(); +} + +void HardwareLed::update() { + if (!_isActive) return; + + unsigned long now = millis(); + if (_currentConfig.duration_ms > 0 && now - _startTime >= _currentConfig.duration_ms) { + _isActive = false; + _strip.clear(); + _strip.show(); + return; + } + + switch (_currentConfig.which_animation_params) { + case hardware_LedConfig_static_params_tag: + applyStatic(_currentConfig.animation_params.static_params); + break; + case hardware_LedConfig_pulse_params_tag: + applyPulse(_currentConfig.animation_params.pulse_params); + break; + case hardware_LedConfig_fade_params_tag: + applyFade(_currentConfig.animation_params.fade_params); + break; + case hardware_LedConfig_flicker_params_tag: + applyFlicker(_currentConfig.animation_params.flicker_params); + break; + default: + break; + } +} + +void HardwareLed::set(const hardware_LedConfig& config) { + _currentConfig = config; + _startTime = millis(); + _isActive = true; + _pulseState = 0; + _lastPulseTime = _startTime; + _fadeIndex = 0; + _lastFadeTime = _startTime; + if (_currentConfig.which_animation_params == 5 && _currentConfig.animation_params.fade_params.colors_count > 0) { + _fadeCurrentColor = _currentConfig.animation_params.fade_params.colors[0]; + _fadeTargetColor = _currentConfig.animation_params.fade_params.colors[0]; + _fadeProgress = 1.0f; + _fadeStartTime = _startTime; + } + // Immediately apply initial state + update(); +} + +void HardwareLed::applyStatic(const hardware_StaticParams& params) { + setColor(params.color, _currentConfig.brightness); +} + +void HardwareLed::applyPulse(const hardware_PulseParams& params) { + unsigned long now = millis(); + float phase = fmod((now - _startTime) / (float)params.speed_ms, 1.0f); + float brightnessFactor = 0.5f + 0.5f * sin(2 * PI * phase); + uint8_t pulseBrightness = _currentConfig.brightness * brightnessFactor; + setColor(params.color, pulseBrightness); +} + +void HardwareLed::applyFade(const hardware_FadeParams& params) { + if (params.colors_count == 0) return; + unsigned long now = millis(); + if (_fadeProgress >= 1.0f) { + // Time to switch to next color + _fadeIndex = (_fadeIndex + 1) % params.colors_count; + _fadeCurrentColor = _fadeTargetColor; + _fadeTargetColor = params.colors[_fadeIndex]; + _fadeProgress = 0.0f; + _fadeStartTime = now; + } + _fadeProgress = (now - _fadeStartTime) / (float)params.speed_ms; + if (_fadeProgress > 1.0f) _fadeProgress = 1.0f; + uint32_t interpolatedColor = lerpColor(_fadeCurrentColor, _fadeTargetColor, _fadeProgress); + setColor(interpolatedColor, _currentConfig.brightness); +} + +void HardwareLed::applyFlicker(const hardware_FlickerParams& params) { + // Simple random flicker based on intensity + uint8_t threshold = map(params.intensity, 0, 100, 0, 255); + if (random(255) < threshold) { + setColor(params.color, _currentConfig.brightness); + } else { + _strip.clear(); + _strip.show(); + } +} + +void HardwareLed::setColor(uint32_t color, uint8_t brightness) { + _strip.setBrightness(brightness); + _strip.setPixelColor(0, color); + _strip.show(); +} + +uint32_t HardwareLed::lerpColor(uint32_t color1, uint32_t color2, float t) { + uint8_t r1 = (color1 >> 16) & 0xFF; + uint8_t g1 = (color1 >> 8) & 0xFF; + uint8_t b1 = color1 & 0xFF; + uint8_t r2 = (color2 >> 16) & 0xFF; + uint8_t g2 = (color2 >> 8) & 0xFF; + uint8_t b2 = color2 & 0xFF; + uint8_t r = r1 + (r2 - r1) * t; + uint8_t g = g1 + (g2 - g1) * t; + uint8_t b = b1 + (b2 - b1) * t; + return (r << 16) | (g << 8) | b; +} \ No newline at end of file diff --git a/lib/hardware/hardware_led.hpp b/lib/hardware/hardware_led.hpp new file mode 100644 index 0000000..c2333ed --- /dev/null +++ b/lib/hardware/hardware_led.hpp @@ -0,0 +1,37 @@ +#ifndef HARDWARE_LED_HPP +#define HARDWARE_LED_HPP + +#include "hardware.pb.h" +#include + +class HardwareLed { +public: + HardwareLed(uint8_t pin, uint8_t numPixels = 1); + void begin(); + void end(); + void update(); + void set(const hardware_LedConfig& config); + +private: + void applyStatic(const hardware_StaticParams& params); + void applyPulse(const hardware_PulseParams& params); + void applyFade(const hardware_FadeParams& params); + void applyFlicker(const hardware_FlickerParams& params); + void setColor(uint32_t color, uint8_t brightness = 255); + uint32_t lerpColor(uint32_t color1, uint32_t color2, float t); + + Adafruit_NeoPixel _strip; + hardware_LedConfig _currentConfig; + unsigned long _startTime; + uint8_t _pulseState; + unsigned long _lastPulseTime; + uint8_t _fadeIndex; + unsigned long _lastFadeTime; + uint32_t _fadeCurrentColor; + uint32_t _fadeTargetColor; + float _fadeProgress; + unsigned long _fadeStartTime; + bool _isActive; +}; + +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index cb9fbba..8fcefa1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,18 +1,64 @@ #include +#include +#include "hardware.pb.h" -// put function declarations here: -int myFunction(int, int); +// Demo for HardwareLed +HardwareLed led(2); // Assuming NeoPixel on pin 4 (D2 on ESP8266) + +hardware_LedConfig configs[4]; +unsigned long lastChange = 0; +int currentConfig = 0; void setup() { - // put your setup code here, to run once: - int result = myFunction(2, 3); + Serial.begin(9600); + led.begin(); + + // Static config + configs[0] = {0}; + configs[0].brightness = 128; + configs[0].duration_ms = 0; + configs[0].which_animation_params = 3; + configs[0].animation_params.static_params.color = 0x00FF00; // Green + + // Pulse config + configs[1] = {0}; + configs[1].brightness = 128; + configs[1].duration_ms = 0; + configs[1].which_animation_params = 4; + configs[1].animation_params.pulse_params.color = 0xFF0000; // Red + configs[1].animation_params.pulse_params.speed_ms = 500; + + // Fade config + configs[2] = {0}; + configs[2].brightness = 128; + configs[2].duration_ms = 0; + configs[2].which_animation_params = 5; + configs[2].animation_params.fade_params.colors_count = 3; + configs[2].animation_params.fade_params.colors[0] = 0xFF0000; // Red + configs[2].animation_params.fade_params.colors[1] = 0x00FF00; // Green + configs[2].animation_params.fade_params.colors[2] = 0x0000FF; // Blue + configs[2].animation_params.fade_params.speed_ms = 1000; + + // Flicker config + configs[3] = {0}; + configs[3].brightness = 128; + configs[3].duration_ms = 0; + configs[3].which_animation_params = 6; + configs[3].animation_params.flicker_params.color = 0xFFFFFF; // White + configs[3].animation_params.flicker_params.intensity = 50; + + led.set(configs[0]); + Serial.println("Starting with static green"); } void loop() { - // put your main code here, to run repeatedly: -} + led.update(); -// put function definitions here: -int myFunction(int x, int y) { - return x + y; + if (millis() - lastChange >= 10000) { + lastChange = millis(); + currentConfig = (currentConfig + 1) % 4; + led.set(configs[currentConfig]); + Serial.print("Switched to config "); + Serial.println(currentConfig); + } } \ No newline at end of file