led selection improvement 2

This commit is contained in:
Tropicananass 2021-02-28 11:12:15 +01:00
parent 1ede34169e
commit 62c58a6a9b
2 changed files with 178 additions and 184 deletions

View File

@ -9,7 +9,7 @@
; https://docs.platformio.org/page/projectconf.html ; https://docs.platformio.org/page/projectconf.html
[platformio] [platformio]
default_envs = attiny85d default_envs = attiny85_debug
[env] [env]
build_flags = -Wall build_flags = -Wall
@ -28,11 +28,16 @@ board_build.f_cpu = 16000000L
; board_fuses.hfuse = 0xBB ; board_fuses.hfuse = 0xBB
; board_fuses.efuse = 0xCC ; board_fuses.efuse = 0xCC
[env:attiny85d] [env:attiny85_debug]
build_type = debug build_type = debug
extends = env:attiny85 extends = env:attiny85
build_flags = -D DEBUG build_flags = -D DEBUG
[env:attiny85_init_debug]
build_type = debug
extends = env:attiny85_debug
build_flags = -D DEBUG_INIT
[env:uno] [env:uno]
build_type = debug build_type = debug

View File

@ -13,41 +13,40 @@
/* State machine */ /* State machine */
#define FOREACH_MODE(MODE) \ #define FOREACH_MODE(MODE) \
MODE(Init) \ MODE(Init) \
MODE(LightOnMin) \
MODE(LightOnMax) \
MODE(ControlOff) \
MODE(Preset) \ MODE(Preset) \
MODE(SetColor) \ MODE(SetColor) \
MODE(SetSaturation) \ MODE(SetSaturation) \
MODE(SetBrightness) \ MODE(SetBrightness)
MODE(LightOn) \
MODE(Shift) \
MODE(ControlOff)
#define GENERATE_MODE_ENUM(ENUM) ENUM, #define GENERATE_MODE_ENUM(ENUM) ENUM,
/* Generate Mode_e enum */
enum class Mode_e { FOREACH_MODE(GENERATE_MODE_ENUM) }; enum class Mode_e { FOREACH_MODE(GENERATE_MODE_ENUM) };
/* cyclic increment operator for mode_e */ /* Cyclic increment operator for Mode_e */
Mode_e &operator++(Mode_e &mode) { Mode_e &operator++(Mode_e &mode) {
if (mode == Mode_e::ControlOff) { if (mode == Mode_e::ControlOff) {
return mode = Mode_e::Preset; return mode = Mode_e::Init;
} }
return mode = static_cast<Mode_e>(static_cast<int>(mode) + 1); return mode = static_cast<Mode_e>(static_cast<int>(mode) + 1);
} }
#ifdef DEBUG #if defined(DEBUG)
/* Generate string array from Mode_e names */
#define GENERATE_MODE_STRING(STRING) #STRING, #define GENERATE_MODE_STRING(STRING) #STRING,
char static const *mode_str[] = {FOREACH_MODE(GENERATE_MODE_STRING)}; char static const *mode_str[] = {FOREACH_MODE(GENERATE_MODE_STRING)};
#endif /*DEBUG*/ #endif /* defined(DEBUG) */
/* Leds */ /* Leds */
uint16_t static const LedCount{24}; uint16_t static const LedCount{24};
uint8_t static const ColorSaturation{128};
uint8_t static const ColorArray[3][3] = {
{ColorSaturation, 0, 0}, {0, ColorSaturation, 0}, {0, 0, ColorSaturation}};
/* Led ring color and led count state */ /* Led ring color and led count state */
typedef struct { typedef struct {
uint16_t ledOnCounter; uint16_t ledOnMin;
uint16_t ledOnShift; uint16_t ledOnMax;
uint16_t hue; uint16_t hue;
uint8_t saturation; uint8_t saturation;
uint8_t brightness; uint8_t brightness;
@ -55,61 +54,17 @@ typedef struct {
uint8_t const PresetMax{8}; uint8_t const PresetMax{8};
// https://hslpicker.com/ = {0, 40, 50, 110, 240, 280, 310, 360 for white} // https://hslpicker.com/ = {0, 40, 50, 110, 240, 280, 310, 360 for
uint16_t const PresetHue[PresetMax] = {0, 7282, 9102, 20025, 43691, 50972, 56434, 65535}; // white}
uint16_t const PresetHue[PresetMax] = {0, 7282, 9102, 20025,
43691, 50972, 56434, 65535};
uint8_t const PresetLevelMax{3}; uint8_t const PresetLevelMax{3};
uint8_t const PresetBrightness[PresetLevelMax] = {16, 64, 127}; 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 */ /* Preset state */
typedef struct { typedef struct {
bool isActive;
uint8_t index; uint8_t index;
uint8_t level; uint8_t level;
} PresetState_t; } PresetState_t;
@ -129,20 +84,13 @@ int const AnalogButtonVRef{970};
/* Led ring state */ /* Led ring state */
LedRingState_t ledRingState{ LedRingState_t ledRingState{
.ledRingColorState = { .ledRingColorState = {.ledOnMin = 0,
.ledOnCounter = LedCount / 2, .ledOnMax = LedCount / 2,
.ledOnShift = 0,
.hue = 0, .hue = 0,
.saturation = 255, .saturation = 255,
.brightness = 16 .brightness = 16},
}, .presetState = {.index = 0, .level = 0},
.presetState = { .currentMode = Mode_e::Init};
.isActive = false,
.index = 0,
.level = 0
},
.currentMode = Mode_e::Init
};
/* IO Objects */ /* IO Objects */
Adafruit_NeoPixel ledRing{LedCount, LedPin, NEO_GRB + NEO_KHZ800}; Adafruit_NeoPixel ledRing{LedCount, LedPin, NEO_GRB + NEO_KHZ800};
@ -150,21 +98,21 @@ Encoder encoder{EncoderPinA, EncoderPinB};
AnalogButton button{AnalogButtonPin, AnalogButtonVRef}; AnalogButton button{AnalogButtonPin, AnalogButtonVRef};
/* debug Serial definition */ /* debug Serial definition */
#ifdef DEBUG #if defined(DEBUG)
#ifdef ARDUINO_AVR_ATTINYX5 #if defined(ARDUINO_AVR_ATTINYX5)
#include <SoftwareSerial.h> #include <SoftwareSerial.h>
SoftwareSerial debugSerial{RxPin, TxPin}; SoftwareSerial debugSerial{RxPin, TxPin};
#endif /*ARDUINO_AVR_ATTINYX5*/ #endif /* defined(ARDUINO_AVR_ATTINYX5) */
#ifdef ARDUINO_AVR_UNO #if defined(ARDUINO_AVR_UNO)
#include <HardwareSerial.h> #include <HardwareSerial.h>
HardwareSerial &debugSerial = Serial; HardwareSerial &debugSerial = Serial;
#endif /*ARDUINO_AVR_UNO*/ #endif /* defined(ARDUINO_AVR_UNO) */
#endif /*DEBUG*/ #endif /* defined(DEBUG) */
/* Private function declarations */ /* Private function declarations */
/*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/
/* State machine */ /* Generates state machine handlers for each Mode_e */
#define GENERATE_MODE_EXEC_DECLARTION(MODE) void MODE##_execute(int shift); #define GENERATE_MODE_EXEC_DECLARTION(MODE) void MODE##_execute(int shift);
FOREACH_MODE(GENERATE_MODE_EXEC_DECLARTION) FOREACH_MODE(GENERATE_MODE_EXEC_DECLARTION)
@ -177,12 +125,12 @@ void display_mode(Mode_e mode);
void display_led_ring(void); void display_led_ring(void);
void refresh_led_ring(LedRingColorState_t const &ledRingColorState = ledRingState.ledRingColorState); void refresh_led_ring(LedRingColorState_t const &ledRingColorState =
ledRingState.ledRingColorState);
/* Function definitions */ /* Function definitions */
/*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/
void setup() { void setup() {
ledRing.begin(); ledRing.begin();
ledRing.fill(Adafruit_NeoPixel::Color(45, 0, 0)); ledRing.fill(Adafruit_NeoPixel::Color(45, 0, 0));
delay(300); delay(300);
@ -191,20 +139,22 @@ void setup() {
ledRing.fill(Adafruit_NeoPixel::Color(0, 0, 45)); ledRing.fill(Adafruit_NeoPixel::Color(0, 0, 45));
delay(300); delay(300);
#ifdef DEBUG #if defined(DEBUG)
debugSerial.begin(9600); debugSerial.begin(9600);
#if defined(DEBUG_INIT)
while (!debugSerial.available()) while (!debugSerial.available())
; ;
#endif /* defined(DEBUG_INIT) */
debugSerial.println("Init ... "); debugSerial.println("Init ... ");
#endif /*DEBUG*/ #endif /* defined(DEBUG) */
analog_button_calibration(); analog_button_calibration();
get_encoder_shift(); get_encoder_shift();
#ifdef DEBUG #if defined(DEBUG)
debugSerial.println(mode_str[static_cast<int>(ledRingState.currentMode)]); debugSerial.println(mode_str[static_cast<int>(ledRingState.currentMode)]);
#endif /*DEBUG*/ #endif /* defined(DEBUG) */
} }
void loop() { void loop() {
@ -217,9 +167,9 @@ void loop() {
} }
++ledRingState.currentMode; ++ledRingState.currentMode;
#ifdef DEBUG #if defined(DEBUG)
debugSerial.println(mode_str[static_cast<int>(ledRingState.currentMode)]); debugSerial.println(mode_str[static_cast<int>(ledRingState.currentMode)]);
#endif /*DEBUG*/ #endif /* defined(DEBUG) */
display_mode(ledRingState.currentMode); display_mode(ledRingState.currentMode);
hasModeChanged = true; hasModeChanged = true;
@ -235,10 +185,6 @@ void loop() {
Preset_execute(shift); Preset_execute(shift);
break; break;
case Mode_e::LightOn:
LightOn_execute(shift);
break;
case Mode_e::SetColor: case Mode_e::SetColor:
SetColor_execute(shift); SetColor_execute(shift);
break; break;
@ -251,8 +197,12 @@ void loop() {
SetSaturation_execute(shift); SetSaturation_execute(shift);
break; break;
case Mode_e::Shift: case Mode_e::LightOnMin:
Shift_execute(shift); LightOnMin_execute(shift);
break;
case Mode_e::LightOnMax:
LightOnMax_execute(shift);
break; break;
default: default:
@ -260,7 +210,8 @@ void loop() {
} }
} }
if (ledRingState.currentMode != Mode_e::ControlOff && (shift != 0 || hasModeChanged)) { if (ledRingState.currentMode != Mode_e::ControlOff &&
(shift != 0 || hasModeChanged)) {
display_led_ring(); display_led_ring();
} }
} }
@ -341,47 +292,29 @@ void SetSaturation_execute(int shift) {
#endif /*defined(DEBUG) && defined(ARDUINO_AVR_UNO)*/ #endif /*defined(DEBUG) && defined(ARDUINO_AVR_UNO)*/
} /* SetSaturation_execute */ } /* SetSaturation_execute */
void LightOn_execute(int shift) { void LightOnMin_execute(int shift) {
uint16_t &ledOnCounter = ledRingState.ledRingColorState.ledOnCounter; uint16_t &ledOnMin = ledRingState.ledRingColorState.ledOnMin;
static bool clockwise = true; uint16_t &ledOnMax = ledRingState.ledRingColorState.ledOnMax;
if ((shift > 0) != !clockwise) {
++ledOnCounter;
if (ledOnCounter > LedCount) {
ledOnCounter = LedCount;
clockwise = !clockwise;
}
} else {
--ledOnCounter;
if (ledOnCounter == UINT16_MAX) {
ledOnCounter = 0;
clockwise = !clockwise;
}
}
#if defined(DEBUG) && defined(ARDUINO_AVR_UNO)
if (shift != 0) {
debugSerial.print(__func__);
debugSerial.print(" : shift=");
debugSerial.print(shift, DEC);
debugSerial.print(", ledOnCounter=");
debugSerial.println(ledOnCounter, DEC);
}
#endif /*defined(DEBUG) && defined(ARDUINO_AVR_UNO)*/
} /* LightOn_execute */
void Shift_execute(int shift) {
uint16_t &ledOnShift = ledRingState.ledRingColorState.ledOnShift;
if (shift > 0) { if (shift > 0) {
++ledOnShift; if (ledOnMin == ledOnMax) {
if (ledOnShift == LedCount) { ledRingState.currentMode = Mode_e::LightOnMax;
ledOnShift = 0; ++ledOnMax;
} else {
++ledOnMin;
if (ledOnMin == LedCount) {
ledOnMin = 0;
}
} }
} else { } else {
--ledOnShift; if (ledOnMin == ledOnMax) {
if (ledOnShift == UINT16_MAX) { ledRingState.currentMode = Mode_e::LightOnMax;
ledOnShift = LedCount - 1; --ledOnMax;
} else {
--ledOnMin;
if (ledOnMin == UINT16_MAX) {
ledOnMin = LedCount - 1;
}
} }
} }
@ -390,39 +323,78 @@ void Shift_execute(int shift) {
debugSerial.print(__func__); debugSerial.print(__func__);
debugSerial.print(" : shift="); debugSerial.print(" : shift=");
debugSerial.print(shift, DEC); debugSerial.print(shift, DEC);
debugSerial.print(", ledOnShift="); debugSerial.print(", ledOnMin=");
debugSerial.println(ledOnShift, DEC); debugSerial.println(ledOnMin, DEC);
} }
#endif /*defined(DEBUG) && defined(ARDUINO_AVR_UNO)*/ #endif /*defined(DEBUG) && defined(ARDUINO_AVR_UNO)*/
} /* Shift_execute */ } /* LightOnMin_execute */
void LightOnMax_execute(int shift) {
uint16_t &ledOnMin = ledRingState.ledRingColorState.ledOnMin;
uint16_t &ledOnMax = ledRingState.ledRingColorState.ledOnMax;
if (shift > 0) {
if (ledOnMax == ledOnMin) {
ledRingState.currentMode = Mode_e::LightOnMin;
++ledOnMin;
} else {
++ledOnMax;
if (ledOnMax == LedCount) {
ledOnMax = 0;
}
}
} else {
if (ledOnMax == ledOnMin) {
ledRingState.currentMode = Mode_e::LightOnMin;
--ledOnMin;
} else {
--ledOnMax;
if (ledOnMax == UINT16_MAX) {
ledOnMax = LedCount - 1;
}
}
}
#if defined(DEBUG) && defined(ARDUINO_AVR_UNO)
if (shift != 0) {
debugSerial.print(__func__);
debugSerial.print(" : shift=");
debugSerial.print(shift, DEC);
debugSerial.print(", ledOnMax=");
debugSerial.println(ledOnMax, DEC);
}
#endif /*defined(DEBUG) && defined(ARDUINO_AVR_UNO)*/
} /* LightOnMax_execute */
/* Others functions */ /* Others functions */
void analog_button_calibration(void) { void analog_button_calibration(void) {
int highRef, lowRef; int highRef, lowRef;
#if defined(DEBUG) && false
debugSerial.print(__func__);
#endif /* defined(DEBUG) */
do { do {
highRef = analogRead(AnalogButtonPin); highRef = analogRead(AnalogButtonPin);
delay(300); delay(300);
#ifdef DEBUG
debugSerial.println(highRef);
#endif /*DEBUG*/
} while (highRef < 1000); } while (highRef < 1000);
#if defined(DEBUG) && false
debugSerial.println("highRef=");
debugSerial.println(highRef);
#endif /* defined(DEBUG) */
lowRef = analogRead(AnalogButtonPin); lowRef = analogRead(AnalogButtonPin);
while (highRef - lowRef < 50) { while (highRef - lowRef < 50) {
#ifdef DEBUG
debugSerial.println(lowRef);
#endif /*DEBUG*/
lowRef = analogRead(AnalogButtonPin); lowRef = analogRead(AnalogButtonPin);
delay(300); delay(300);
} }
#ifdef DEBUG #if defined(DEBUG) && false
debugSerial.println("lowRef=");
debugSerial.println(lowRef); debugSerial.println(lowRef);
#endif /*DEBUG*/ #endif /* defined(DEBUG) */
button = AnalogButton{AnalogButtonPin, lowRef + 10}; button = AnalogButton{AnalogButtonPin, lowRef + 10};
} }
@ -448,17 +420,12 @@ int get_encoder_shift(void) {
void display_mode(Mode_e mode) { void display_mode(Mode_e mode) {
if (ledRingState.currentMode != Mode_e::ControlOff) { if (ledRingState.currentMode != Mode_e::ControlOff) {
#ifdef DEBUG
debugSerial.println("Display mode");
#endif /*DEBUG*/
for (size_t i = 0; i < 3; ++i) { for (size_t i = 0; i < 3; ++i) {
ledRing.fill(0); ledRing.fill(0);
ledRing.show(); ledRing.show();
delay(300); delay(300);
for (Mode_e i = Mode_e::Init; i < ledRingState.currentMode; ++i) { for (Mode_e i = Mode_e::Init; i < ledRingState.currentMode; ++i) {
ledRing.setPixelColor(int(i), Adafruit_NeoPixel::ColorHSV( ledRing.setPixelColor(int(i), Adafruit_NeoPixel::ColorHSV(0, 255, 16));
0, 255, 16));
} }
ledRing.show(); ledRing.show();
delay(300); delay(300);
@ -471,45 +438,67 @@ void display_led_ring(void) {
LedRingColorState_t ledRingColorState; LedRingColorState_t ledRingColorState;
if (ledRingState.currentMode == Mode_e::Preset) { if (ledRingState.currentMode == Mode_e::Preset) {
#ifdef DEBUG #if defined(DEBUG) && false
debugSerial.print("Preset : "); debugSerial.print("Preset index,level=");
debugSerial.print(preset.index); debugSerial.print(preset.index);
debugSerial.print(","); debugSerial.print(",");
// debugSerial.print((preset.index == (PresetMax - 1)) ? 0 : UINT8_MAX); debugSerial.print(preset.level);
// debugSerial.print(", "); debugSerial.println();
debugSerial.println(preset.level); #endif /* defined(DEBUG) */
#endif ledRingColorState = {.ledOnMin = ledRingState.ledRingColorState.ledOnMin,
ledRingColorState = { .ledOnMax = ledRingState.ledRingColorState.ledOnMax,
.ledOnCounter = LedCount / 4,
.ledOnShift = 0,
.hue = PresetHue[preset.index], .hue = PresetHue[preset.index],
.saturation = (preset.index == (PresetMax - 1)) ? 0 : UINT8_MAX, .saturation =
.brightness = PresetBrightness[preset.level] (preset.index == (PresetMax - 1)) ? 0 : UINT8_MAX,
}; .brightness = PresetBrightness[preset.level]};
refresh_led_ring(ledRingColorState); refresh_led_ring(ledRingColorState);
} else { } else {
refresh_led_ring(); refresh_led_ring();
} }
} }
void refresh_led_ring(LedRingColorState_t const &ledRingColorState) { void refresh_led_ring(LedRingColorState_t const &ledRingColorState) {
#ifdef DEBUG uint16_t const &ledOnMin = ledRingColorState.ledOnMin;
debugSerial.print("Color : "); uint16_t const &ledOnMax = ledRingColorState.ledOnMax;
uint16_t LedOnCount = 0;
#if defined(DEBUG)
debugSerial.print("Color hue,sat,bri=");
debugSerial.print(ledRingColorState.hue); debugSerial.print(ledRingColorState.hue);
debugSerial.print(","); debugSerial.print(",");
debugSerial.print(ledRingColorState.saturation); debugSerial.print(ledRingColorState.saturation);
debugSerial.print(","); debugSerial.print(",");
debugSerial.println(ledRingColorState.brightness); debugSerial.println(ledRingColorState.brightness);
#endif #endif /* defined(DEBUG) */
/* reset ring */
ledRing.fill(0); ledRing.fill(0);
for (size_t i = 0; i < ledRingColorState.ledOnCounter; ++i) {
unsigned int ledId = i + ledRingColorState.ledOnShift; /* compute number of led on */
if (ledOnMin <= ledOnMax) {
LedOnCount = ledOnMax - ledOnMin;
} else {
LedOnCount = LedCount - (ledOnMax - ledOnMax);
}
#if defined(DEBUG)
debugSerial.print("Led min,max,count=");
debugSerial.print(ledOnMin);
debugSerial.print(",");
debugSerial.print(ledOnMax);
debugSerial.print(",");
debugSerial.println(LedOnCount);
#endif /* defined(DEBUG) */
for (size_t i = ledRingColorState.ledOnMin;
i < ledRingColorState.ledOnMin + LedOnCount; ++i) {
unsigned int ledId = i;
if (ledId >= LedCount) { if (ledId >= LedCount) {
ledId -= LedCount; ledId -= LedCount;
} }
ledRing.setPixelColor(ledId, Adafruit_NeoPixel::ColorHSV( ledRing.setPixelColor(
ledRingColorState.hue, ledRingColorState.saturation, ledId, Adafruit_NeoPixel::ColorHSV(ledRingColorState.hue,
ledRingColorState.saturation,
ledRingColorState.brightness)); ledRingColorState.brightness));
} }
ledRing.show(); ledRing.show();