Skip to content

Instantly share code, notes, and snippets.

@zfogg
Created January 4, 2023 20:45
Show Gist options
  • Save zfogg/e4ee04c8366d6def91f6887aa77b3fc9 to your computer and use it in GitHub Desktop.
Save zfogg/e4ee04c8366d6def91f6887aa77b3fc9 to your computer and use it in GitHub Desktop.
Ellydeez - Remote Control LED Ring FINAL
#include <Adafruit_NeoPixel.h>
#include <IRremote.hpp>
#include <FastLED.h>
#define LED_PIN 7
#define IRRECV_PIN 8
#define FPS_MILLIS 17
#define NUM_LEDS 12
unsigned int brightness = 32;
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
// 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) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
// Fill the strip with a solid color.
void colorFill(uint32_t c) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
}
strip.show();
}
// Fill the LEDs with a single color, one by one, over time.
void colorWipe(uint32_t c, unsigned long start, unsigned long time, unsigned long end) {
float p = 1 - (float)(end-time) / (end-start);
for(uint16_t i= 0; i < strip.numPixels() * p; i++) {
strip.setPixelColor(i, c);
}
strip.show();
}
// Shows the rainbow animated across all pixels over time, zooming in and out to
// various sections of the rainbow rhythmically.
void rainbow(unsigned long time, unsigned long pixelStart) {
for(uint16_t j = pixelStart; j < strip.numPixels() + pixelStart; j++) {
uint16_t i = j % strip.numPixels();
strip.setPixelColor(i, Wheel((int)(i*10*sin(0.001*time)+((int)(time*0.1)%255)) & 255));
}
strip.show();
}
// Slightly different, this makes the rainbow equally distributed across all pixels
// and spins it around five times over the animation duration.
void rainbowCycle(unsigned long start, unsigned long time, unsigned long end) {
float p = 1 - (float)(end-time) / (end-start);
int j = p * (256*5);
for(uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
}
void setup() {
// Open a serial connection for printing logs.
Serial.begin(9600);
// Turn on the LEDs.
strip.begin();
strip.setBrightness(brightness);
strip.show(); // Initialize all pixels to 'off'
// Turn on the infrared receiver.
IrReceiver.begin(IRRECV_PIN, ENABLE_LED_FEEDBACK);
}
unsigned long startTime;
unsigned long endTime;
unsigned int activeAnimation = 0;
const unsigned long animationTime = 2700;
unsigned long pixelStart = 0;
void loop() {
unsigned long ms = millis();
// If some infrared data was received and can be decoded...
if (IrReceiver.decode()) {
if (IrReceiver.decodedIRData.decodedRawData != 0) {
// Just print it out for debugging.
Serial.println(IrReceiver.decodedIRData.decodedRawData);
}
bool shouldAnim = false;
if (IrReceiver.decodedIRData.decodedRawData == 4077715200) { // Button 1
activeAnimation = 1;
shouldAnim = true;
} else if (IrReceiver.decodedIRData.decodedRawData == 3877175040) { // Button 2
activeAnimation = 2;
shouldAnim = true;
} else if (IrReceiver.decodedIRData.decodedRawData == 2707357440) { // Button 3
activeAnimation = 3;
shouldAnim = true;
} else if (IrReceiver.decodedIRData.decodedRawData == 4144561920) { // Button 4
activeAnimation = 4;
shouldAnim = true;
} else if (IrReceiver.decodedIRData.decodedRawData == 3810328320) { // Button 5
activeAnimation = 5;
shouldAnim = true;
} else if (IrReceiver.decodedIRData.decodedRawData == 4127850240) { // Button UP
// Turn the brightness up.
brightness = min(brightness+64, 255);
strip.setBrightness(brightness);
} else if (IrReceiver.decodedIRData.decodedRawData == 4161273600) { // Button DOWN
// Turn the brightness down.
brightness = max(brightness-min(64, brightness), 0);
strip.setBrightness(brightness);
}
// If an animation button was pressed
if (shouldAnim) {
colorFill(strip.Color(0, 0, 0));
startTime = ms+FPS_MILLIS;
endTime = startTime+animationTime+FPS_MILLIS;
}
// Continue receiving infrared data...
IrReceiver.resume();
}
// Cycle some variables for animations every so often.
EVERY_N_SECONDS(1) {
pixelStart += 1 % strip.numPixels();
}
// Play the active animation.
EVERY_N_MILLISECONDS(30) {
switch (activeAnimation) {
case 1:
colorWipe(strip.Color(255, 0, 0), startTime, ms, endTime);
break;
case 2:
colorWipe(strip.Color(0, 255, 0), startTime, ms, endTime);
break;
case 3:
colorWipe(strip.Color(0, 0, 255), startTime, ms, endTime);
break;
case 4:
colorWipe(strip.Color(255, 192, 203), startTime, ms, endTime);
break;
case 5:
rainbowCycle(startTime, ms, endTime);
break;
default:
rainbow(ms, pixelStart);
break;
}
}
// Reset the active animation to 0 so the default animation plays.
if (activeAnimation != 0 && ms >= endTime) {
Serial.println("Ending an animation.");
activeAnimation = 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment