Skip to content

Instantly share code, notes, and snippets.

@jnovack
Last active May 21, 2021 13:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jnovack/ce208617a2ec53af11d674b20b127c9a to your computer and use it in GitHub Desktop.
Save jnovack/ce208617a2ec53af11d674b20b127c9a to your computer and use it in GitHub Desktop.
#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