holiday-lights/holiday-lights.ino

137 lines
3.1 KiB
Arduino
Raw Permalink Normal View History

2020-12-05 10:43:22 -07:00
#include <FastLED.h>
2020-12-15 21:52:15 -07:00
#include "Debounce.h"
#include "durations.h"
2020-11-28 20:23:35 -07:00
#include "morse.h"
#include "pulse.h"
2016-11-27 10:26:04 -07:00
2023-12-31 10:11:55 -07:00
// Which pins your LED strips are connected to
#define NUM_OUTPUTS 2
#define OUTPUT_PIN1 7
#define OUTPUT_PIN2 8
2016-11-27 18:06:09 -07:00
2020-11-28 20:23:35 -07:00
// Which pin has the momentary switch to toggle full white.
#define BUTTON_PIN 4
2016-12-11 21:02:37 -07:00
2023-12-31 10:11:55 -07:00
// How many LEDs you have per output. It's okay if this is too big.
2020-11-28 20:23:35 -07:00
#define LEDS_PER_GROUP 10
2023-12-31 10:11:55 -07:00
#define NUM_GROUPS 10
2020-12-05 10:43:22 -07:00
#define NUM_LEDS (LEDS_PER_GROUP * NUM_GROUPS)
2016-12-11 21:02:37 -07:00
2020-11-28 20:23:35 -07:00
// How many milliseconds between activity in one group
#define DELAY_MS 600
2016-12-11 21:02:37 -07:00
// Each group has this percentage chance of
#define GROUP_UPDATE_PROBABILITY 25
2020-11-28 20:23:35 -07:00
// What percentage chance a chosen light has of being on
#define ACTIVITY 40
// Which pixel to flash messages in morse code: -1 = disable
#define MORSE_PIXEL 8
#define MORSE_COLOR CRGB::Red
2020-11-28 20:23:35 -07:00
// How long a dit lasts
#define DIT_DURATION_MS 150
2020-11-28 20:23:35 -07:00
#define ARK "\x03\x04"
const char *message = (
"seasons greetings" ARK
"happy holiday" ARK
"merry xmas" ARK
"happy new year" ARK
"CQ CQ OF9X" ARK
);
2016-11-27 10:26:04 -07:00
2023-12-31 10:11:55 -07:00
CRGB leds[NUM_OUTPUTS][NUM_LEDS];
2020-12-15 21:52:15 -07:00
Debounce button(BUTTON_PIN, false, true);
2020-11-28 20:23:35 -07:00
2016-11-27 10:26:04 -07:00
void setup() {
2023-12-31 10:11:55 -07:00
FastLED.addLeds<WS2812, OUTPUT_PIN1, RGB>(leds[0], NUM_LEDS);
FastLED.addLeds<WS2812, OUTPUT_PIN2, RGB>(leds[1], NUM_LEDS);
FastLED.setTemperature(Tungsten40W);
2020-12-15 21:52:15 -07:00
FastLED.setBrightness(52);
2020-11-28 20:23:35 -07:00
pinMode(LED_BUILTIN, OUTPUT);
2016-11-27 10:26:04 -07:00
}
2020-12-15 21:52:15 -07:00
uint8_t RandomHue() {
switch (random(12)) {
case 0 ... 2:
return 52; // reddish yellow
case 3 ... 5:
return HUE_RED;
case 6 ... 8:
return 28; // reddish orange
case 9:
return HUE_BLUE;
case 10:
return HUE_GREEN;
case 11:
return 204; // reddish purple
}
}
2020-11-28 20:23:35 -07:00
2020-12-19 16:46:43 -07:00
bool strandUpdate(unsigned long now, bool white) {
2023-12-31 10:11:55 -07:00
static Pulse pulse = Pulse(DELAY_MS);
if (!pulse.Ticked(now)) {
2020-11-28 20:23:35 -07:00
return false;
2016-11-27 18:06:09 -07:00
}
2023-12-31 10:11:55 -07:00
for (int output = 0; output < NUM_OUTPUTS; output += 1) {
for (int group = 0; group < NUM_GROUPS; group += 1) {
int pos = (group * LEDS_PER_GROUP) + random(LEDS_PER_GROUP);
if (random(100) < GROUP_UPDATE_PROBABILITY) {
uint8_t hue = 0;
uint8_t saturation = white?0:255;
uint8_t value = 255;
if (random(100) < ACTIVITY) {
2020-12-15 21:52:15 -07:00
hue = RandomHue();
2023-12-31 10:11:55 -07:00
} else {
value = 0;
}
2023-12-31 10:11:55 -07:00
leds[output][pos] = CHSV(hue, saturation, value);
group = (group + 1) % NUM_GROUPS;
}
2016-11-27 10:26:04 -07:00
}
}
2020-11-28 20:23:35 -07:00
return true;
}
2020-12-19 16:46:43 -07:00
bool morseUpdate(unsigned long now) {
2020-11-28 20:23:35 -07:00
static MorseEncoder enc;
static Pulse pulse = Pulse(DIT_DURATION_MS);
2023-12-31 10:11:55 -07:00
if (!pulse.Ticked(now)) {
return false;
2020-11-28 20:23:35 -07:00
}
2020-12-19 16:46:43 -07:00
2023-12-31 10:11:55 -07:00
if (!enc.Tick()) {
enc.SetText(message);
2020-11-28 20:23:35 -07:00
}
2023-12-31 10:11:55 -07:00
leds[0][MORSE_PIXEL] = enc.Transmitting ? MORSE_COLOR : CRGB::Black;
return true;
2016-11-27 18:06:09 -07:00
}
void loop() {
2020-12-15 21:52:15 -07:00
bool white = false;
2020-11-28 20:23:35 -07:00
bool update = false;
2020-12-19 16:46:43 -07:00
unsigned long now = millis(); // Everybody uses the same time so we don't do spurious updates 5ms apart
2020-11-28 20:23:35 -07:00
2020-12-15 21:52:15 -07:00
button.read();
white = (button.count() % 2 == 1);
2020-11-28 20:23:35 -07:00
2023-12-31 10:11:55 -07:00
update |= strandUpdate(now, white);
//update |= morseUpdate(now);
2020-11-28 20:23:35 -07:00
if (update) {
2020-12-05 10:43:22 -07:00
FastLED.show();
2016-11-27 18:06:09 -07:00
}
2016-12-11 21:02:37 -07:00
2020-11-28 20:23:35 -07:00
// blink the heart for a little bit
if (millis() < 30 * 1000) {
bool on = (millis() % 1000) < 500;
digitalWrite(LED_BUILTIN, on);
}
2016-11-27 10:26:04 -07:00
}