Skip to content

Instantly share code, notes, and snippets.

@mnemocron
Created March 23, 2025 19:43
Show Gist options
  • Save mnemocron/8a2af11e37172fa5b4e34ccb24bfa283 to your computer and use it in GitHub Desktop.
Save mnemocron/8a2af11e37172fa5b4e34ccb24bfa283 to your computer and use it in GitHub Desktop.
#include <EventButton.h>
#include <Adafruit_NeoPixel.h>
#include <EEPROM.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define LED_PIN 2
#define BTN_PIN 3
#define LED_COUNT 16
#define EEPROM_ADDR 1
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
EventButton leButton(BTN_PIN);
typedef enum {SABER_OFF, SABER_ON, SABER_SETTINGS_START, SABER_SETTINGS, SABER_SETTINGS_EXIT} saber_state_t;
saber_state_t saber_state = SABER_OFF;
uint8_t wheel_counter = 0;
uint32_t leColor;
void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
leButton.begin();
leButton.setCallback(btn_callback);
strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
strip.show(); // Turn OFF all pixels ASAP
wheel_counter = EEPROM.read(EEPROM_ADDR);
}
void loop() {
leButton.update();
switch(saber_state){
case SABER_OFF:
//bladeOn(0,10);
break;
case SABER_ON:
//leColor = Wheel(wheel_counter);
//bladeOff(leColor,10);
break;
case SABER_SETTINGS_START:
bladeOn(0,0);
delay(200);
bladeOn(leColor,0);
delay(200);
bladeOn(0,0);
delay(200);
bladeOn(leColor,0);
delay(200);
saber_state = SABER_SETTINGS;
case SABER_SETTINGS:
leColor = Wheel(wheel_counter);
bladeOn(leColor,0);
break;
case SABER_SETTINGS_EXIT:
EEPROM.write(EEPROM_ADDR, wheel_counter);
bladeOn(0,0);
delay(200);
bladeOn(leColor,0);
delay(200);
bladeOn(0,0);
delay(200);
bladeOn(leColor,0);
saber_state = SABER_ON;
break;
default:
saber_state = SABER_OFF;
}
}
void btn_callback(InputEventType et, EventButton& eb) {
switch (et) {
case InputEventType::CLICKED :
if(saber_state == SABER_OFF){
saber_state = SABER_ON;
leColor = Wheel(wheel_counter);
bladeOn(leColor,10);
} else if(saber_state == SABER_ON){
saber_state = SABER_OFF;
bladeOff(0,10);
}
break;
case InputEventType::LONG_PRESS :
if(saber_state == SABER_ON){
saber_state = SABER_SETTINGS_START;
}
if(saber_state == SABER_SETTINGS){
wheel_counter += 5;
}
break;
case InputEventType::DOUBLE_CLICKED :
if(saber_state == SABER_SETTINGS){
saber_state = SABER_SETTINGS_EXIT;
}
break;
default:
break;
}
}
void bladeOn(uint32_t color, int wait) {
for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
strip.show(); // Update strip to match
delay(wait); // Pause for a moment
}
}
void bladeOff(uint32_t color, int wait) {
for(int i=strip.numPixels()-1; i>=0; i--) { // For each pixel in strip...
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
strip.show(); // Update strip to match
delay(wait); // Pause for a moment
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment