diff --git a/.clang-format b/.clang-format index 03ce0b4..1bdff23 100644 --- a/.clang-format +++ b/.clang-format @@ -54,7 +54,7 @@ BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeColon BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true -ColumnLimit: 80 +ColumnLimit: 120 CommentPragmas: '^ IWYU pragma:' CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: false diff --git a/platformio.ini b/platformio.ini index aae3fa1..99c15c8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,12 +9,11 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -default_envs = attiny85_debug +default_envs = attiny841_debug [env] build_flags = -Wall lib_deps = - Adafruit NeoPixel Encoder [env:attiny85] @@ -23,10 +22,6 @@ platform = atmelavr board = attiny85 framework = arduino upload_protocol = usbtiny -board_build.f_cpu = 16000000L -; board_fuses.lfuse = 0xAA -; board_fuses.hfuse = 0xBB -; board_fuses.efuse = 0xCC [env:attiny85_debug] build_type = debug @@ -37,9 +32,27 @@ build_type = debug extends = env:attiny85_debug build_flags = -D DEBUG_INIT +[env:attiny841] +build_type = release +platform = atmelavr +board = attiny841 +framework = arduino +upload_protocol = usbtiny +; default is 42 which divides by 8 internal clock to wich gives a system clock of 1MHz +; whith C2 we do not divide and system runs at 8MHz +board_build.f_cpu = 8000000L +board_fuses.lfuse = 0xC2 +board_fuses.hfuse = 0xDF +board_fuses.efuse = 0xFF + +[env:attiny841_debug] +extends = env:attiny841 +build_flags = -D DEBUG_INIT -D __BUILD_DEBUG__ [env:uno] build_type = debug +lib_deps = + Adafruit NeoPixel platform = atmelavr board = uno framework = arduino diff --git a/res/Atmel-ATtiny841_Datasheet_Summary.pdf b/res/Atmel-ATtiny841_Datasheet_Summary.pdf new file mode 100644 index 0000000..a476115 Binary files /dev/null and b/res/Atmel-ATtiny841_Datasheet_Summary.pdf differ diff --git a/res/Atmel_ATtiny841_Datasheet.pdf b/res/Atmel_ATtiny841_Datasheet.pdf new file mode 100644 index 0000000..fd4c0a3 Binary files /dev/null and b/res/Atmel_ATtiny841_Datasheet.pdf differ diff --git a/res/Atmel_attiny85.pdf b/res/Atmel_ATtiny85_Datasheet.pdf similarity index 100% rename from res/Atmel_attiny85.pdf rename to res/Atmel_ATtiny85_Datasheet.pdf diff --git a/src/button.cpp b/src/button.cpp index 9248787..17e3e27 100644 --- a/src/button.cpp +++ b/src/button.cpp @@ -2,10 +2,48 @@ #include -bool AnalogButton::is_button_pressed(void) { - return analogRead(_aPin) < _vRef; +void Button::setup(void) { pinMode(_pin, INPUT_PULLUP); } + +bool Button::is_button_pressed(void) { return digitalRead(_pin) == 0; } + +void AnalogButton::setup(void) { + if (_vRef < 0) { + calibrate(); + } } -void AnalogButton::calibrate(void) { +bool AnalogButton::is_button_pressed(void) { return analogRead(_pin) < _vRef; } -} \ No newline at end of file +void AnalogButton::calibrate(void) { + int highRef, lowRef; + +#if defined(__BUILD_DEBUG__) && false + debugSerial.print(__func__); +#endif /* defined(__BUILD_DEBUG__) */ + + /* Get the button released (High) state voltage, should be close to 1024 (analogRead max) */ + do { + highRef = analogRead(_pin); + delay(300); + } while (highRef < 1000); + +#if defined(__BUILD_DEBUG__) && false + debugSerial.println("highRef="); + debugSerial.println(highRef); +#endif /* defined(__BUILD_DEBUG__) */ + + /* Get the button pushed (Low) state voltage (min of ~5% difference needed to avoid false detection) */ + lowRef = analogRead(_pin); + while (highRef - lowRef < 50) { + lowRef = analogRead(_pin); + delay(300); + } + +#if defined(__BUILD_DEBUG__) && false + debugSerial.println("lowRef="); + debugSerial.println(lowRef); +#endif /* defined(__BUILD_DEBUG__) */ + + /* Add ~1% tolerance */ + _vRef = lowRef + 10; +} diff --git a/src/button.hpp b/src/button.hpp index dd934c1..3f9b049 100644 --- a/src/button.hpp +++ b/src/button.hpp @@ -3,14 +3,33 @@ #include -class AnalogButton { +class Button { + public: - AnalogButton(uint8_t analogPin, int vRef) : _aPin{analogPin}, _vRef{vRef} {}; - bool is_button_pressed(void); - void calibrate(void); + Button(uint8_t pin) : _pin{pin} {}; + ~Button() {}; + + void setup(void); + bool is_button_pressed(void); + +protected: + uint8_t _pin; + private: - uint8_t _aPin; - int _vRef; +}; + +class AnalogButton : Button { +public: + AnalogButton(uint8_t pin, int vRef = -1) : Button(pin), _vRef{vRef} {}; + virtual ~AnalogButton() {}; + + void setup(void); + bool is_button_pressed(void); + +private: + int _vRef; + + void calibrate(void); }; #endif /* __BUTTON_HPP__ */ diff --git a/src/global.hpp b/src/global.hpp new file mode 100644 index 0000000..a641695 --- /dev/null +++ b/src/global.hpp @@ -0,0 +1,14 @@ +#ifndef __GLOBAL_HPP__ +#define __GLOBAL_HPP__ +#include + +/* debug Serial definition */ +#if defined(__BUILD_DEBUG__) +#if defined(ARDUINO_AVR_ATTINYX5) +extern SoftwareSerial debugSerial; +#else +extern HardwareSerial &debugSerial; +#endif +#endif + +#endif /* __GLOBAL_HPP__ */ \ No newline at end of file diff --git a/src/led_strip.cpp b/src/led_strip.cpp new file mode 100644 index 0000000..277da79 --- /dev/null +++ b/src/led_strip.cpp @@ -0,0 +1,194 @@ +#include "led_strip.hpp" +#include "global.hpp" + +// LedStrip::LedStrip(/* args */) {} +// LedStrip::~LedStrip() {} + +#if defined(ARDUINO_AVR_ATTINYX5) || defined(ARDUINO_AVR_ATTINYX41) +/* TODO: remove when switching to tinycore V2.0.0 */ +void LedStrip::fill(uint32_t c, uint16_t first, uint16_t count) { + uint16_t i, end; + + if (first >= LedCount) { + return; // If first LED is past end of strip, nothing to do + } + + // Calculate the index ONE AFTER the last pixel to fill + if (count == 0) { + // Fill to end of strip + end = LedCount; + } else { + // Ensure that the loop won't go past the last pixel + end = first + count; + if (end > LedCount) + end = LedCount; + } + + for (i = first; i < end; i++) { + setPixelColor(i, c); + } +} +#endif /* defined(ARDUINO_AVR_ATTINYX5) || defined(ARDUINO_AVR_ATTINYX41) */ + +void LedStrip::setup() { + pinMode(LedPin, OUTPUT); + setPixelColor(0, 255, 0, 0); + fill(Color(45, 0, 0)); + show(); + delay(300); + fill(Color(0, 45, 0)); + show(); + delay(300); + fill(Color(0, 0, 45)); + show(); + delay(300); +} + +void LedStrip::refresh() { + uint16_t const &ledOnMin = ledRingColorState.ledOnMin; + uint16_t const &ledOnMax = ledRingColorState.ledOnMax; + uint16_t LedOnCount = 0; + +#if defined(__BUILD_DEBUG__) + debugSerial.print("Color hue,sat,bri="); + debugSerial.print(ledRingColorState.hue); + debugSerial.print(","); + debugSerial.print(ledRingColorState.saturation); + debugSerial.print(","); + debugSerial.println(ledRingColorState.brightness); +#endif /* defined(__BUILD_DEBUG__) */ + + /* reset ring */ + fill(); + + /* compute number of led on */ + if (ledOnMin <= ledOnMax) { + LedOnCount = ledOnMax - ledOnMin; + } else { + LedOnCount = LedCount - (ledOnMax - ledOnMax); + } + +#if defined(__BUILD_DEBUG__) + debugSerial.print("Led min,max,count="); + debugSerial.print(ledOnMin); + debugSerial.print(","); + debugSerial.print(ledOnMax); + debugSerial.print(","); + debugSerial.println(LedOnCount); +#endif /* defined(__BUILD_DEBUG__) */ + + for (size_t i = ledRingColorState.ledOnMin; i < ledRingColorState.ledOnMin + LedOnCount; ++i) { + unsigned int ledId = i; + if (ledId >= LedCount) { + ledId -= LedCount; + } + setPixelColor(ledId, ColorHSV(ledRingColorState.hue, ledRingColorState.saturation, ledRingColorState.brightness)); + } + show(); +} + +void LedStrip::next_preset(void) { + ++presetState.index; + if (presetState.index >= PresetMax) { + presetState.index = 0; + ++presetState.level; + if (presetState.level >= PresetLevelMax) { + presetState.level = 0; + } + } +} + +void LedStrip::previous_preset(void) { + --presetState.index; + if (presetState.index == UINT8_MAX) { + presetState.index = PresetMax - 1; + --presetState.level; + if (presetState.level == UINT8_MAX) { + presetState.level = PresetLevelMax - 1; + } + } +} + +void LedStrip::display_led_ring(bool is_preset_enabled) { + LedRingColorState_t colorState; + + if (is_preset_enabled) { +#if defined(__BUILD_DEBUG__) && false + debugSerial.print("Preset index,level="); + debugSerial.print(presetState.index); + debugSerial.print(","); + debugSerial.print(presetState.level); + debugSerial.println(); +#endif /* defined(__BUILD_DEBUG__) */ + colorState = {.ledOnMin = this->ledRingColorState.ledOnMin, + .ledOnMax = this->ledRingColorState.ledOnMax, + .hue = PresetHue[presetState.index], + .saturation = (presetState.index == (PresetMax - 1U)) ? 0U : UINT8_MAX, + .brightness = PresetBrightness[presetState.level]}; + refresh_led_ring(&colorState); + } else { + refresh_led_ring(); + } +} + +void LedStrip::refresh_led_ring(LedRingColorState_t const *ledRingColorState) { + if (ledRingColorState == nullptr) { + ledRingColorState = &this->ledRingColorState + } + uint16_t const &ledOnMin = ledRingColorState.ledOnMin; + uint16_t const &ledOnMax = ledRingColorState.ledOnMax; + uint16_t LedOnCount = 0; + +#if defined(__BUILD_DEBUG__) + debugSerial.print("Color hue,sat,bri="); + debugSerial.print(ledRingColorState.hue); + debugSerial.print(","); + debugSerial.print(ledRingColorState.saturation); + debugSerial.print(","); + debugSerial.println(ledRingColorState.brightness); +#endif /* defined(__BUILD_DEBUG__) */ + + /* reset ring */ + this->fill(0); + + /* compute number of led on */ + if (ledOnMin <= ledOnMax) { + LedOnCount = ledOnMax - ledOnMin; + } else { + LedOnCount = ledCount - (ledOnMax - ledOnMax); + } + +#if defined(__BUILD_DEBUG__) + debugSerial.print("Led min,max,count="); + debugSerial.print(ledOnMin); + debugSerial.print(","); + debugSerial.print(ledOnMax); + debugSerial.print(","); + debugSerial.println(LedOnCount); +#endif /* defined(__BUILD_DEBUG__) */ + + for (size_t i = ledRingColorState.ledOnMin; i < ledRingColorState.ledOnMin + LedOnCount; ++i) { + unsigned int ledId = i; + if (ledId >= LedCount) { + ledId -= LedCount; + } + ledRing.setPixelColor(ledId, Adafruit_NeoPixel::ColorHSV(ledRingColorState.hue, ledRingColorState.saturation, + ledRingColorState.brightness)); + } + ledRing.show(); +} + +// void display_mode(Mode_e mode) { +// if (currentMode != Mode_e::ControlOff) { +// for (size_t i = 0; i < 3; ++i) { +// fill(0); +// show(); +// delay(300); +// for (Mode_e i = Mode_e::Init; i < currentMode; ++i) { +// setPixelColor(int(i), Adafruit_NeoPixel::ColorHSV(0, 255, 16)); +// } +// show(); +// delay(300); +// } +// } +// } \ No newline at end of file diff --git a/src/led_strip.hpp b/src/led_strip.hpp new file mode 100644 index 0000000..48ae393 --- /dev/null +++ b/src/led_strip.hpp @@ -0,0 +1,75 @@ +#ifndef __LED_STRIP_HPP__ +#define __LED_STRIP_HPP__ +#include + +#if defined(ARDUINO_AVR_ATTINYX5) || defined(ARDUINO_AVR_ATTINYX41) +#include +#else +#include +#endif /* defined(ARDUINO_AVR_ATTINYX5) || defined(ARDUINO_AVR_ATTINYX41) */ + +#include "pin_map.hpp" + +/* Leds */ + +/* Led ring color and led count state */ +typedef struct { + uint16_t ledOnMin; + uint16_t ledOnMax; + 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}; + +/* Preset state */ +typedef struct { + uint8_t index; + uint8_t level; +} PresetState_t; + +#if defined(ARDUINO_AVR_ATTINYX5) || defined(ARDUINO_AVR_ATTINYX41) +class LedStrip : tinyNeoPixel { +#else +class LedStrip : Adafruit_NeoPixel { +#endif /* defined(ARDUINO_AVR_ATTINYX5) || defined(ARDUINO_AVR_ATTINYX41) */ + +public: +#if defined(ARDUINO_AVR_ATTINYX5) || defined(ARDUINO_AVR_ATTINYX41) + LedStrip(void) : tinyNeoPixel{LedCount, LedPin, NEO_GRB + NEO_KHZ800, pixels} {} + void fill(uint32_t c = 0, uint16_t first = 0, uint16_t count = 0); +#else + LedStrip(void) : Adafruit_NeoPixel{LedCount, LedPin, NEO_GRB + NEO_KHZ800} {} +#endif /* defined(ARDUINO_AVR_ATTINYX5) || defined(ARDUINO_AVR_ATTINYX41) */ + virtual ~LedStrip() {} + + void setup(); + void refresh(); + + void next_preset(); + void previous_preset(); + void display_led_ring(bool is_preset_enabled); + +private: + uint16_t static const LedCount{24}; + +/* IO Objects */ +#if defined(ARDUINO_AVR_ATTINYX5) || defined(ARDUINO_AVR_ATTINYX41) + byte pixels[LedCount * 3]; +#endif /* defined(ARDUINO_AVR_ATTINYX5) || defined(ARDUINO_AVR_ATTINYX41) */ + + LedRingColorState_t ledRingColorState = { + .ledOnMin = 0, .ledOnMax = LedCount / 2, .hue = 0, .saturation = 255, .brightness = 16}; + PresetState_t presetState = {.index = 0, .level = 0}; + void refresh_led_ring(LedRingColorState_t const *ledRingColorState = nullptr); +}; + +#endif /* __LED_STRIP_HPP__ */ diff --git a/src/main.cpp b/src/main.cpp index 39cf4b0..c4a23dc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,12 +1,12 @@ #include - -// TODO : use core built-in lib tinyNeoPixel -#include #include -#include "button.hpp" +#include "global.hpp" #include "pin_map.hpp" +#include "button.hpp" +#include "led_strip.hpp" + /* Types and Constants */ /*--------------------------------------------------------------------------------------------------------------------*/ @@ -15,11 +15,11 @@ MODE(Init) \ MODE(LightOnMin) \ MODE(LightOnMax) \ - MODE(ControlOff) \ MODE(Preset) \ MODE(SetColor) \ MODE(SetSaturation) \ - MODE(SetBrightness) + MODE(SetBrightness) \ + MODE(ControlOff) #define GENERATE_MODE_ENUM(ENUM) ENUM, @@ -34,75 +34,41 @@ Mode_e &operator++(Mode_e &mode) { return mode = static_cast(static_cast(mode) + 1); } -#if defined(__PLATFORMIO_BUILD_DEBUG__) +#if defined(__BUILD_DEBUG__) /* Generate string array from Mode_e names */ #define GENERATE_MODE_STRING(STRING) #STRING, char static const *mode_str[] = {FOREACH_MODE(GENERATE_MODE_STRING)}; -#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ - -/* Leds */ -uint16_t static const LedCount{24}; - -/* Led ring color and led count state */ -typedef struct { - uint16_t ledOnMin; - uint16_t ledOnMax; - 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}; - -/* Preset state */ -typedef struct { - uint8_t index; - uint8_t level; -} PresetState_t; +#endif /* defined(__BUILD_DEBUG__) */ /* Led ring system state */ -typedef struct { - LedRingColorState_t ledRingColorState; - PresetState_t presetState; - Mode_e currentMode; -} LedRingState_t; - -/* Button */ -int const AnalogButtonVRef{970}; +Mode_e currentMode{Mode_e::Init}; /* Global variables */ /*--------------------------------------------------------------------------------------------------------------------*/ -/* Led ring state */ -LedRingState_t ledRingState{ - .ledRingColorState = {.ledOnMin = 0, .ledOnMax = LedCount / 2, .hue = 0, .saturation = 255, .brightness = 16}, - .presetState = {.index = 0, .level = 0}, - .currentMode = Mode_e::Init}; - /* IO Objects */ -Adafruit_NeoPixel ledRing{LedCount, LedPin, NEO_GRB + NEO_KHZ800}; Encoder encoder{EncoderPinA, EncoderPinB}; -AnalogButton button{AnalogButtonPin, AnalogButtonVRef}; - -/* debug Serial definition */ -#if defined(__PLATFORMIO_BUILD_DEBUG__) #if defined(ARDUINO_AVR_ATTINYX5) -#include +AnalogButton button{AnalogButtonPin, AnalogButtonVRef}; +#elif defined(ARDUINO_AVR_ATTINYX41) +Button button{ButtonPin}; +#else +/* No vRef defined force to calibrate for test purpose */ +AnalogButton button{AnalogButtonPin}; +#endif /* defined(ARDUINO_AVR_ATTINYX41) */ + +LedStrip ledStrip{}; + +/* debug Serial declaration */ +#if defined(__BUILD_DEBUG__) +#if defined(ARDUINO_AVR_ATTINYX5) SoftwareSerial debugSerial{RxPin, TxPin}; -#endif /* defined(ARDUINO_AVR_ATTINYX5) */ -#if defined(ARDUINO_AVR_UNO) -#include +#elif defined(ARDUINO_AVR_ATTINYX41) +HardwareSerial &debugSerial = Serial1; +#elif HardwareSerial &debugSerial = Serial; -#endif /* defined(ARDUINO_AVR_UNO) */ -#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ +#endif +#endif /* defined(__BUILD_DEBUG__) */ /* Private function declarations */ /*--------------------------------------------------------------------------------------------------------------------*/ @@ -116,39 +82,32 @@ void analog_button_calibration(void); int get_encoder_shift(void); -void display_mode(Mode_e mode); +// 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 */ /*--------------------------------------------------------------------------------------------------------------------*/ 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); + ledStrip.setup(); + button.setup(); -#if defined(__PLATFORMIO_BUILD_DEBUG__) +#if defined(__BUILD_DEBUG__) debugSerial.begin(9600); #if defined(DEBUG_INIT) while (!debugSerial.available()) ; #endif /* defined(DEBUG_INIT) */ debugSerial.println("Init ... "); -#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ - - analog_button_calibration(); +#endif /* defined(__BUILD_DEBUG__) */ get_encoder_shift(); -#if defined(__PLATFORMIO_BUILD_DEBUG__) - debugSerial.println(mode_str[static_cast(ledRingState.currentMode)]); -#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ +#if defined(__BUILD_DEBUG__) + debugSerial.println(mode_str[static_cast(currentMode)]); +#endif /* defined(__BUILD_DEBUG__) */ } void loop() { @@ -159,18 +118,19 @@ void loop() { while (button.is_button_pressed()) { delay(150); } - ++ledRingState.currentMode; + ++currentMode; -#if defined(__PLATFORMIO_BUILD_DEBUG__) - debugSerial.println(mode_str[static_cast(ledRingState.currentMode)]); -#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ +#if defined(__BUILD_DEBUG__) + debugSerial.println(mode_str[static_cast(currentMode)]); +#endif /* defined(__BUILD_DEBUG__) */ - display_mode(ledRingState.currentMode); + // display_mode(currentMode); hasModeChanged = true; } + ledStrip.setup(); if (shift != 0) { - switch (ledRingState.currentMode) { + switch (currentMode) { case Mode_e::ControlOff: ControlOff_execute(shift); break; @@ -179,34 +139,34 @@ void loop() { Preset_execute(shift); break; - case Mode_e::SetColor: - SetColor_execute(shift); - break; + // case Mode_e::SetColor: + // SetColor_execute(shift); + // break; - case Mode_e::SetBrightness: - SetBrightness_execute(shift); - break; + // case Mode_e::SetBrightness: + // SetBrightness_execute(shift); + // break; - case Mode_e::SetSaturation: - SetSaturation_execute(shift); - break; + // case Mode_e::SetSaturation: + // SetSaturation_execute(shift); + // break; - case Mode_e::LightOnMin: - LightOnMin_execute(shift); - break; + // case Mode_e::LightOnMin: + // LightOnMin_execute(shift); + // break; - case Mode_e::LightOnMax: - LightOnMax_execute(shift); - break; + // case Mode_e::LightOnMax: + // LightOnMax_execute(shift); + // break; default: break; } } - if (ledRingState.currentMode != Mode_e::ControlOff && (shift != 0 || hasModeChanged)) { - display_led_ring(); - } + // if (currentMode != Mode_e::ControlOff && (shift != 0 || hasModeChanged)) { + // display_led_ring(); + // } } /* Private function definitions */ @@ -217,184 +177,136 @@ void loop() { 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; - } - } + ledStrip.next_preset(); } else { - --preset.index; - if (preset.index == UINT8_MAX) { - preset.index = PresetMax - 1; - --preset.level; - if (preset.level == UINT8_MAX) { - preset.level = PresetLevelMax - 1; - } - } + ledStrip.previous_preset(); } } /* Preset_execute */ -void SetColor_execute(int shift) { - uint16_t &hue = ledRingState.ledRingColorState.hue; +// void SetColor_execute(int shift) { +// uint16_t &hue = ledRingState.ledRingColorState.hue; - hue += (shift << 8); +// hue += (shift << 8); -#if defined(__PLATFORMIO_BUILD_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(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ -} /* SetColor_execute */ +// #if defined(__BUILD_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(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ +// } /* SetColor_execute */ -void SetBrightness_execute(int shift) { - uint8_t &brightness = ledRingState.ledRingColorState.brightness; +// void SetBrightness_execute(int shift) { +// uint8_t &brightness = ledRingState.ledRingColorState.brightness; - brightness += (shift << 2); +// brightness += (shift << 2); -#if defined(__PLATFORMIO_BUILD_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(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ -} /* SetBrightness_execute */ +// #if defined(__BUILD_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(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ +// } /* SetBrightness_execute */ -void SetSaturation_execute(int shift) { - uint8_t &saturation = ledRingState.ledRingColorState.saturation; +// void SetSaturation_execute(int shift) { +// uint8_t &saturation = ledRingState.ledRingColorState.saturation; - saturation += (shift << 2); +// saturation += (shift << 2); -#if defined(__PLATFORMIO_BUILD_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(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ -} /* SetSaturation_execute */ +// #if defined(__BUILD_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(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ +// } /* SetSaturation_execute */ -void LightOnMin_execute(int shift) { - uint16_t &ledOnMin = ledRingState.ledRingColorState.ledOnMin; - uint16_t &ledOnMax = ledRingState.ledRingColorState.ledOnMax; +// void LightOnMin_execute(int shift) { +// uint16_t &ledOnMin = ledRingState.ledRingColorState.ledOnMin; +// uint16_t &ledOnMax = ledRingState.ledRingColorState.ledOnMax; - if (shift > 0) { - if (ledOnMin == ledOnMax) { - ledRingState.currentMode = Mode_e::LightOnMax; - ++ledOnMax; - } else { - ++ledOnMin; - if (ledOnMin == LedCount) { - ledOnMin = 0; - } - } - } else { - if (ledOnMin == ledOnMax) { - ledRingState.currentMode = Mode_e::LightOnMax; - --ledOnMax; - } else { - --ledOnMin; - if (ledOnMin == UINT16_MAX) { - ledOnMin = LedCount - 1; - } - } - } +// if (shift > 0) { +// if (ledOnMin == ledOnMax) { +// currentMode = Mode_e::LightOnMax; +// ++ledOnMax; +// } else { +// ++ledOnMin; +// if (ledOnMin == LedCount) { +// ledOnMin = 0; +// } +// } +// } else { +// if (ledOnMin == ledOnMax) { +// currentMode = Mode_e::LightOnMax; +// --ledOnMax; +// } else { +// --ledOnMin; +// if (ledOnMin == UINT16_MAX) { +// ledOnMin = LedCount - 1; +// } +// } +// } -#if defined(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO) - if (shift != 0) { - debugSerial.print(__func__); - debugSerial.print(" : shift="); - debugSerial.print(shift, DEC); - debugSerial.print(", ledOnMin="); - debugSerial.println(ledOnMin, DEC); - } -#endif /*defined(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ -} /* LightOnMin_execute */ +// #if defined(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO) +// if (shift != 0) { +// debugSerial.print(__func__); +// debugSerial.print(" : shift="); +// debugSerial.print(shift, DEC); +// debugSerial.print(", ledOnMin="); +// debugSerial.println(ledOnMin, DEC); +// } +// #endif /*defined(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ +// } /* LightOnMin_execute */ -void LightOnMax_execute(int shift) { - uint16_t &ledOnMin = ledRingState.ledRingColorState.ledOnMin; - uint16_t &ledOnMax = ledRingState.ledRingColorState.ledOnMax; +// 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 (shift > 0) { +// if (ledOnMax == ledOnMin) { +// currentMode = Mode_e::LightOnMin; +// ++ledOnMin; +// } else { +// ++ledOnMax; +// if (ledOnMax == LedCount) { +// ledOnMax = 0; +// } +// } +// } else { +// if (ledOnMax == ledOnMin) { +// currentMode = Mode_e::LightOnMin; +// --ledOnMin; +// } else { +// --ledOnMax; +// if (ledOnMax == UINT16_MAX) { +// ledOnMax = LedCount - 1; +// } +// } +// } -#if defined(__PLATFORMIO_BUILD_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(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ -} /* LightOnMax_execute */ +// #if defined(__BUILD_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(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ +// } /* LightOnMax_execute */ /* Others functions */ - -void analog_button_calibration(void) { - int highRef, lowRef; - -#if defined(__PLATFORMIO_BUILD_DEBUG__) && false - debugSerial.print(__func__); -#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ - - do { - highRef = analogRead(AnalogButtonPin); - delay(300); - } while (highRef < 1000); - -#if defined(__PLATFORMIO_BUILD_DEBUG__) && false - debugSerial.println("highRef="); - debugSerial.println(highRef); -#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ - - lowRef = analogRead(AnalogButtonPin); - while (highRef - lowRef < 50) { - lowRef = analogRead(AnalogButtonPin); - delay(300); - } - -#if defined(__PLATFORMIO_BUILD_DEBUG__) && false - debugSerial.println("lowRef="); - debugSerial.println(lowRef); -#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ - - button = AnalogButton{AnalogButtonPin, lowRef + 10}; -} - int get_encoder_shift(void) { int32_t static _previousValue{encoder.read()}; @@ -414,84 +326,84 @@ int get_encoder_shift(void) { } } -void display_mode(Mode_e mode) { - if (ledRingState.currentMode != Mode_e::ControlOff) { - 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_mode(Mode_e mode) { +// if (currentMode != Mode_e::ControlOff) { +// for (size_t i = 0; i < 3; ++i) { +// ledRing.fill(0); +// ledRing.show(); +// delay(300); +// for (Mode_e i = Mode_e::Init; i < 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; +// void display_led_ring(void) { +// PresetState_t &preset = ledRingState.presetState; +// LedRingColorState_t ledRingColorState; - if (ledRingState.currentMode == Mode_e::Preset) { -#if defined(__PLATFORMIO_BUILD_DEBUG__) && false - debugSerial.print("Preset index,level="); - debugSerial.print(preset.index); - debugSerial.print(","); - debugSerial.print(preset.level); - debugSerial.println(); -#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ - ledRingColorState = {.ledOnMin = ledRingState.ledRingColorState.ledOnMin, - .ledOnMax = ledRingState.ledRingColorState.ledOnMax, - .hue = PresetHue[preset.index], - .saturation = (preset.index == (PresetMax - 1)) ? 0 : UINT8_MAX, - .brightness = PresetBrightness[preset.level]}; - refresh_led_ring(ledRingColorState); - } else { - refresh_led_ring(); - } -} +// if (currentMode == Mode_e::Preset) { +// #if defined(__BUILD_DEBUG__) && false +// debugSerial.print("Preset index,level="); +// debugSerial.print(preset.index); +// debugSerial.print(","); +// debugSerial.print(preset.level); +// debugSerial.println(); +// #endif /* defined(__BUILD_DEBUG__) */ +// ledRingColorState = {.ledOnMin = ledRingState.ledRingColorState.ledOnMin, +// .ledOnMax = ledRingState.ledRingColorState.ledOnMax, +// .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) { - uint16_t const &ledOnMin = ledRingColorState.ledOnMin; - uint16_t const &ledOnMax = ledRingColorState.ledOnMax; - uint16_t LedOnCount = 0; +// void refresh_led_ring(LedRingColorState_t const &ledRingColorState) { +// uint16_t const &ledOnMin = ledRingColorState.ledOnMin; +// uint16_t const &ledOnMax = ledRingColorState.ledOnMax; +// uint16_t LedOnCount = 0; -#if defined(__PLATFORMIO_BUILD_DEBUG__) - debugSerial.print("Color hue,sat,bri="); - debugSerial.print(ledRingColorState.hue); - debugSerial.print(","); - debugSerial.print(ledRingColorState.saturation); - debugSerial.print(","); - debugSerial.println(ledRingColorState.brightness); -#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ +// #if defined(__BUILD_DEBUG__) +// debugSerial.print("Color hue,sat,bri="); +// debugSerial.print(ledRingColorState.hue); +// debugSerial.print(","); +// debugSerial.print(ledRingColorState.saturation); +// debugSerial.print(","); +// debugSerial.println(ledRingColorState.brightness); +// #endif /* defined(__BUILD_DEBUG__) */ - /* reset ring */ - ledRing.fill(0); +// /* reset ring */ +// ledRing.fill(0); - /* compute number of led on */ - if (ledOnMin <= ledOnMax) { - LedOnCount = ledOnMax - ledOnMin; - } else { - LedOnCount = LedCount - (ledOnMax - ledOnMax); - } +// /* compute number of led on */ +// if (ledOnMin <= ledOnMax) { +// LedOnCount = ledOnMax - ledOnMin; +// } else { +// LedOnCount = LedCount - (ledOnMax - ledOnMax); +// } -#if defined(__PLATFORMIO_BUILD_DEBUG__) - debugSerial.print("Led min,max,count="); - debugSerial.print(ledOnMin); - debugSerial.print(","); - debugSerial.print(ledOnMax); - debugSerial.print(","); - debugSerial.println(LedOnCount); -#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ +// #if defined(__BUILD_DEBUG__) +// debugSerial.print("Led min,max,count="); +// debugSerial.print(ledOnMin); +// debugSerial.print(","); +// debugSerial.print(ledOnMax); +// debugSerial.print(","); +// debugSerial.println(LedOnCount); +// #endif /* defined(__BUILD_DEBUG__) */ - for (size_t i = ledRingColorState.ledOnMin; i < ledRingColorState.ledOnMin + LedOnCount; ++i) { - unsigned int ledId = i; - 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 +// for (size_t i = ledRingColorState.ledOnMin; i < ledRingColorState.ledOnMin + LedOnCount; ++i) { +// unsigned int ledId = i; +// 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/pin_map.hpp b/src/pin_map.hpp index d3f4e4c..d6a17e1 100644 --- a/src/pin_map.hpp +++ b/src/pin_map.hpp @@ -1,22 +1,42 @@ +#ifndef __PIN_MAP_HPP__ +#define __PIN_MAP_HPP__ + #if defined(ARDUINO_AVR_ATTINYX5) -/* Led output pin */ +/* LedStrip output pin */ uint8_t const LedPin{PB0}; /* Button analog input pin */ +/* Note: we use PB5 as button input which is also the reset pin, to avoid reseting we read an analogic value with + * lower voltage than the triger value of reset */ +int const AnalogButtonVRef{970}; uint8_t const AnalogButtonPin{0}; /* Rotary encoder input pins */ uint8_t const EncoderPinA{PB3}; uint8_t const EncoderPinB{PB4}; /* Uart for serial debug pins */ -#if defined(__PLATFORMIO_BUILD_DEBUG__) +#if defined(__BUILD_DEBUG__) uint8_t const TxPin{PB1}; uint8_t const RxPin{PB2}; -#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ -#endif /* defined(ARDUINO_AVR_ATTINYX5) */ +#endif /* defined(__BUILD_DEBUG__) */ +#elif defined(ARDUINO_AVR_ATTINYX41) +/* LedStrip output pin */ +uint8_t const LedPin{PA1}; -#if defined(ARDUINO_AVR_UNO) -/* Led output pin */ +/* Button input pin (internally pulled up) */ +uint8_t const ButtonPin{ADC11D}; +/* Rotary encoder input pins */ +uint8_t const EncoderPinA{PA2}; +uint8_t const EncoderPinB{PA3}; + +/* Uart for serial debug pins */ +#if defined(__BUILD_DEBUG__) +uint8_t const TxPin{PA5}; +uint8_t const RxPin{PA4}; +#endif /* defined(__BUILD_DEBUG__) */ + +#elif defined(ARDUINO_AVR_UNO) +/* LedStrip output pin */ uint8_t const LedPin{6}; /* Button analog input pin */ @@ -24,4 +44,6 @@ uint8_t const AnalogButtonPin{A0}; /* Rotary encoder input pins */ uint8_t const EncoderPinA{8}; uint8_t const EncoderPinB{9}; -#endif /* defined(ARDUINO_AVR_UNO) */ \ No newline at end of file +#endif /* Hardware selection */ + +#endif /* __PIN_MAP_HPP__ */ \ No newline at end of file