From 6685e9742e798d4054c5513f07ddae0caa84acb6 Mon Sep 17 00:00:00 2001 From: Tropicananass Date: Sat, 13 Feb 2021 13:45:48 +0100 Subject: [PATCH] wip preset --- src/main.cpp | 401 +++++++++++++++++++++++++++++++++------------- src/main.cpp.echo | 32 ++++ 2 files changed, 321 insertions(+), 112 deletions(-) create mode 100644 src/main.cpp.echo diff --git a/src/main.cpp b/src/main.cpp index dd3a143..e79aeda 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,7 +4,7 @@ #include #include -#include "Button.hpp" +#include "button.hpp" #include "pin_map.hpp" /* Types and Constants */ @@ -12,22 +12,24 @@ /* State machine */ #define FOREACH_MODE(MODE) \ - MODE(ControlOff) \ - MODE(LightOn) \ + MODE(Init) \ + MODE(Preset) \ MODE(SetColor) \ MODE(SetSaturation) \ MODE(SetBrightness) \ - MODE(Shift) + MODE(LightOn) \ + MODE(Shift) \ + MODE(ControlOff) #define GENERATE_MODE_ENUM(ENUM) ENUM, enum class Mode_e { FOREACH_MODE(GENERATE_MODE_ENUM) }; +/* cyclic increment operator for mode_e */ Mode_e &operator++(Mode_e &mode) { - if (mode == Mode_e::Shift) { - return mode = Mode_e::ControlOff; + if (mode == Mode_e::ControlOff) { + return mode = Mode_e::Preset; } - return mode = static_cast(static_cast(mode) + 1); } @@ -42,13 +44,81 @@ uint8_t static const ColorSaturation{128}; uint8_t static const ColorArray[3][3] = { {ColorSaturation, 0, 0}, {0, ColorSaturation, 0}, {0, 0, ColorSaturation}}; -/* Led ring state */ +/* Led ring color and led count state */ typedef struct { uint16_t ledOnCounter; uint16_t ledOnShift; uint16_t hue; uint8_t saturation; uint8_t brightness; +} LedRingColorState_t; + +uint8_t const PresetMax{8}; + +// https://hslpicker.com/ = {0, 40, 50, 110, 240, 280, 310, 360 for white} +uint16_t const PresetHue[PresetMax] = {0, 7282, 9102, 20025, 43691, 50972, 56434, 65535}; + +uint8_t const PresetLevelMax{3}; + +uint8_t const PresetBrightness[PresetLevelMax] = {16, 64, 127}; + +// LedRingColorState_t const Preset[PresetMax] = {{ +// .ledOnCounter = LedCount, +// .ledOnShift = 0, +// .hue = 0, +// .saturation = 255, +// .brightness = 255 +// }, { +// .ledOnCounter = LedCount, +// .ledOnShift = 0, +// .hue = 28, +// .saturation = 255, +// .brightness = 255 +// }, { +// .ledOnCounter = LedCount, +// .ledOnShift = 0, +// .hue = 36, +// .saturation = 255, +// .brightness = 255 +// }, { +// .ledOnCounter = LedCount, +// .ledOnShift = 0, +// .hue = 78, +// .saturation = 255, +// .brightness = 255 +// }, { +// .ledOnCounter = LedCount, +// .ledOnShift = 0, +// .hue = 171, +// .saturation = 255, +// .brightness = 16, +// }, { +// .ledOnCounter = LedCount, +// .ledOnShift = 0, +// .hue = 199, +// .saturation = 255, +// .brightness = 16, +// }, { +// .ledOnCounter = LedCount, +// .ledOnShift = 0, +// .hue = 220, +// .saturation = 255, +// .brightness = 16, +// } +// }; + +/* Preset state */ +typedef struct { + bool isActive; + uint8_t index; + uint8_t level; +} PresetState_t; + +/* Led ring system state */ +typedef struct { + LedRingColorState_t ledRingColorState; + PresetState_t presetState; + Mode_e currentMode; } LedRingState_t; /* Button */ @@ -57,16 +127,21 @@ int const AnalogButtonVRef{970}; /* Global variables */ /*----------------------------------------------------------------------------------------------*/ -/* State machine */ -Mode_e currentMode{Mode_e::ControlOff}; - /* Led ring state */ -LedRingState_t ledRingState{ - .ledOnCounter = LedCount / 2, - .ledOnShift = LedCount / 4, - .hue = 0, - .saturation = 255, - .brightness = 16, +LedRingState_t ledRingState { + .ledRingColorState = { + .ledOnCounter = LedCount / 2, + .ledOnShift = 0, + .hue = 0, + .saturation = 255, + .brightness = 16 + }, + .presetState = { + .isActive = false, + .index = 0, + .level = 0 + }, + .currentMode = Mode_e::Init }; /* IO Objects */ @@ -94,15 +169,28 @@ HardwareSerial &debugSerial = Serial; FOREACH_MODE(GENERATE_MODE_EXEC_DECLARTION) /* Encoder */ +void analog_button_calibration(void); + int get_encoder_shift(void); -void refresh_led_ring(void); +void display_mode(Mode_e mode); -void analog_button_calibration(void); +void display_led_ring(void); + +void refresh_led_ring(LedRingColorState_t const &ledRingColorState = ledRingState.ledRingColorState); /* Function definitions */ /*----------------------------------------------------------------------------------------------*/ void setup() { + + ledRing.begin(); + ledRing.fill(Adafruit_NeoPixel::Color(45, 0, 0)); + delay(300); + ledRing.fill(Adafruit_NeoPixel::Color(0, 45, 0)); + delay(300); + ledRing.fill(Adafruit_NeoPixel::Color(0, 0, 45)); + delay(300); + #ifdef DEBUG debugSerial.begin(9600); while (!debugSerial.available()) @@ -110,37 +198,43 @@ void setup() { debugSerial.println("Init ... "); #endif /*DEBUG*/ - ledRing.begin(); - refresh_led_ring(); - analog_button_calibration(); get_encoder_shift(); #ifdef DEBUG - debugSerial.println(mode_str[static_cast(currentMode)]); + debugSerial.println(mode_str[static_cast(ledRingState.currentMode)]); #endif /*DEBUG*/ } void loop() { + bool hasModeChanged{false}; int shift{get_encoder_shift()}; if (button.is_button_pressed()) { while (button.is_button_pressed()) { delay(150); } - ++currentMode; + ++ledRingState.currentMode; + #ifdef DEBUG - debugSerial.println(mode_str[static_cast(currentMode)]); + debugSerial.println(mode_str[static_cast(ledRingState.currentMode)]); #endif /*DEBUG*/ + + display_mode(ledRingState.currentMode); + hasModeChanged = true; } if (shift != 0) { - switch (currentMode) { + switch (ledRingState.currentMode) { case Mode_e::ControlOff: ControlOff_execute(shift); break; + case Mode_e::Preset: + Preset_execute(shift); + break; + case Mode_e::LightOn: LightOn_execute(shift); break; @@ -166,15 +260,89 @@ void loop() { } } - if (currentMode != Mode_e::ControlOff && shift != 0) { - refresh_led_ring(); + if (ledRingState.currentMode != Mode_e::ControlOff && (shift != 0 || hasModeChanged)) { + display_led_ring(); } } +/* State Machine functions */ + void ControlOff_execute(int shift) {} +void Preset_execute(int shift) { + PresetState_t &preset = ledRingState.presetState; + + if (shift > 0) { + ++preset.index; + if (preset.index >= PresetMax) { + preset.index = 0; + ++preset.level; + if (preset.level >= PresetLevelMax) { + preset.level = 0; + } + } + } else { + --preset.index; + if (preset.index == UINT8_MAX) { + preset.index = PresetMax - 1; + --preset.level; + if (preset.level == UINT8_MAX) { + preset.level = PresetLevelMax - 1; + } + } + } +} /* Preset_execute */ + +void SetColor_execute(int shift) { + uint16_t &hue = ledRingState.ledRingColorState.hue; + + hue += (shift << 8); + +#if defined(DEBUG) && defined(ARDUINO_AVR_UNO) + if (shift != 0) { + debugSerial.print(__func__); + debugSerial.print(" : shift="); + debugSerial.print(shift, DEC); + debugSerial.print(", hue="); + debugSerial.println(hue, DEC); + } +#endif /*defined(DEBUG) && defined(ARDUINO_AVR_UNO)*/ +} /* SetColor_execute */ + +void SetBrightness_execute(int shift) { + uint8_t &brightness = ledRingState.ledRingColorState.brightness; + + brightness += (shift << 2); + +#if defined(DEBUG) && defined(ARDUINO_AVR_UNO) + if (shift != 0) { + debugSerial.print(__func__); + debugSerial.print(" : shift="); + debugSerial.print(shift, DEC); + debugSerial.print(", brightness="); + debugSerial.println(brightness, DEC); + } +#endif /*defined(DEBUG) && defined(ARDUINO_AVR_UNO)*/ +} /* SetBrightness_execute */ + +void SetSaturation_execute(int shift) { + uint8_t &saturation = ledRingState.ledRingColorState.saturation; + + saturation += (shift << 2); + +#if defined(DEBUG) && defined(ARDUINO_AVR_UNO) + if (shift != 0) { + debugSerial.print(__func__); + debugSerial.print(" : shift="); + debugSerial.print(shift, DEC); + debugSerial.print(", saturation="); + debugSerial.println(saturation, DEC); + } +#endif /*defined(DEBUG) && defined(ARDUINO_AVR_UNO)*/ +} /* SetSaturation_execute */ + void LightOn_execute(int shift) { - uint16_t &ledOnCounter = ledRingState.ledOnCounter; + uint16_t &ledOnCounter = ledRingState.ledRingColorState.ledOnCounter; if (shift > 0) { ++ledOnCounter; @@ -197,42 +365,10 @@ void LightOn_execute(int shift) { debugSerial.println(ledOnCounter, DEC); } #endif /*defined(DEBUG) && defined(ARDUINO_AVR_UNO)*/ -} - -void SetColor_execute(int shift) { - uint16_t &hue = ledRingState.hue; - - hue += (shift << 8); - -#if defined(DEBUG) && defined(ARDUINO_AVR_UNO) - if (shift != 0) { - debugSerial.print(__func__); - debugSerial.print(" : shift="); - debugSerial.print(shift, DEC); - debugSerial.print(", hue="); - debugSerial.println(hue, DEC); - } -#endif /*defined(DEBUG) && defined(ARDUINO_AVR_UNO)*/ -} - -void SetBrightness_execute(int shift) { - uint8_t &brightness = ledRingState.brightness; - - brightness += (shift << 2); - -#if defined(DEBUG) && defined(ARDUINO_AVR_UNO) - if (shift != 0) { - debugSerial.print(__func__); - debugSerial.print(" : shift="); - debugSerial.print(shift, DEC); - debugSerial.print(", brightness="); - debugSerial.println(brightness, DEC); - } -#endif /*defined(DEBUG) && defined(ARDUINO_AVR_UNO)*/ -} +} /* LightOn_execute */ void Shift_execute(int shift) { - uint16_t &ledOnShift = ledRingState.ledOnShift; + uint16_t &ledOnShift = ledRingState.ledRingColorState.ledOnShift; if (shift > 0) { ++ledOnShift; @@ -255,56 +391,9 @@ void Shift_execute(int shift) { debugSerial.println(ledOnShift, DEC); } #endif /*defined(DEBUG) && defined(ARDUINO_AVR_UNO)*/ -} +} /* Shift_execute */ -void SetSaturation_execute(int shift) { - uint8_t &saturation = ledRingState.saturation; - - saturation += (shift << 2); - -#if defined(DEBUG) && defined(ARDUINO_AVR_UNO) - if (shift != 0) { - debugSerial.print(__func__); - debugSerial.print(" : shift="); - debugSerial.print(shift, DEC); - debugSerial.print(", saturation="); - debugSerial.println(saturation, DEC); - } -#endif /*defined(DEBUG) && defined(ARDUINO_AVR_UNO)*/ -} - -int get_encoder_shift(void) { - int32_t static _previousValue{encoder.read()}; - - int32_t currentValue{encoder.read()}; - int32_t diff{currentValue - _previousValue}; - - if (diff <= -4) { - _previousValue = currentValue; - return diff >> 2; - - } else if (diff >= 4) { - _previousValue = currentValue; - return diff >> 2; - - } else { - return 0; - } -} - -void refresh_led_ring(void) { - ledRing.fill(0); - for (size_t i = 0; i < ledRingState.ledOnCounter; ++i) { - unsigned int ledId = i + ledRingState.ledOnShift; - if (ledId >= LedCount) { - ledId -= LedCount; - } - ledRing.setPixelColor(ledId, Adafruit_NeoPixel::ColorHSV( - ledRingState.hue, ledRingState.saturation, - ledRingState.brightness)); - } - ledRing.show(); -} +/* Others functions */ void analog_button_calibration(void) { int highRef, lowRef; @@ -333,4 +422,92 @@ void analog_button_calibration(void) { #endif /*DEBUG*/ button = AnalogButton{AnalogButtonPin, lowRef + 10}; +} + +int get_encoder_shift(void) { + int32_t static _previousValue{encoder.read()}; + + int32_t currentValue{encoder.read()}; + int32_t diff{currentValue - _previousValue}; + + if (diff <= -4) { + _previousValue = currentValue; + return diff >> 2; + + } else if (diff >= 4) { + _previousValue = currentValue; + return diff >> 2; + + } else { + return 0; + } +} + +void display_mode(Mode_e mode) { + if (ledRingState.currentMode != Mode_e::ControlOff) { +#ifdef DEBUG + debugSerial.println("Display mode"); +#endif /*DEBUG*/ + + for (size_t i = 0; i < 3; ++i) { + ledRing.fill(0); + ledRing.show(); + delay(300); + for (Mode_e i = Mode_e::Init; i < ledRingState.currentMode; ++i) { + ledRing.setPixelColor(int(i), Adafruit_NeoPixel::ColorHSV( + 0, 255, 16)); + } + ledRing.show(); + delay(300); + } + } +} + +void display_led_ring(void) { + PresetState_t &preset = ledRingState.presetState; + LedRingColorState_t ledRingColorState; + + if (ledRingState.currentMode == Mode_e::Preset) { +#ifdef DEBUG + debugSerial.print("Preset : "); + debugSerial.print(preset.index); + debugSerial.print(", "); + // debugSerial.print((preset.index == (PresetMax - 1)) ? 0 : UINT8_MAX); + // debugSerial.print(", "); + debugSerial.println(preset.level); +#endif + ledRingColorState = { + .ledOnCounter = LedCount / 4, + .ledOnShift = 0, + .hue = PresetHue[preset.index], + .saturation = (preset.index == (PresetMax - 1)) ? 0 : UINT8_MAX, + .brightness = PresetBrightness[preset.level] + }; + refresh_led_ring(ledRingColorState); + } else { + refresh_led_ring(); + } + +} + +void refresh_led_ring(LedRingColorState_t const &ledRingColorState) { +#ifdef DEBUG + debugSerial.print("Color : "); + debugSerial.print(ledRingColorState.hue); + debugSerial.print(", "); + debugSerial.print(ledRingColorState.saturation); + debugSerial.print(", "); + debugSerial.println(ledRingColorState.brightness); +#endif + ledRing.fill(0); + for (size_t i = 0; i < ledRingColorState.ledOnCounter; ++i) { + unsigned int ledId = i + ledRingColorState.ledOnShift; + if (ledId >= LedCount) { + ledId -= LedCount; + } + ledRing.setPixelColor(ledId, Adafruit_NeoPixel::ColorHSV( + ledRingColorState.hue, ledRingColorState.saturation, + ledRingColorState.brightness)); + } + ledRing.show(); } \ No newline at end of file diff --git a/src/main.cpp.echo b/src/main.cpp.echo new file mode 100644 index 0000000..ef01cd0 --- /dev/null +++ b/src/main.cpp.echo @@ -0,0 +1,32 @@ +#include + +#include "pin_map.hpp" + +/* debug Serial definition */ +#ifdef DEBUG +#ifdef ARDUINO_AVR_ATTINYX5 +#include +SoftwareSerial debugSerial{RxPin, TxPin}; +#endif /*ARDUINO_AVR_ATTINYX5*/ +#ifdef ARDUINO_AVR_UNO +#include +HardwareSerial &debugSerial = Serial; +#endif /*ARDUINO_AVR_UNO*/ +#endif /*DEBUG*/ + + +void setup() { + +#ifdef DEBUG + debugSerial.begin(9600); + while (!debugSerial.available()) + ; + debugSerial.println("Init ... "); +#endif /*DEBUG*/ +} + +void loop() { + while (!debugSerial.available()) + ; + debugSerial.println("ok"); +} \ No newline at end of file