Last active
January 21, 2023 23:40
-
-
Save cmsj/ad9d7497d7092c1000ce742f605a34fd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Adafruit_NeoPixel.h> | |
#include <Adafruit_DotStar.h> | |
// led_effects | |
// by Chris Jones <cmsj@tenshu.net> | |
// Released under the MIT License. | |
// RGB LED built in to the Trinket M0 | |
Adafruit_DotStar dot = Adafruit_DotStar(1, INTERNAL_DS_DATA, INTERNAL_DS_CLK, DOTSTAR_BGR); | |
// NeoPixel Jewel | |
#define NEOPIXEL_PIN 4 | |
#define NEOPIXEL_CNT 7 | |
Adafruit_NeoPixel jewel = Adafruit_NeoPixel(NEOPIXEL_CNT, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800); | |
// Choose which effect to implement. Only one of these should be uncommented. | |
#define EFFECT_STATIC 1 | |
// #define EFFECT_RAINBOW 1 | |
// #define EFFECT_STATIC_SPIN 1 | |
// #define EFFECT_STATIC_PULSE 1 | |
// Globals useful to effects | |
int fps = 60; | |
uint32_t target_color = jewel.Color(255, 0, 0); | |
void *effect_data = NULL; | |
char debug[255]; | |
// Our entrypoint. Initialise serial and boot the LEDs. | |
void setup() { | |
// Pseudo-random seed - some effects need reasonable random numbers | |
// randomSeed(); | |
// Initialise our serial port | |
Serial.begin(9600); | |
// Don't uncomment this in a production build, it will probably cause startup to hang indefinitely. | |
// Uncomment it if you want to guarantee you get all messages from setup() over serial: | |
while(!Serial); | |
Serial.println("Booting LEDs..."); | |
dot.begin(); | |
dot.clear(); | |
dot.show(); | |
jewel.begin(); | |
jewel.clear(); | |
jewel.show(); | |
Serial.println("Done."); | |
Serial.flush(); | |
Serial.println("Calling effect_setup()..."); | |
effect_data = effect_setup(); | |
Serial.println("Done."); | |
Serial.flush(); | |
} | |
void loop() { | |
// Capture the time at the start of this iteration | |
unsigned long t_start = millis(); | |
// Clear the current LED state | |
dot.clear(); | |
jewel.clear(); | |
// Iterate the effect | |
effect_loop(); | |
// Commit the LED state | |
dot.show(); | |
jewel.show(); | |
// Calculate the length of this iteration | |
unsigned long t_stop = millis(); | |
unsigned long t_len = t_stop - t_start; | |
// If we took less than our target frame time, sleep for the remainder of the time. | |
// If we took more than our target frame time, log an error and don't sleep. | |
if (t_len > 1000/fps) { | |
sprintf(debug, "loop() frame time: %lu ms, max target is %d ms. Effect is too complex, or 50 day millis() rollover occurred", t_len, 1000/fps); | |
Serial.println(debug); | |
} else { | |
unsigned long t_frame_left = 1000/fps - t_len; | |
// sprintf(debug, "loop() frame time: %lu/%d ms, sleeping for %lu", t_len, 1000/fps, t_frame_left); | |
// Serial.println(debug); | |
delay(floor(t_frame_left)); | |
} | |
} | |
// Below here are the effects. | |
#ifdef EFFECT_STATIC | |
// EFFECT: Static | |
// Apply a plain static color to all LEDs | |
void* effect_setup() { | |
fps = 1; | |
return NULL; | |
} | |
void effect_loop() { | |
dot.fill(target_color, 0, 1); | |
jewel.fill(target_color, 0, NEOPIXEL_CNT); | |
} | |
#endif | |
#ifdef EFFECT_RAINBOW | |
// EFFECT: Rainbow cycle. | |
// Cycle through various colours on all LEDs simultaneously | |
struct rainbow_cycle_data { | |
long red; | |
long green; | |
long blue; | |
float r_angle; | |
float g_angle; | |
float b_angle; | |
int rand_min; | |
int rand_max; | |
}; | |
void* effect_setup() { | |
fps = 30; | |
rainbow_cycle_data *data = (rainbow_cycle_data *)malloc(sizeof(rainbow_cycle_data)); | |
data->red = random(0, 254); | |
data->green = random(0, 254); | |
data->blue = random(0, 254); | |
data->r_angle = 0; | |
data->g_angle = 90; | |
data->b_angle = 180; | |
data->rand_min = 1; | |
data->rand_max = 3; | |
return (void *)data; | |
} | |
void effect_loop() { | |
rainbow_cycle_data *data = (rainbow_cycle_data *)effect_data; | |
dot.fill(dot.Color(data->red, data->green, data->blue)); | |
jewel.fill(jewel.Color(data->red, data->green, data->blue)); | |
data->r_angle = data->r_angle + (float)random(data->rand_min, data->rand_max) / 10; | |
data->g_angle = data->g_angle + (float)random(data->rand_min, data->rand_max) / 10; | |
data->b_angle = data->b_angle + (float)random(data->rand_min, data->rand_max) / 10; | |
data->red = (sin(data->r_angle) + 1) * 128; | |
data->green = (sin(data->g_angle) + 1) * 128; | |
data->blue = (sin(data->b_angle) + 1) * 128; | |
} | |
#endif | |
#ifdef EFFECT_STATIC_SPIN | |
// EFFECT: Static Spin. | |
// Cycle through the LEDs individually, with whatever the target color is set to | |
struct static_spin_data { | |
int i; | |
}; | |
void* effect_setup() { | |
fps = 30; | |
static_spin_data *data = (static_spin_data *)malloc(sizeof(static_spin_data)); | |
data->i = 1; | |
return (void *)data; | |
} | |
void effect_loop() { | |
static_spin_data *data = (static_spin_data *)effect_data; | |
jewel.setPixelColor(data->i, target_color); | |
data->i++; | |
if (data->i > NEOPIXEL_CNT) { | |
data->i = 1; | |
} | |
} | |
#endif | |
#ifdef EFFECT_STATIC_PULSE | |
// EFFECT: Static Pulse. | |
// Pulse the brightness of the target color | |
struct static_pulse_data { | |
int brightness_delta; | |
}; | |
void* effect_setup() { | |
fps = 90; | |
static_pulse_data *data = (static_pulse_data *)malloc(sizeof(static_pulse_data)); | |
data->brightness_delta = 2; | |
jewel.fill(target_color); | |
jewel.setBrightness(254); | |
jewel.show(); | |
return (void *)data; | |
} | |
void effect_loop() { | |
static_pulse_data *data = (static_pulse_data *)effect_data; | |
uint8_t current_brightness = jewel.getBrightness(); | |
if (current_brightness <= 20 || current_brightness >= 254) { | |
data->brightness_delta = -(data->brightness_delta); | |
} | |
jewel.fill(target_color); | |
jewel.setBrightness(current_brightness + data->brightness_delta); | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment