wip adapting for attiny841

This commit is contained in:
Tropicananass 2025-01-24 12:03:35 +01:00
parent f6c4f27efa
commit a562810380
12 changed files with 643 additions and 356 deletions

View File

@ -54,7 +54,7 @@ BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true BreakStringLiterals: true
ColumnLimit: 80 ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:' CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false ConstructorInitializerAllOnOneLineOrOnePerLine: false

View File

@ -9,12 +9,11 @@
; https://docs.platformio.org/page/projectconf.html ; https://docs.platformio.org/page/projectconf.html
[platformio] [platformio]
default_envs = attiny85_debug default_envs = attiny841_debug
[env] [env]
build_flags = -Wall build_flags = -Wall
lib_deps = lib_deps =
Adafruit NeoPixel
Encoder Encoder
[env:attiny85] [env:attiny85]
@ -23,10 +22,6 @@ platform = atmelavr
board = attiny85 board = attiny85
framework = arduino framework = arduino
upload_protocol = usbtiny upload_protocol = usbtiny
board_build.f_cpu = 16000000L
; board_fuses.lfuse = 0xAA
; board_fuses.hfuse = 0xBB
; board_fuses.efuse = 0xCC
[env:attiny85_debug] [env:attiny85_debug]
build_type = debug build_type = debug
@ -37,9 +32,27 @@ build_type = debug
extends = env:attiny85_debug extends = env:attiny85_debug
build_flags = -D DEBUG_INIT 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] [env:uno]
build_type = debug build_type = debug
lib_deps =
Adafruit NeoPixel
platform = atmelavr platform = atmelavr
board = uno board = uno
framework = arduino framework = arduino

Binary file not shown.

Binary file not shown.

View File

@ -2,10 +2,48 @@
#include <Arduino.h> #include <Arduino.h>
bool AnalogButton::is_button_pressed(void) { void Button::setup(void) { pinMode(_pin, INPUT_PULLUP); }
return analogRead(_aPin) < _vRef;
bool Button::is_button_pressed(void) { return digitalRead(_pin) == 0; }
void AnalogButton::setup(void) {
if (_vRef < 0) {
calibrate();
}
} }
bool AnalogButton::is_button_pressed(void) { return analogRead(_pin) < _vRef; }
void AnalogButton::calibrate(void) { 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;
} }

View File

@ -3,14 +3,33 @@
#include <stdint.h> #include <stdint.h>
class AnalogButton { class Button {
public: public:
AnalogButton(uint8_t analogPin, int vRef) : _aPin{analogPin}, _vRef{vRef} {}; Button(uint8_t pin) : _pin{pin} {};
~Button() {};
void setup(void);
bool is_button_pressed(void); bool is_button_pressed(void);
void calibrate(void);
protected:
uint8_t _pin;
private:
};
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: private:
uint8_t _aPin;
int _vRef; int _vRef;
void calibrate(void);
}; };
#endif /* __BUTTON_HPP__ */ #endif /* __BUTTON_HPP__ */

14
src/global.hpp Normal file
View File

@ -0,0 +1,14 @@
#ifndef __GLOBAL_HPP__
#define __GLOBAL_HPP__
#include <Arduino.h>
/* debug Serial definition */
#if defined(__BUILD_DEBUG__)
#if defined(ARDUINO_AVR_ATTINYX5)
extern SoftwareSerial debugSerial;
#else
extern HardwareSerial &debugSerial;
#endif
#endif
#endif /* __GLOBAL_HPP__ */

194
src/led_strip.cpp Normal file
View File

@ -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);
// }
// }
// }

75
src/led_strip.hpp Normal file
View File

@ -0,0 +1,75 @@
#ifndef __LED_STRIP_HPP__
#define __LED_STRIP_HPP__
#include <Arduino.h>
#if defined(ARDUINO_AVR_ATTINYX5) || defined(ARDUINO_AVR_ATTINYX41)
#include <tinyNeoPixel_Static.h>
#else
#include <Adafruit_NeoPixel.h>
#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__ */

View File

