Last active
May 21, 2021 13:39
-
-
Save jnovack/ce208617a2ec53af11d674b20b127c9a 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> | |
/* halloween.ino | |
* https://gist.github.com/jnovack/ce208617a2ec53af11d674b20b127c9a/ | |
* 2021 - Justin J. Novack | |
* | |
* When the PIN_PIR is rising (from LOW to HIGH, e.g. 0V to 5V), turn on the pixels | |
* in a random order waiting DELAY_ON between each pixel, then wait DELAY_WAIT before | |
* starting to turn the pixels off, waiting DELAY_OFF between each pixel. | |
* | |
* DELAY_ON is the eyes "waking up" | |
* DELAY_WAIT is the eyes "staying open" | |
* DELAY_OFF is the eyes "going back to sleep" | |
* | |
* Each time this runs, the pixels turn on in a different order, with different colors, | |
* turning on at different intervals, stay on for different intervals, and turn off at | |
* different intervals. | |
*/ | |
#define PIN_PIR 13 // D7 | |
#define PIN_LED 5 // D1 | |
#define NUMPIXELS 4 // Popular NeoPixel ring size | |
#define BRIGHTNESS 128 // 0-255 | |
#define DELAYVAL 40 // Time (in milliseconds) to pause between pixels | |
#define DELAY_ON_MIN 100 // Time (in milliseconds) for minimum delay between pixels turning on | |
#define DELAY_ON_MAX 500 // Time (in milliseconds) for minimum delay between pixels turning on | |
#define DELAY_WAIT_MIN 2000 // Time (in milliseconds) for minimum delay between pixels staying on | |
#define DELAY_WAIT_MAX 6000 // Time (in milliseconds) for minimum delay between pixels staying on | |
#define DELAY_OFF_MIN 1000 // Time (in milliseconds) for minimum delay between pixels turning off | |
#define DELAY_OFF_MAX 2500 // Time (in milliseconds) for minimum delay between pixels turning off | |
// Array of colors to choose from, duplicates are weighted higher | |
int colors[ 14 ][ 3 ] = { | |
{ 255, 0, 0 }, // Red | |
{ 255, 0, 0 }, // Red | |
{ 255, 127, 0 }, // Orange | |
{ 255, 127, 0 }, // Orange | |
{ 0, 255, 0 }, // Green | |
{ 0, 255, 0 }, // Green | |
{ 127, 255, 0 }, // Light Green | |
{ 255, 255, 0 }, // Yellow | |
{ 255, 255, 0 }, // Yellow | |
{ 0, 0, 255 }, // Blue | |
{ 255, 0, 255 }, // Light Purple | |
{ 127, 0, 255 }, // Dark Purple | |
{ 127, 0, 255 }, // Dark Purple | |
{ 255, 255, 255 }, // White | |
}; | |
// No touching below the belt. | |
Adafruit_NeoPixel pixels(NUMPIXELS, PIN_LED, NEO_RGB + NEO_KHZ800); | |
volatile bool triggered = false; | |
int pixel[NUMPIXELS]; | |
// pirStateChanged sets triggered to true so the loop can run | |
void ICACHE_RAM_ATTR pirStateChanged() { | |
triggered = true; | |
} | |
// setup runs a number of functions just once | |
void setup() { | |
for (int i = 0; i< NUMPIXELS; i++) { // Create array of pixel numbers... | |
pixel[i] = i; | |
} | |
randomSeed(analogRead(A0)); // randomize based on the big bang | |
// Permit the PIR triggering to set a variable at any time so that loop() can use it | |
pinMode(PIN_PIR, INPUT); | |
pixels.begin(); | |
pixels.setBrightness(BRIGHTNESS); | |
attachInterrupt(digitalPinToInterrupt(PIN_PIR), pirStateChanged, RISING); | |
} | |
// loop executes indefintely, but only does anything when the pir | |
// interrupt sets triggered to true | |
void loop() { | |
if (triggered == true) { | |
triggered = false; | |
randomize(pixel, NUMPIXELS); | |
for(int i = 0; i < NUMPIXELS; i++) { // For each pixel... | |
int c = randomNumber(sizeof(colors) / sizeof(colors[0])); | |
pixels.setPixelColor(pixel[i], pixels.Color(colors[c][0], colors[c][1], colors[c][2])); | |
pixels.show(); // Send the updated pixel colors to the hardware. | |
delay(random(DELAY_ON_MIN, DELAY_ON_MAX)); // Pause before next pass through loop | |
} | |
delay(random(DELAY_WAIT_MIN, DELAY_WAIT_MAX)); | |
randomize(pixel, NUMPIXELS); | |
for(int i = 0; i < NUMPIXELS; i++) { // For each pixel... | |
pixels.setPixelColor(pixel[i], pixels.Color(0, 0, 0)); | |
pixels.show(); // Send the updated pixel colors to the hardware. | |
delay(random(DELAY_OFF_MIN, DELAY_OFF_MAX)); // Pause before next pass through loop | |
} | |
} | |
} | |
// randomNumber returns a random number between 0 and n | |
int randomNumber( int n ) { | |
return random(0,n+1); | |
} | |
// swap is for randomize | |
void swap(int *a, int *b) { | |
int temp = *a; | |
*a = *b; | |
*b = temp; | |
} | |
// randomize shuffles an array | |
void randomize ( int arr[], int n ) { | |
for (int i = 0; i < n; i++) { | |
long j = random(0, n); | |
swap(&arr[i], &arr[j]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment