Difference between revisions of "NeoPixel Workshop Instructions"
Line 31: | Line 31: | ||
See this page for the uberguide of everything neopixel https://learn.adafruit.com/adafruit-neopixel-uberguide/the-magic-of-neopixels | See this page for the uberguide of everything neopixel https://learn.adafruit.com/adafruit-neopixel-uberguide/the-magic-of-neopixels | ||
+ | |||
+ | And here is another guide https://www.tweaking4all.com/hardware/arduino/arduino-ws2812-led/ | ||
Hook up your LED strand like this picture: | Hook up your LED strand like this picture: |
Revision as of 10:33, 12 November 2017
This is the instruction page for the NeoPixel Workshop ran by Andy Miller on 11/11/17
Contents
Software to install
You will need to install the following programs and drivers
Download and install the Arduino IDE V 1.8.5 (or newer).
Do not download/install the web IDE!
https://www.arduino.cc/en/Main/Software
There are some step by step instructions here: https://www.arduino.cc/en/Guide/HomePage
Download and install the CH340 USB drivers for the Arduino clones:
https://sparks.gogo.co.nz/ch340.html
Note: The CH340 chip is a USB to serial chip used frequently on Arduino clones. Official Arduinos use the FTDI chip. Those drivers are included in the Arduino software install.
Download the NeoPixel and Fast LED libraries using the Arduino IDE:
Go to Sketch->Include Library->Manage Library in the Arduino IDE menu
Search for Adafruit NeoPixel library, select it and then click the install button
Search for FASTLed library, select and install
Hardware setup
See this page for the uberguide of everything neopixel https://learn.adafruit.com/adafruit-neopixel-uberguide/the-magic-of-neopixels
And here is another guide https://www.tweaking4all.com/hardware/arduino/arduino-ws2812-led/
Hook up your LED strand like this picture:
Be sure to hook up the dataline to pin 6. We are not using the 470 ohm resistor. Just use a wire!
Code
Open the Arduino IDE and copy and paste this test code! Have fun!
The code below is also found in your Arduino IDE under File->Examples->FastLED and File->Examples->Adafruit Neopixel
Since your strand is connected to pin 6, you may have to change the code to relfect that.
Examples are a good place to start programming Arduino sketches!
Color Pallet
#include <FastLED.h> #define LED_PIN 6 #define NUM_LEDS 60 #define BRIGHTNESS 96 #define LED_TYPE WS2811 #define COLOR_ORDER GRB CRGB leds[NUM_LEDS]; #define UPDATES_PER_SECOND 100 // FastLED provides a few pre-configured color palettes, and makes it // extremely easy to make up your own color schemes with palettes. // // Some notes on the more abstract 'theory and practice' of // FastLED compact palettes are at the bottom of this file. CRGBPalette16 currentPalette; TBlendType currentBlending; extern CRGBPalette16 myRedWhiteBluePalette; extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM; void setup() { delay( 3000 ); // power-up safety delay FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip ); FastLED.setBrightness( BRIGHTNESS ); currentPalette = RainbowColors_p; currentBlending = LINEARBLEND; } void loop() { ChangePalettePeriodically(); static uint8_t startIndex = 0; startIndex = startIndex + 1; /* motion speed */ FillLEDsFromPaletteColors( startIndex); FastLED.show(); FastLED.delay(1000 / UPDATES_PER_SECOND); } void FillLEDsFromPaletteColors( uint8_t colorIndex) { uint8_t brightness = 255; for( int i = 0; i < NUM_LEDS; i++) { leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending); colorIndex += 3; } } void ChangePalettePeriodically() { uint8_t secondHand = (millis() / 1000) % 60; static uint8_t lastSecond = 99; if( lastSecond != secondHand) { lastSecond = secondHand; if( secondHand == 0) { currentPalette = RainbowColors_p; currentBlending = LINEARBLEND; } if( secondHand == 10) { currentPalette = RainbowStripeColors_p; currentBlending = NOBLEND; } if( secondHand == 15) { currentPalette = RainbowStripeColors_p; currentBlending = LINEARBLEND; } if( secondHand == 20) { SetupPurpleAndGreenPalette(); currentBlending = LINEARBLEND; } if( secondHand == 25) { SetupTotallyRandomPalette(); currentBlending = LINEARBLEND; } if( secondHand == 30) { SetupBlackAndWhiteStripedPalette(); currentBlending = NOBLEND; } if( secondHand == 35) { SetupBlackAndWhiteStripedPalette(); currentBlending = LINEARBLEND; } if( secondHand == 40) { currentPalette = CloudColors_p; currentBlending = LINEARBLEND; } if( secondHand == 45) { currentPalette = PartyColors_p; currentBlending = LINEARBLEND; } if( secondHand == 50) { currentPalette = myRedWhiteBluePalette_p; currentBlending = NOBLEND; } if( secondHand == 55) { currentPalette = myRedWhiteBluePalette_p; currentBlending = LINEARBLEND; } } } // This function fills the palette with totally random colors. void SetupTotallyRandomPalette() { for( int i = 0; i < 16; i++) { currentPalette[i] = CHSV( random8(), 255, random8()); } } // This function sets up a palette of black and white stripes, // using code. Since the palette is effectively an array of // sixteen CRGB colors, the various fill_* functions can be used // to set them up. void SetupBlackAndWhiteStripedPalette() { // 'black out' all 16 palette entries... fill_solid( currentPalette, 16, CRGB::Black); // and set every fourth one to white. currentPalette[0] = CRGB::White; currentPalette[4] = CRGB::White; currentPalette[8] = CRGB::White; currentPalette[12] = CRGB::White; } // This function sets up a palette of purple and green stripes. void SetupPurpleAndGreenPalette() { CRGB purple = CHSV( HUE_PURPLE, 255, 255); CRGB green = CHSV( HUE_GREEN, 255, 255); CRGB black = CRGB::Black; currentPalette = CRGBPalette16( green, green, black, black, purple, purple, black, black, green, green, black, black, purple, purple, black, black ); } // This example shows how to set up a static color palette // which is stored in PROGMEM (flash), which is almost always more // plentiful than RAM. A static PROGMEM palette like this // takes up 64 bytes of flash. const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM = { CRGB::Red, CRGB::Gray, // 'white' is too bright compared to red and blue CRGB::Blue, CRGB::Black, CRGB::Red, CRGB::Gray, CRGB::Blue, CRGB::Black, CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray, CRGB::Blue, CRGB::Blue, CRGB::Black, CRGB::Black };
Demo Reel.ino
#include "FastLED.h" #if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000) #warning "Requires FastLED 3.1 or later; check github for latest code." #endif #define DATA_PIN 6 #define LED_TYPE WS2811 #define COLOR_ORDER GRB #define NUM_LEDS 60 CRGB leds[NUM_LEDS]; #define BRIGHTNESS 96 #define FRAMES_PER_SECOND 80 void setup() { delay(3000); // 3 second delay for recovery // tell FastLED about the LED strip configuration FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); // set master brightness control FastLED.setBrightness(BRIGHTNESS); } // List of patterns to cycle through. Each is defined as a separate function below. typedef void (*SimplePatternList[])(); SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm }; uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current uint8_t gHue = 0; // rotating "base color" used by many of the patterns void loop() { // Call the current pattern function once, updating the 'leds' array gPatterns[gCurrentPatternNumber](); // send the 'leds' array out to the actual LED strip FastLED.show(); // insert a delay to keep the framerate modest FastLED.delay(1000/FRAMES_PER_SECOND); // do some periodic updates EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically } #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) void nextPattern() { // add one to the current pattern number, and wrap around at the end gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns); } void rainbow() { // FastLED's built-in rainbow generator fill_rainbow( leds, NUM_LEDS, gHue, 7); } void rainbowWithGlitter() { // built-in FastLED rainbow, plus some random sparkly glitter rainbow(); addGlitter(80); } void addGlitter( fract8 chanceOfGlitter) { if( random8() < chanceOfGlitter) { leds[ random16(NUM_LEDS) ] += CRGB::White; } } void confetti() { // random colored speckles that blink in and fade smoothly fadeToBlackBy( leds, NUM_LEDS, 10); int pos = random16(NUM_LEDS); leds[pos] += CHSV( gHue + random8(64), 200, 255); } void sinelon() { // a colored dot sweeping back and forth, with fading trails fadeToBlackBy( leds, NUM_LEDS, 20); int pos = beatsin16( 13, 0, NUM_LEDS-1 ); leds[pos] += CHSV( gHue, 255, 192); } void bpm() { // colored stripes pulsing at a defined Beats-Per-Minute (BPM) uint8_t BeatsPerMinute = 62; CRGBPalette16 palette = PartyColors_p; uint8_t beat = beatsin8( BeatsPerMinute, 64, 255); for( int i = 0; i < NUM_LEDS; i++) { //9948 leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10)); } } void juggle() { // eight colored dots, weaving in and out of sync with each other fadeToBlackBy( leds, NUM_LEDS, 20); byte dothue = 0; for( int i = 0; i < 8; i++) { leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255); dothue += 32; } }
Fire Nash
#include <Adafruit_NeoPixel.h> #define PIN 6 #define NUM_LEDS 144 // 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, PIN, NEO_GRB + NEO_KHZ800); void setup() { strip.begin(); strip.show(); // Initialize all pixels to 'off' } // *** REPLACE FROM HERE *** void loop() { Fire(55,120,15); } void Fire(int Cooling, int Sparking, int SpeedDelay) { static byte heat[NUM_LEDS]; int cooldown; // Step 1. Cool down every cell a little for( int i = 0; i < NUM_LEDS; i++) { cooldown = random(0, ((Cooling * 10) / NUM_LEDS) + 2); if(cooldown>heat[i]) { heat[i]=0; } else { heat[i]=heat[i]-cooldown; } } // Step 2. Heat from each cell drifts 'up' and diffuses a little for( int k= NUM_LEDS - 1; k >= 2; k--) { heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3; } // Step 3. Randomly ignite new 'sparks' near the bottom if( random(255) < Sparking ) { int y = random(7); heat[y] = heat[y] + random(160,255); //heat[y] = random(160,255); } // Step 4. Convert heat to LED colors for( int j = 0; j < NUM_LEDS; j++) { setPixelHeatColor(j, heat[j] ); } showStrip(); delay(SpeedDelay); } void setPixelHeatColor (int Pixel, byte temperature) { // Scale 'heat' down from 0-255 to 0-191 byte t192 = round((temperature/255.0)*191); // calculate ramp up from byte heatramp = t192 & 0x3F; // 0..63 heatramp <<= 2; // scale up to 0..252 // figure out which third of the spectrum we're in: if( t192 > 0x80) { // hottest setPixel(Pixel, 255, 255, heatramp); } else if( t192 > 0x40 ) { // middle setPixel(Pixel, 255, heatramp, 0); } else { // coolest setPixel(Pixel, heatramp, 0, 0); } } // *** REPLACE TO HERE *** void showStrip() { #ifdef ADAFRUIT_NEOPIXEL_H // NeoPixel strip.show(); #endif #ifndef ADAFRUIT_NEOPIXEL_H // FastLED FastLED.show(); #endif } void setPixel(int Pixel, byte red, byte green, byte blue) { #ifdef ADAFRUIT_NEOPIXEL_H // NeoPixel strip.setPixelColor(Pixel, strip.Color(red, green, blue)); #endif #ifndef ADAFRUIT_NEOPIXEL_H // FastLED leds[Pixel].r = red; leds[Pixel].g = green; leds[Pixel].b = blue; #endif } void setAll(byte red, byte green, byte blue) { for(int i = 0; i < NUM_LEDS; i++ ) { setPixel(i, red, green, blue); } showStrip(); }
Neo Test Code
#include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> #endif #define PIN 6 #define NUM_LEDS 144 #define BRIGHTNESS 50 Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRBW + NEO_KHZ800); int gamma[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68, 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, 90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114, 115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142, 144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175, 177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213, 215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 }; void setup() { Serial.begin(115200); // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket #if defined (__AVR_ATtiny85__) if (F_CPU == 16000000) clock_prescale_set(clock_div_1); #endif // End of trinket special code strip.setBrightness(BRIGHTNESS); strip.begin(); strip.show(); // Initialize all pixels to 'off' } void loop() { // Some example procedures showing how to display to the pixels: colorWipe(strip.Color(255, 0, 0), 50); // Red colorWipe(strip.Color(0, 0, 255), 50); // Blue colorWipe(strip.Color(0, 0, 0, 255), 50); // White whiteOverRainbow(20,75,5); pulseWhite(5); // fullWhite(); // delay(2000); rainbowFade2White(3,3,1); } // Fill the dots one after the other with a color void colorWipe(uint32_t c, uint8_t wait) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, c); strip.show(); delay(wait); } } void pulseWhite(uint8_t wait) { for(int j = 0; j < 256 ; j++){ for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, strip.Color(0,0,0, gamma[j] ) ); } delay(wait); strip.show(); } for(int j = 255; j >= 0 ; j--){ for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, strip.Color(0,0,0, gamma[j] ) ); } delay(wait); strip.show(); } } void rainbowFade2White(uint8_t wait, int rainbowLoops, int whiteLoops) { float fadeMax = 100.0; int fadeVal = 0; uint32_t wheelVal; int redVal, greenVal, blueVal; for(int k = 0 ; k < rainbowLoops ; k ++){ for(int j=0; j<256; j++) { // 5 cycles of all colors on wheel for(int i=0; i< strip.numPixels(); i++) { wheelVal = Wheel(((i * 256 / strip.numPixels()) + j) & 255); redVal = red(wheelVal) * float(fadeVal/fadeMax); greenVal = green(wheelVal) * float(fadeVal/fadeMax); blueVal = blue(wheelVal) * float(fadeVal/fadeMax); strip.setPixelColor( i, strip.Color( redVal, greenVal, blueVal ) ); } //First loop, fade in! if(k == 0 && fadeVal < fadeMax-1) { fadeVal++; } //Last loop, fade out! else if(k == rainbowLoops - 1 && j > 255 - fadeMax ){ fadeVal--; } strip.show(); delay(wait); } } delay(500); for(int k = 0 ; k < whiteLoops ; k ++){ for(int j = 0; j < 256 ; j++){ for(uint16_t i=0; i < strip.numPixels(); i++) { strip.setPixelColor(i, strip.Color(0,0,0, gamma[j] ) ); } strip.show(); } delay(2000); for(int j = 255; j >= 0 ; j--){ for(uint16_t i=0; i < strip.numPixels(); i++) { strip.setPixelColor(i, strip.Color(0,0,0, gamma[j] ) ); } strip.show(); } } delay(500); } void whiteOverRainbow(uint8_t wait, uint8_t whiteSpeed, uint8_t whiteLength ) { if(whiteLength >= strip.numPixels()) whiteLength = strip.numPixels() - 1; int head = whiteLength - 1; int tail = 0; int loops = 3; int loopNum = 0; static unsigned long lastTime = 0; while(true){ for(int j=0; j<256; j++) { for(uint16_t i=0; i<strip.numPixels(); i++) { if((i >= tail && i <= head) || (tail > head && i >= tail) || (tail > head && i <= head) ){ strip.setPixelColor(i, strip.Color(0,0,0, 255 ) ); } else{ strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255)); } } if(millis() - lastTime > whiteSpeed) { head++; tail++; if(head == strip.numPixels()){ loopNum++; } lastTime = millis(); } if(loopNum == loops) return; head%=strip.numPixels(); tail%=strip.numPixels(); strip.show(); delay(wait); } } } void fullWhite() { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, strip.Color(0,0,0, 255 ) ); } strip.show(); } // Slightly different, this makes the rainbow equally distributed throughout void rainbowCycle(uint8_t wait) { uint16_t i, j; for(j=0; j<256 * 5; j++) { // 5 cycles of all colors on wheel for(i=0; i< strip.numPixels(); i++) { strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255)); } strip.show(); delay(wait); } } void rainbow(uint8_t wait) { uint16_t i, j; for(j=0; j<256; j++) { for(i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, Wheel((i+j) & 255)); } strip.show(); delay(wait); } } // 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,0); } if(WheelPos < 170) { WheelPos -= 85; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3,0); } WheelPos -= 170; return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0,0); } uint8_t red(uint32_t c) { return (c >> 8); } uint8_t green(uint32_t c) { return (c >> 16); } uint8_t blue(uint32_t c) { return (c); }
RWB 1St Code
#include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> #endif #define PIN 6 Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800); void setup() { // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket #if defined (__AVR_ATtiny85__) if (F_CPU == 16000000) clock_prescale_set(clock_div_1); #endif // End of trinket special code strip.begin(); strip.show(); // Initialize all pixels to 'off' } void loop() { // Some example procedures showing how to display to the pixels: colorWipe(strip.Color(255, 0, 0), 10); // Red colorWipe(strip.Color(127, 127, 127), 10); // White colorWipe(strip.Color(0, 0, 255), 10); // Blue colorWipe(strip.Color(255, 0, 0), 10); // Red colorWipe(strip.Color(127, 127, 127), 10); // White colorWipe(strip.Color(0, 0, 255), 10); // Blue colorWipe(strip.Color(255, 0, 0), 10); // Red colorWipe(strip.Color(127, 127, 127), 10); // White colorWipe(strip.Color(0, 0, 255), 10); // Blue colorWipe(strip.Color(255, 0, 0), 10); // Red colorWipe(strip.Color(127, 127, 127), 10); // White colorWipe(strip.Color(0, 0, 255), 10); // Blue // Send a theater pixel chase in... theaterChase(strip.Color(127, 0, 0), 10); // Red theaterChase(strip.Color(127, 127, 127), 10); // White theaterChase(strip.Color(0, 0, 127), 10); // Blue theaterChase(strip.Color(127, 0, 0), 10); // Red theaterChase(strip.Color(127, 127, 127), 10); // White theaterChase(strip.Color(0, 0, 127), 10); // Blue theaterChase(strip.Color(127, 0, 0), 10); // Red theaterChase(strip.Color(127, 127, 127), 10); // White theaterChase(strip.Color(0, 0, 127), 10); // Blue rainbow(10); rainbowCycle(10); theaterChaseRainbow(10); } // Fill the dots one after the other with a color void colorWipe(uint32_t c, uint8_t wait) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, c); strip.show(); delay(wait); } } void rainbow(uint8_t wait) { uint16_t i, j; for(j=0; j<128; j++) { for(i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, Wheel((i+j) & 127)); } strip.show(); delay(wait); } } // Slightly different, this makes the rainbow equally distributed throughout void rainbowCycle(uint8_t wait) { uint16_t i, j; for(j=0; j<127*5; j++) { // 5 cycles of all colors on wheel for(i=0; i< strip.numPixels(); i++) { strip.setPixelColor(i, Wheel(((i * 128 / strip.numPixels()) + j) & 127)); } strip.show(); delay(wait); } } //Theatre-style crawling lights. void theaterChase(uint32_t c, uint8_t wait) { for (int j=0; j<10; j++) { //do 10 cycles of chasing for (int q=0; q < 3; q++) { for (uint16_t i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, c); //turn every third pixel on } strip.show(); delay(wait); for (uint16_t i=0; i < strip.numPixels(); i=i+5) { strip.setPixelColor(i+q, 0); //turn every third pixel off } } } } //Theatre-style crawling lights with rainbow effect void theaterChaseRainbow(uint8_t wait) { for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel for (int q=0; q < 3; q++) { for (uint16_t i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on } strip.show(); delay(wait); for (uint16_t i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, 0); //turn every third pixel off } } } } // 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 = 150 - WheelPos; if(WheelPos < 100) { return strip.Color(150 - WheelPos * 3, 0, WheelPos * 3); } if(WheelPos < 255) { WheelPos -= 100; return strip.Color(100, WheelPos * 3, 125 - WheelPos * 3); } WheelPos -= 190; return strip.Color(WheelPos * 2, 100 - WheelPos * 4, 255); }
Show Me the Blinkey
#include "FastLED.h" #define LED_COUNT 60 #define LED_PIN 6 struct CRGB leds[LED_COUNT]; uint8_t hue = 25; byte idex = 200; byte meteorLength = 10; void setup() { // sanity check delay - allows reprogramming if accidently blowing power w/leds delay(1000); LEDS.addLeds<WS2812, LED_PIN, GRB>(leds, LED_COUNT); LEDS.setBrightness(200); } void loop(){ meteorShower(); } void meteorShower(){ // slide all the pixels down one in the array memmove8( &leds[1], &leds[0], (LED_COUNT - 1) * 3 ); // increment the meteor display frame idex++; // make sure we don't drift into space if ( idex > meteorLength ) { idex = 0; // cycle through hues in each successive meteor tail hue += 32; } // this switch controls the actual meteor animation, i.e., what gets placed in the // first position and then subsequently gets moved down the strip by the memmove above switch ( idex ) { case 0: leds[0] = CRGB(200,200,200); break; case 1: leds[0] = CHSV((hue - 20), 255, 210); break; case 2: leds[0] = CHSV((hue - 22), 255, 180); break; case 3: leds[0] = CHSV((hue - 23), 255, 150); break; case 4: leds[0] = CHSV((hue - 24), 255, 110); break; case 5: leds[0] = CHSV((hue - 25), 255, 90); break; case 6: leds[0] = CHSV((hue - 26), 160, 60); break; case 7: leds[0] = CHSV((hue - 27), 140, 40); break; case 8: leds[0] = CHSV((hue - 28), 120, 20); break; case 9: leds[0] = CHSV((hue - 29), 100, 20); break; default: leds[0] = CRGB::Black; } // show the blinky FastLED.show(); // control the animation speed/frame rate delay(10); }
Strobe
#include <Adafruit_NeoPixel.h> #define PIN 6 #define NUM_LEDS 60 // 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, PIN, NEO_GRB + NEO_KHZ800); void setup() { strip.begin(); strip.show(); // Initialize all pixels to 'off' } // *** REPLACE FROM HERE *** void loop() { // Slower: // Strobe(0xff, 0x77, 0x00, 10, 100, 1000); // Fast: Strobe(0xff, 0xff, 0xff, 10, 50, 1000); } void Strobe(byte red, byte green, byte blue, int StrobeCount, int FlashDelay, int EndPause){ for(int j = 0; j < StrobeCount; j++) { setAll(red,green,blue); showStrip(); delay(FlashDelay); setAll(0,0,0); showStrip(); delay(FlashDelay); } delay(EndPause); } // *** REPLACE TO HERE *** void showStrip() { #ifdef ADAFRUIT_NEOPIXEL_H // NeoPixel strip.show(); #endif #ifndef ADAFRUIT_NEOPIXEL_H // FastLED FastLED.show(); #endif } void setPixel(int Pixel, byte red, byte green, byte blue) { #ifdef ADAFRUIT_NEOPIXEL_H // NeoPixel strip.setPixelColor(Pixel, strip.Color(red, green, blue)); #endif #ifndef ADAFRUIT_NEOPIXEL_H // FastLED leds[Pixel].r = red; leds[Pixel].g = green; leds[Pixel].b = blue; #endif } void setAll(byte red, byte green, byte blue) { for(int i = 0; i < NUM_LEDS; i++ ) { setPixel(i, red, green, blue); } showStrip(); }
Twinkle
#include "FastLED.h" #if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000) #warning "Requires FastLED 3.1 or later; check github for latest code." #endif #define NUM_LEDS 100 #define LED_TYPE WS2811 #define COLOR_ORDER GRB #define DATA_PIN 6 #define VOLTS 12 #define MAX_MA 4000 // TwinkleFOX: Twinkling 'holiday' lights that fade in and out. // Colors are chosen from a palette; a few palettes are provided. // // This December 2015 implementation improves on the December 2014 version // in several ways: // - smoother fading, compatible with any colors and any palettes // - easier control of twinkle speed and twinkle density // - supports an optional 'background color' // - takes even less RAM: zero RAM overhead per pixel // - illustrates a couple of interesting techniques (uh oh...) // // The idea behind this (new) implementation is that there's one // basic, repeating pattern that each pixel follows like a waveform: // The brightness rises from 0..255 and then falls back down to 0. // The brightness at any given point in time can be determined as // as a function of time, for example: // brightness = sine( time ); // a sine wave of brightness over time // // So the way this implementation works is that every pixel follows // the exact same wave function over time. In this particular case, // I chose a sawtooth triangle wave (triwave8) rather than a sine wave, // but the idea is the same: brightness = triwave8( time ). // // Of course, if all the pixels used the exact same wave form, and // if they all used the exact same 'clock' for their 'time base', all // the pixels would brighten and dim at once -- which does not look // like twinkling at all. // // So to achieve random-looking twinkling, each pixel is given a // slightly different 'clock' signal. Some of the clocks run faster, // some run slower, and each 'clock' also has a random offset from zero. // The net result is that the 'clocks' for all the pixels are always out // of sync from each other, producing a nice random distribution // of twinkles. // // The 'clock speed adjustment' and 'time offset' for each pixel // are generated randomly. One (normal) approach to implementing that // would be to randomly generate the clock parameters for each pixel // at startup, and store them in some arrays. However, that consumes // a great deal of precious RAM, and it turns out to be totally // unnessary! If the random number generate is 'seeded' with the // same starting value every time, it will generate the same sequence // of values every time. So the clock adjustment parameters for each // pixel are 'stored' in a pseudo-random number generator! The PRNG // is reset, and then the first numbers out of it are the clock // adjustment parameters for the first pixel, the second numbers out // of it are the parameters for the second pixel, and so on. // In this way, we can 'store' a stable sequence of thousands of // random clock adjustment parameters in literally two bytes of RAM. // // There's a little bit of fixed-point math involved in applying the // clock speed adjustments, which are expressed in eighths. Each pixel's // clock speed ranges from 8/8ths of the system clock (i.e. 1x) to // 23/8ths of the system clock (i.e. nearly 3x). // // On a basic Arduino Uno or Leonardo, this code can twinkle 300+ pixels // smoothly at over 50 updates per seond. // // -Mark Kriegsman, December 2015 CRGBArray<NUM_LEDS> leds; // Overall twinkle speed. // 0 (VERY slow) to 8 (VERY fast). // 4, 5, and 6 are recommended, default is 4. #define TWINKLE_SPEED 4 // Overall twinkle density. // 0 (NONE lit) to 8 (ALL lit at once). // Default is 5. #define TWINKLE_DENSITY 5 // How often to change color palettes. #define SECONDS_PER_PALETTE 30 // Also: toward the bottom of the file is an array // called "ActivePaletteList" which controls which color // palettes are used; you can add or remove color palettes // from there freely. // Background color for 'unlit' pixels // Can be set to CRGB::Black if desired. CRGB gBackgroundColor = CRGB::Black; // Example of dim incandescent fairy light background color // CRGB gBackgroundColor = CRGB(CRGB::FairyLight).nscale8_video(16); // If AUTO_SELECT_BACKGROUND_COLOR is set to 1, // then for any palette where the first two entries // are the same, a dimmed version of that color will // automatically be used as the background color. #define AUTO_SELECT_BACKGROUND_COLOR 0 // If COOL_LIKE_INCANDESCENT is set to 1, colors will // fade out slighted 'reddened', similar to how // incandescent bulbs change color as they get dim down. #define COOL_LIKE_INCANDESCENT 1 CRGBPalette16 gCurrentPalette; CRGBPalette16 gTargetPalette; void setup() { delay( 3000 ); //safety startup delay FastLED.setMaxPowerInVoltsAndMilliamps( VOLTS, MAX_MA); FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS) .setCorrection(TypicalLEDStrip); chooseNextColorPalette(gTargetPalette); } void loop() { EVERY_N_SECONDS( SECONDS_PER_PALETTE ) { chooseNextColorPalette( gTargetPalette ); } EVERY_N_MILLISECONDS( 10 ) { nblendPaletteTowardPalette( gCurrentPalette, gTargetPalette, 12); } drawTwinkles( leds); FastLED.show(); } // This function loops over each pixel, calculates the // adjusted 'clock' that this pixel should use, and calls // "CalculateOneTwinkle" on each pixel. It then displays // either the twinkle color of the background color, // whichever is brighter. void drawTwinkles( CRGBSet& L) { // "PRNG16" is the pseudorandom number generator // It MUST be reset to the same starting value each time // this function is called, so that the sequence of 'random' // numbers that it generates is (paradoxically) stable. uint16_t PRNG16 = 11337; uint32_t clock32 = millis(); // Set up the background color, "bg". // if AUTO_SELECT_BACKGROUND_COLOR == 1, and the first two colors of // the current palette are identical, then a deeply faded version of // that color is used for the background color CRGB bg; if( (AUTO_SELECT_BACKGROUND_COLOR == 1) && (gCurrentPalette[0] == gCurrentPalette[1] )) { bg = gCurrentPalette[0]; uint8_t bglight = bg.getAverageLight(); if( bglight > 64) { bg.nscale8_video( 16); // very bright, so scale to 1/16th } else if( bglight > 16) { bg.nscale8_video( 64); // not that bright, so scale to 1/4th } else { bg.nscale8_video( 86); // dim, scale to 1/3rd. } } else { bg = gBackgroundColor; // just use the explicitly defined background color } uint8_t backgroundBrightness = bg.getAverageLight(); for( CRGB& pixel: L) { PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number uint16_t myclockoffset16= PRNG16; // use that number as clock offset PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number // use that number as clock speed adjustment factor (in 8ths, from 8/8ths to 23/8ths) uint8_t myspeedmultiplierQ5_3 = ((((PRNG16 & 0xFF)>>4) + (PRNG16 & 0x0F)) & 0x0F) + 0x08; uint32_t myclock30 = (uint32_t)((clock32 * myspeedmultiplierQ5_3) >> 3) + myclockoffset16; uint8_t myunique8 = PRNG16 >> 8; // get 'salt' value for this pixel // We now have the adjusted 'clock' for this pixel, now we call // the function that computes what color the pixel should be based // on the "brightness = f( time )" idea. CRGB c = computeOneTwinkle( myclock30, myunique8); uint8_t cbright = c.getAverageLight(); int16_t deltabright = cbright - backgroundBrightness; if( deltabright >= 32 || (!bg)) { // If the new pixel is significantly brighter than the background color, // use the new color. pixel = c; } else if( deltabright > 0 ) { // If the new pixel is just slightly brighter than the background color, // mix a blend of the new color and the background color pixel = blend( bg, c, deltabright * 8); } else { // if the new pixel is not at all brighter than the background color, // just use the background color. pixel = bg; } } } // This function takes a time in pseudo-milliseconds, // figures out brightness = f( time ), and also hue = f( time ) // The 'low digits' of the millisecond time are used as // input to the brightness wave function. // The 'high digits' are used to select a color, so that the color // does not change over the course of the fade-in, fade-out // of one cycle of the brightness wave function. // The 'high digits' are also used to determine whether this pixel // should light at all during this cycle, based on the TWINKLE_DENSITY. CRGB computeOneTwinkle( uint32_t ms, uint8_t salt) { uint16_t ticks = ms >> (8-TWINKLE_SPEED); uint8_t fastcycle8 = ticks; uint16_t slowcycle16 = (ticks >> 8) + salt; slowcycle16 += sin8( slowcycle16); slowcycle16 = (slowcycle16 * 2053) + 1384; uint8_t slowcycle8 = (slowcycle16 & 0xFF) + (slowcycle16 >> 8); uint8_t bright = 0; if( ((slowcycle8 & 0x0E)/2) < TWINKLE_DENSITY) { bright = attackDecayWave8( fastcycle8); } uint8_t hue = slowcycle8 - salt; CRGB c; if( bright > 0) { c = ColorFromPalette( gCurrentPalette, hue, bright, NOBLEND); if( COOL_LIKE_INCANDESCENT == 1 ) { coolLikeIncandescent( c, fastcycle8); } } else { c = CRGB::Black; } return c; } // This function is like 'triwave8', which produces a // symmetrical up-and-down triangle sawtooth waveform, except that this // function produces a triangle wave with a faster attack and a slower decay: // // / \ // / \ // / \ // / \ // uint8_t attackDecayWave8( uint8_t i) { if( i < 86) { return i * 3; } else { i -= 86; return 255 - (i + (i/2)); } } // This function takes a pixel, and if its in the 'fading down' // part of the cycle, it adjusts the color a little bit like the // way that incandescent bulbs fade toward 'red' as they dim. void coolLikeIncandescent( CRGB& c, uint8_t phase) { if( phase < 128) return; uint8_t cooling = (phase - 128) >> 4; c.g = qsub8( c.g, cooling); c.b = qsub8( c.b, cooling * 2); } // A mostly red palette with green accents and white trim. // "CRGB::Gray" is used as white to keep the brightness more uniform. const TProgmemRGBPalette16 RedGreenWhite_p FL_PROGMEM = { CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray, CRGB::Green, CRGB::Green, CRGB::Green, CRGB::Green }; // A mostly (dark) green palette with red berries. #define Holly_Green 0x00580c #define Holly_Red 0xB00402 const TProgmemRGBPalette16 Holly_p FL_PROGMEM = { Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Red }; // A red and white striped palette // "CRGB::Gray" is used as white to keep the brightness more uniform. const TProgmemRGBPalette16 RedWhite_p FL_PROGMEM = { CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Gray }; // A mostly blue palette with white accents. // "CRGB::Gray" is used as white to keep the brightness more uniform. const TProgmemRGBPalette16 BlueWhite_p FL_PROGMEM = { CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Gray, CRGB::Gray, CRGB::Gray }; // A pure "fairy light" palette with some brightness variations #define HALFFAIRY ((CRGB::FairyLight & 0xFEFEFE) / 2) #define QUARTERFAIRY ((CRGB::FairyLight & 0xFCFCFC) / 4) const TProgmemRGBPalette16 FairyLight_p FL_PROGMEM = { CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, HALFFAIRY, HALFFAIRY, CRGB::FairyLight, CRGB::FairyLight, QUARTERFAIRY, QUARTERFAIRY, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight }; // A palette of soft snowflakes with the occasional bright one const TProgmemRGBPalette16 Snow_p FL_PROGMEM = { 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0xE0F0FF }; // A palette reminiscent of large 'old-school' C9-size tree lights // in the five classic colors: red, orange, green, blue, and white. #define C9_Red 0xB80400 #define C9_Orange 0x902C02 #define C9_Green 0x046002 #define C9_Blue 0x070758 #define C9_White 0x606820 const TProgmemRGBPalette16 RetroC9_p FL_PROGMEM = { C9_Red, C9_Orange, C9_Red, C9_Orange, C9_Orange, C9_Red, C9_Orange, C9_Red, C9_Green, C9_Green, C9_Green, C9_Green, C9_Blue, C9_Blue, C9_Blue, C9_White }; // A cold, icy pale blue palette #define Ice_Blue1 0x0C1040 #define Ice_Blue2 0x182080 #define Ice_Blue3 0x5080C0 const TProgmemRGBPalette16 Ice_p FL_PROGMEM = { Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue2, Ice_Blue2, Ice_Blue2, Ice_Blue3 }; // Add or remove palette names from this list to control which color // palettes are used, and in what order. const TProgmemRGBPalette16* ActivePaletteList[] = { &RetroC9_p, &BlueWhite_p, &RainbowColors_p, &FairyLight_p, &RedGreenWhite_p, &PartyColors_p, &RedWhite_p, &Snow_p, &Holly_p, &Ice_p }; // Advance to the next color palette in the list (above). void chooseNextColorPalette( CRGBPalette16& pal) { const uint8_t numberOfPalettes = sizeof(ActivePaletteList) / sizeof(ActivePaletteList[0]); static uint8_t whichPalette = -1; whichPalette = addmod8( whichPalette, 1, numberOfPalettes); pal = *(ActivePaletteList[whichPalette]); }