@ -1,12 +1,12 @@
#include <Arduino.h> #include <Arduino.h>
// TODO : use core built-in lib tinyNeoPixel
#include <Adafruit_NeoPixel.h>
#include <Encoder.h> #include <Encoder.h>
#include "button.hpp" #include "global.hpp"
#include "pin_map.hpp" #include "pin_map.hpp"
#include "button.hpp"
#include "led_strip.hpp"
/* Types and Constants */ /* Types and Constants */
/*--------------------------------------------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------------------------------------------*/
@ -15,11 +15,11 @@
MODE(Init) \ MODE(Init) \
MODE(LightOnMin) \ MODE(LightOnMin) \
MODE(LightOnMax) \ MODE(LightOnMax) \
MODE(ControlOff) \
MODE(Preset) \ MODE(Preset) \
MODE(SetColor) \ MODE(SetColor) \
MODE(SetSaturation) \ MODE(SetSaturation) \
MODE(SetBrightness) MODE(SetBrightness) \
MODE(ControlOff)
#define GENERATE_MODE_ENUM(ENUM) ENUM, #define GENERATE_MODE_ENUM(ENUM) ENUM,
@ -34,75 +34,41 @@ Mode_e &operator++(Mode_e &mode) {
return mode = static_cast<Mode_e>(static_cast<int>(mode) + 1); return mode = static_cast<Mode_e>(static_cast<int>(mode) + 1);
} }
#if defined(__PLATFORMIO_BUILD_DEBUG__) #if defined(__BUILD_DEBUG__)
/* Generate string array from Mode_e names */ /* 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 /* defined(__PLATFORMIO_BUILD_DEBUG__) */ #endif /* defined(__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;
/* Led ring system state */ /* Led ring system state */
typedef struct { Mode_e currentMode{Mode_e::Init};
LedRingColorState_t ledRingColorState;
PresetState_t presetState;
Mode_e currentMode;
} LedRingState_t;
/* Button */
int const AnalogButtonVRef{970};
/* Global variables */ /* 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 */ /* IO Objects */
Adafruit_NeoPixel ledRing{LedCount, LedPin, NEO_GRB + NEO_KHZ800};
Encoder encoder{EncoderPinA, EncoderPinB}; Encoder encoder{EncoderPinA, EncoderPinB};
AnalogButton button{AnalogButtonPin, AnalogButtonVRef};
/* debug Serial definition */
#if defined(__PLATFORMIO_BUILD_DEBUG__)
#if defined(ARDUINO_AVR_ATTINYX5) #if defined(ARDUINO_AVR_ATTINYX5)
#include <SoftwareSerial.h> 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}; SoftwareSerial debugSerial{RxPin, TxPin};
#endif /* defined(ARDUINO_AVR_ATTINYX5) */ #elif defined(ARDUINO_AVR_ATTINYX41)
#if defined(ARDUINO_AVR_UNO) HardwareSerial &debugSerial = Serial1;
#include <HardwareSerial.h> #elif
HardwareSerial &debugSerial = Serial; HardwareSerial &debugSerial = Serial;
#endif /* defined(ARDUINO_AVR_UNO) */ #endif
#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ #endif /* defined(__BUILD_DEBUG__) */
/* Private function declarations */ /* Private function declarations */
/*--------------------------------------------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------------------------------------------*/
@ -116,39 +82,32 @@ void analog_button_calibration(void);
int get_encoder_shift(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 */ /* Function definitions */
/*--------------------------------------------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------------------------------------------*/
void setup() { void setup() {
ledRing.begin(); ledStrip.setup();
ledRing.fill(Adafruit_NeoPixel::Color(45, 0, 0)); button.setup();
delay(300);
ledRing.fill(Adafruit_NeoPixel::Color(0, 45, 0));
delay(300);
ledRing.fill(Adafruit_NeoPixel::Color(0, 0, 45));
delay(300);
#if defined(__PLATFORMIO_BUILD_DEBUG__) #if defined(__BUILD_DEBUG__)
debugSerial.begin(9600); debugSerial.begin(9600);
#if defined(DEBUG_INIT) #if defined(DEBUG_INIT)
while (!debugSerial.available()) while (!debugSerial.available())
; ;
#endif /* defined(DEBUG_INIT) */ #endif /* defined(DEBUG_INIT) */
debugSerial.println("Init ... "); debugSerial.println("Init ... ");
#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ #endif /* defined(__BUILD_DEBUG__) */
analog_button_calibration();
get_encoder_shift(); get_encoder_shift();
#if defined(__PLATFORMIO_BUILD_DEBUG__) #if defined(__BUILD_DEBUG__)
debugSerial.println(mode_str[static_cast<int>(ledRingState.currentMode)]); debugSerial.println(mode_str[static_cast<int>(currentMode)]);
#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ #endif /* defined(__BUILD_DEBUG__) */
} }
void loop() { void loop() {
@ -159,18 +118,19 @@ void loop() {
while (button.is_button_pressed()) { while (button.is_button_pressed()) {
delay(150); delay(150);
} }
++ledRingState.currentMode; ++currentMode;
#if defined(__PLATFORMIO_BUILD_DEBUG__) #if defined(__BUILD_DEBUG__)
debugSerial.println(mode_str[static_cast<int>(ledRingState.currentMode)]); debugSerial.println(mode_str[static_cast<int>(currentMode)]);
#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ #endif /* defined(__BUILD_DEBUG__) */
display_mode(ledRingState.currentMode); // display_mode(currentMode);
hasModeChanged = true; hasModeChanged = true;
} }
ledStrip.setup();
if (shift != 0) { if (shift != 0) {
switch (ledRingState.currentMode) { switch (currentMode) {
case Mode_e::ControlOff: case Mode_e::ControlOff:
ControlOff_execute(shift); ControlOff_execute(shift);
break; break;
@ -179,34 +139,34 @@ void loop() {
Preset_execute(shift); Preset_execute(shift);
break; break;
case Mode_e::SetColor: // case Mode_e::SetColor:
SetColor_execute(shift); // SetColor_execute(shift);
break; // break;
case Mode_e::SetBrightness: // case Mode_e::SetBrightness:
SetBrightness_execute(shift); // SetBrightness_execute(shift);
break; // break;
case Mode_e::SetSaturation: // case Mode_e::SetSaturation:
SetSaturation_execute(shift); // SetSaturation_execute(shift);
break; // break;
case Mode_e::LightOnMin: // case Mode_e::LightOnMin:
LightOnMin_execute(shift); // LightOnMin_execute(shift);
break; // break;
case Mode_e::LightOnMax: // case Mode_e::LightOnMax:
LightOnMax_execute(shift); // LightOnMax_execute(shift);
break; // break;
default: default:
break; break;
} }
} }
if (ledRingState.currentMode != Mode_e::ControlOff && (shift != 0 || hasModeChanged)) { // if (currentMode != Mode_e::ControlOff && (shift != 0 || hasModeChanged)) {
display_led_ring(); // display_led_ring();
} // }
} }
/* Private function definitions */ /* Private function definitions */
@ -217,184 +177,136 @@ void loop() {
void ControlOff_execute(int shift) {} void ControlOff_execute(int shift) {}
void Preset_execute(int shift) { void Preset_execute(int shift) {
PresetState_t &preset = ledRingState.presetState;
if (shift > 0) { if (shift > 0) {
++preset.index; ledStrip.next_preset();
if (preset.index >= PresetMax) {
preset.index = 0;
++preset.level;
if (preset.level >= PresetLevelMax) {
preset.level = 0;
}
}
} else { } else {
--preset.index; ledStrip.previous_preset();
if (preset.index == UINT8_MAX) {
preset.index = PresetMax - 1;
--preset.level;
if (preset.level == UINT8_MAX) {
preset.level = PresetLevelMax - 1;
}
}
} }
} /* Preset_execute */ } /* Preset_execute */
void SetColor_execute(int shift) { // void SetColor_execute(int shift) {
uint16_t &hue = ledRingState.ledRingColorState.hue; // uint16_t &hue = ledRingState.ledRingColorState.hue;
hue += (shift << 8); // hue += (shift << 8);
#if defined(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO) // #if defined(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)
if (shift != 0) { // if (shift != 0) {
debugSerial.print(__func__); // debugSerial.print(__func__);
debugSerial.print(" : shift="); // debugSerial.print(" : shift=");
debugSerial.print(shift, DEC); // debugSerial.print(shift, DEC);
debugSerial.print(", hue="); // debugSerial.print(", hue=");
debugSerial.println(hue, DEC); // debugSerial.println(hue, DEC);
} // }
#endif /*defined(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ // #endif /*defined(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/
} /* SetColor_execute */ // } /* SetColor_execute */
void SetBrightness_execute(int shift) { // void SetBrightness_execute(int shift) {
uint8_t &brightness = ledRingState.ledRingColorState.brightness; // uint8_t &brightness = ledRingState.ledRingColorState.brightness;
brightness += (shift << 2); // brightness += (shift << 2);
#if defined(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO) // #if defined(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)
if (shift != 0) { // if (shift != 0) {
debugSerial.print(__func__); // debugSerial.print(__func__);
debugSerial.print(" : shift="); // debugSerial.print(" : shift=");
debugSerial.print(shift, DEC); // debugSerial.print(shift, DEC);
debugSerial.print(", brightness="); // debugSerial.print(", brightness=");
debugSerial.println(brightness, DEC); // debugSerial.println(brightness, DEC);
} // }
#endif /*defined(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ // #endif /*defined(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/
} /* SetBrightness_execute */ // } /* SetBrightness_execute */
void SetSaturation_execute(int shift) { // void SetSaturation_execute(int shift) {
uint8_t &saturation = ledRingState.ledRingColorState.saturation; // uint8_t &saturation = ledRingState.ledRingColorState.saturation;
saturation += (shift << 2); // saturation += (shift << 2);
#if defined(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO) // #if defined(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)
if (shift != 0) { // if (shift != 0) {
debugSerial.print(__func__); // debugSerial.print(__func__);
debugSerial.print(" : shift="); // debugSerial.print(" : shift=");
debugSerial.print(shift, DEC); // debugSerial.print(shift, DEC);
debugSerial.print(", saturation="); // debugSerial.print(", saturation=");
debugSerial.println(saturation, DEC); // debugSerial.println(saturation, DEC);
} // }
#endif /*defined(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ // #endif /*defined(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/
} /* SetSaturation_execute */ // } /* SetSaturation_execute */
void LightOnMin_execute(int shift) { // void LightOnMin_execute(int shift) {
uint16_t &ledOnMin = ledRingState.ledRingColorState.ledOnMin; // uint16_t &ledOnMin = ledRingState.ledRingColorState.ledOnMin;
uint16_t &ledOnMax = ledRingState.ledRingColorState.ledOnMax; // uint16_t &ledOnMax = ledRingState.ledRingColorState.ledOnMax;
if (shift > 0) { // if (shift > 0) {
if (ledOnMin == ledOnMax) { // if (ledOnMin == ledOnMax) {
ledRingState.currentMode = Mode_e::LightOnMax; // currentMode = Mode_e::LightOnMax;
++ledOnMax; // ++ledOnMax;
} else { // } else {
++ledOnMin; // ++ledOnMin;
if (ledOnMin == LedCount) { // if (ledOnMin == LedCount) {
ledOnMin = 0; // ledOnMin = 0;
} // }
} // }
} else { // } else {
if (ledOnMin == ledOnMax) { // if (ledOnMin == ledOnMax) {
ledRingState.currentMode = Mode_e::LightOnMax; // currentMode = Mode_e::LightOnMax;
--ledOnMax; // --ledOnMax;
} else { // } else {
--ledOnMin; // --ledOnMin;
if (ledOnMin == UINT16_MAX) { // if (ledOnMin == UINT16_MAX) {
ledOnMin = LedCount - 1; // ledOnMin = LedCount - 1;
} // }
} // }
} // }
#if defined(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO) // #if defined(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)
if (shift != 0) { // if (shift != 0) {
debugSerial.print(__func__); // debugSerial.print(__func__);
debugSerial.print(" : shift="); // debugSerial.print(" : shift=");
debugSerial.print(shift, DEC); // debugSerial.print(shift, DEC);
debugSerial.print(", ledOnMin="); // debugSerial.print(", ledOnMin=");
debugSerial.println(ledOnMin, DEC); // debugSerial.println(ledOnMin, DEC);
} // }
#endif /*defined(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ // #endif /*defined(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/
} /* LightOnMin_execute */ // } /* LightOnMin_execute */
void LightOnMax_execute(int shift) { // void LightOnMax_execute(int shift) {
uint16_t &ledOnMin = ledRingState.ledRingColorState.ledOnMin; // uint16_t &ledOnMin = ledRingState.ledRingColorState.ledOnMin;
uint16_t &ledOnMax = ledRingState.ledRingColorState.ledOnMax; // uint16_t &ledOnMax = ledRingState.ledRingColorState.ledOnMax;
if (shift > 0) { // if (shift > 0) {
if (ledOnMax == ledOnMin) { // if (ledOnMax == ledOnMin) {
ledRingState.currentMode = Mode_e::LightOnMin; // currentMode = Mode_e::LightOnMin;
++ledOnMin; // ++ledOnMin;
} else { // } else {
++ledOnMax; // ++ledOnMax;
if (ledOnMax == LedCount) { // if (ledOnMax == LedCount) {
ledOnMax = 0; // ledOnMax = 0;
} // }
} // }
} else { // } else {
if (ledOnMax == ledOnMin) { // if (ledOnMax == ledOnMin) {
ledRingState.currentMode = Mode_e::LightOnMin; // currentMode = Mode_e::LightOnMin;
--ledOnMin; // --ledOnMin;
} else { // } else {
--ledOnMax; // --ledOnMax;
if (ledOnMax == UINT16_MAX) { // if (ledOnMax == UINT16_MAX) {
ledOnMax = LedCount - 1; // ledOnMax = LedCount - 1;
} // }
} // }
} // }
#if defined(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO) // #if defined(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)
if (shift != 0) { // if (shift != 0) {
debugSerial.print(__func__); // debugSerial.print(__func__);
debugSerial.print(" : shift="); // debugSerial.print(" : shift=");
debugSerial.print(shift, DEC); // debugSerial.print(shift, DEC);
debugSerial.print(", ledOnMax="); // debugSerial.print(", ledOnMax=");
debugSerial.println(ledOnMax, DEC); // debugSerial.println(ledOnMax, DEC);
} // }
#endif /*defined(__PLATFORMIO_BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/ // #endif /*defined(__BUILD_DEBUG__) && defined(ARDUINO_AVR_UNO)*/
} /* LightOnMax_execute */ // } /* LightOnMax_execute */
/* Others functions */ /* 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) { int get_encoder_shift(void) {
int32_t static _previousValue{encoder.read()}; int32_t static _previousValue{encoder.read()};
@ -414,84 +326,84 @@ int get_encoder_shift(void) {
} }
} }
void display_mode(Mode_e mode) { // void display_mode(Mode_e mode) {
if (ledRingState.currentMode != Mode_e::ControlOff) { // if (currentMode != Mode_e::ControlOff) {
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 < currentMode; ++i) {
ledRing.setPixelColor(int(i), Adafruit_NeoPixel::ColorHSV(0, 255, 16)); // ledRing.setPixelColor(int(i), Adafruit_NeoPixel::ColorHSV(0, 255, 16));
} // }
ledRing.show(); // ledRing.show();
delay(300); // delay(300);
} // }
} // }
} // }
void display_led_ring(void) { // void display_led_ring(void) {
PresetState_t &preset = ledRingState.presetState; // PresetState_t &preset = ledRingState.presetState;
LedRingColorState_t ledRingColorState; // LedRingColorState_t ledRingColorState;
if (ledRingState.currentMode == Mode_e::Preset) { // if (currentMode == Mode_e::Preset) {
#if defined(__PLATFORMIO_BUILD_DEBUG__) && false // #if defined(__BUILD_DEBUG__) && false
debugSerial.print("Preset index,level="); // debugSerial.print("Preset index,level=");
debugSerial.print(preset.index); // debugSerial.print(preset.index);
debugSerial.print(","); // debugSerial.print(",");
debugSerial.print(preset.level); // debugSerial.print(preset.level);
debugSerial.println(); // debugSerial.println();
#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ // #endif /* defined(__BUILD_DEBUG__) */
ledRingColorState = {.ledOnMin = ledRingState.ledRingColorState.ledOnMin, // ledRingColorState = {.ledOnMin = ledRingState.ledRingColorState.ledOnMin,
.ledOnMax = ledRingState.ledRingColorState.ledOnMax, // .ledOnMax = ledRingState.ledRingColorState.ledOnMax,
.hue = PresetHue[preset.index], // .hue = PresetHue[preset.index],
.saturation = (preset.index == (PresetMax - 1)) ? 0 : UINT8_MAX, // .saturation = (preset.index == (PresetMax - 1)) ? 0 : UINT8_MAX,
.brightness = PresetBrightness[preset.level]}; // .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) {
uint16_t const &ledOnMin = ledRingColorState.ledOnMin; // uint16_t const &ledOnMin = ledRingColorState.ledOnMin;
uint16_t const &ledOnMax = ledRingColorState.ledOnMax; // uint16_t const &ledOnMax = ledRingColorState.ledOnMax;
uint16_t LedOnCount = 0; // uint16_t LedOnCount = 0;
#if defined(__PLATFORMIO_BUILD_DEBUG__) // #if defined(__BUILD_DEBUG__)
debugSerial.print("Color hue,sat,bri="); // 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 /* defined(__PLATFORMIO_BUILD_DEBUG__) */ // #endif /* defined(__BUILD_DEBUG__) */
/* reset ring */ // /* reset ring */
ledRing.fill(0); // ledRing.fill(0);
/* compute number of led on */ // /* compute number of led on */
if (ledOnMin <= ledOnMax) { // if (ledOnMin <= ledOnMax) {
LedOnCount = ledOnMax - ledOnMin; // LedOnCount = ledOnMax - ledOnMin;
} else { // } else {
LedOnCount = LedCount - (ledOnMax - ledOnMax); // LedOnCount = LedCount - (ledOnMax - ledOnMax);
} // }
#if defined(__PLATFORMIO_BUILD_DEBUG__) // #if defined(__BUILD_DEBUG__)
debugSerial.print("Led min,max,count="); // debugSerial.print("Led min,max,count=");
debugSerial.print(ledOnMin); // debugSerial.print(ledOnMin);
debugSerial.print(","); // debugSerial.print(",");
debugSerial.print(ledOnMax); // debugSerial.print(ledOnMax);
debugSerial.print(","); // debugSerial.print(",");
debugSerial.println(LedOnCount); // debugSerial.println(LedOnCount);
#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ // #endif /* defined(__BUILD_DEBUG__) */
for (size_t i = ledRingColorState.ledOnMin; i < ledRingColorState.ledOnMin + LedOnCount; ++i) { // for (size_t i = ledRingColorState.ledOnMin; i < ledRingColorState.ledOnMin + LedOnCount; ++i) {
unsigned int ledId = i; // unsigned int ledId = i;
if (ledId >= LedCount) { // if (ledId >= LedCount) {
ledId -= LedCount; // ledId -= LedCount;
} // }
ledRing.setPixelColor(ledId, Adafruit_NeoPixel::ColorHSV(ledRingColorState.hue, ledRingColorState.saturation, // ledRing.setPixelColor(ledId, Adafruit_NeoPixel::ColorHSV(ledRingColorState.hue, ledRingColorState.saturation,
ledRingColorState.brightness)); // ledRingColorState.brightness));
} // }
ledRing.show(); // ledRing.show();
} // }

View File

@ -1,22 +1,42 @@
#ifndef __PIN_MAP_HPP__
#define __PIN_MAP_HPP__
#if defined(ARDUINO_AVR_ATTINYX5) #if defined(ARDUINO_AVR_ATTINYX5)
/* Led output pin */ /* LedStrip output pin */
uint8_t const LedPin{PB0}; uint8_t const LedPin{PB0};
/* Button analog input pin */ /* 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}; uint8_t const AnalogButtonPin{0};
/* Rotary encoder input pins */ /* Rotary encoder input pins */
uint8_t const EncoderPinA{PB3}; uint8_t const EncoderPinA{PB3};
uint8_t const EncoderPinB{PB4}; uint8_t const EncoderPinB{PB4};
/* Uart for serial debug pins */ /* Uart for serial debug pins */
#if defined(__PLATFORMIO_BUILD_DEBUG__) #if defined(__BUILD_DEBUG__)
uint8_t const TxPin{PB1}; uint8_t const TxPin{PB1};
uint8_t const RxPin{PB2}; uint8_t const RxPin{PB2};
#endif /* defined(__PLATFORMIO_BUILD_DEBUG__) */ #endif /* defined(__BUILD_DEBUG__) */
#endif /* defined(ARDUINO_AVR_ATTINYX5) */ #elif defined(ARDUINO_AVR_ATTINYX41)
/* LedStrip output pin */
uint8_t const LedPin{PA1};
#if defined(ARDUINO_AVR_UNO) /* Button input pin (internally pulled up) */
/* Led output pin */ 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}; uint8_t const LedPin{6};
/* Button analog input pin */ /* Button analog input pin */
@ -24,4 +44,6 @@ uint8_t const AnalogButtonPin{A0};
/* Rotary encoder input pins */ /* Rotary encoder input pins */
uint8_t const EncoderPinA{8}; uint8_t const EncoderPinA{8};
uint8_t const EncoderPinB{9}; uint8_t const EncoderPinB{9};
#endif /* defined(ARDUINO_AVR_UNO) */ #endif /* Hardware selection */
#endif /* __PIN_MAP_HPP__ */