wip preset
This commit is contained in:
parent
a68d774d71
commit
6685e9742e
393
src/main.cpp
393
src/main.cpp
@ -4,7 +4,7 @@
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
#include <Encoder.h>
|
||||
|
||||
#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<Mode_e>(static_cast<int>(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 {
|
||||
.ledRingColorState = {
|
||||
.ledOnCounter = LedCount / 2,
|
||||
.ledOnShift = LedCount / 4,
|
||||
.ledOnShift = 0,
|
||||
.hue = 0,
|
||||
.saturation = 255,
|
||||
.brightness = 16,
|
||||
.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<int>(currentMode)]);
|
||||
debugSerial.println(mode_str[static_cast<int>(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<int>(currentMode)]);
|
||||
debugSerial.println(mode_str[static_cast<int>(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;
|
||||
@ -334,3 +423,91 @@ void analog_button_calibration(void) {
|
||||
|
||||
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();
|
||||
}
|
32
src/main.cpp.echo
Normal file
32
src/main.cpp.echo
Normal file
@ -0,0 +1,32 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "pin_map.hpp"
|
||||
|
||||
/* debug Serial definition */
|
||||
#ifdef DEBUG
|
||||
#ifdef ARDUINO_AVR_ATTINYX5
|
||||
#include <SoftwareSerial.h>
|
||||
SoftwareSerial debugSerial{RxPin, TxPin};
|
||||
#endif /*ARDUINO_AVR_ATTINYX5*/
|
||||
#ifdef ARDUINO_AVR_UNO
|
||||
#include <HardwareSerial.h>
|
||||
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");
|
||||
}
|
Loading…
Reference in New Issue
Block a user