lithophane_lantern/arduino/lithophane.ino

140 lines
3.0 KiB
C++

#include <WS2812FX.h>
#define BRIGHTNESS 150
#define SPEED 1000
#define LED_COUNT 12
#define LED_SEGMENTS 4
#define LED_PIN D1
#define MODE_PIN D6
#define COLOR_PIN D7
#define TIMER_COLOR 60000
#define TIMER_MODE 480000
unsigned long now = 0;
unsigned long last_mode = 0;
unsigned long last_color = 0;
volatile unsigned short current_mode = 0;
volatile unsigned short current_color = 0;
volatile unsigned short increment_mode = 0;
volatile unsigned short increment_color = 0;
volatile bool auto_mode = true;
volatile bool auto_color = true;
const uint32_t colors_cycle [8] = {
0x777777,
0xFF0000,
0xFF6900,
0xFFF900,
0x05B600,
0x10F8FA,
0x002AFF,
0xFFD0B9
};
const unsigned int modes_cycle [7] = {
FX_MODE_STATIC,
FX_MODE_COMET,
FX_MODE_BREATH,
FX_MODE_FIRE_FLICKER,
FX_MODE_FIRE_FLICKER_INTENSE,
FX_MODE_FIRE_FLICKER_SOFT,
FX_MODE_SCAN
};
const unsigned int speed_cycle [7] = {
1000,
200,
200,
200,
200,
200,
1000
};
WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void ICACHE_RAM_ATTR changeModeInterrupt() {
bool color_state = digitalRead(COLOR_PIN);
if(color_state) {
auto_mode = true;
auto_color = true;
} else {
auto_mode = false;
}
increment_mode++;
}
void ICACHE_RAM_ATTR changeColorInterrupt() {
bool mode_state = digitalRead(MODE_PIN);
if(mode_state) {
auto_mode = true;
auto_color = true;
} else {
auto_color = false;
}
increment_color++;
}
void setup() {
int size = LED_COUNT/LED_SEGMENTS;
int seg=0;
pinMode(MODE_PIN, INPUT_PULLUP);
pinMode(COLOR_PIN, INPUT_PULLUP);
attachInterrupt(
digitalPinToInterrupt(MODE_PIN),
changeModeInterrupt, RISING);
attachInterrupt(
digitalPinToInterrupt(COLOR_PIN),
changeColorInterrupt, RISING);
ws2812fx.init();
ws2812fx.setBrightness(BRIGHTNESS);
for(seg=0; seg<LED_SEGMENTS; seg++) {
ws2812fx.setSegment(
seg,
seg*size, (seg+1)*size-1,
modes_cycle[current_mode], colors_cycle[current_color],
speed_cycle[current_mode], seg%2==1);
}
ws2812fx.start();
}
void loop() {
int size = LED_COUNT/LED_SEGMENTS;
int seg = 0;
now = millis();
ws2812fx.service();
if(auto_mode && now-last_mode>TIMER_MODE) {
increment_mode++;
}
if(auto_color && now-last_color>TIMER_COLOR) {
increment_color++;
}
if(increment_mode>0 || increment_color>0) {
if(increment_mode>0) {
last_mode = now;
}
if(increment_color>0) {
last_color = now;
}
current_mode = (current_mode + increment_mode) % (sizeof(modes_cycle)/sizeof(modes_cycle[0]));
increment_mode = 0;
current_color = (current_color + increment_color) % (sizeof(colors_cycle)/sizeof(colors_cycle[0]));
increment_color = 0;
ws2812fx.resetSegmentRuntimes();
ws2812fx.setBrightness(BRIGHTNESS);
for(seg=0; seg<LED_SEGMENTS; seg++) {
ws2812fx.setSegment(
seg,
seg*size, (seg+1)*size-1,
modes_cycle[current_mode], colors_cycle[current_color],
speed_cycle[current_mode], seg%2==1);
}
}
}