Last active
August 2, 2018 07:42
-
-
Save MWers/78441b43ab57183078c7 to your computer and use it in GitHub Desktop.
Arduino Gemma/Flora program to control a NeoPixel traffic signal using a button
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 <Time.h> | |
#define PIXEL_PIN 0 // Digital IO pin connected to the NeoPixels. | |
#define BUTTON_PIN 1 // Digital IO pin connected to the button. This will be | |
// driven with a pull-up resistor so the switch should | |
// pull the pin to ground momentarily. On a high -> low | |
// transition the button press logic will execute. | |
// 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(60, PIXEL_PIN, NEO_GRB + NEO_KHZ800); | |
// User-defined constants | |
#define MANUAL_MODE_TIMEOUT_IN_SEC 30 | |
#define RED_LIGHT_TIMEOUT_IN_SEC 10 | |
#define YELLOW_LIGHT_TIMEOUT_IN_SEC 3 | |
#define GREEN_LIGHT_TIMEOUT_IN_SEC 10 | |
#define RED_LIGHT_FIRST_PIXEL 0 | |
#define RED_LIGHT_LAST_PIXEL 0 | |
#define YELLOW_LIGHT_FIRST_PIXEL 1 | |
#define YELLOW_LIGHT_LAST_PIXEL 1 | |
#define GREEN_LIGHT_FIRST_PIXEL 2 | |
#define GREEN_LIGHT_LAST_PIXEL 2 | |
// Constants | |
#define RED 2 | |
#define YELLOW 1 | |
#define GREEN 0 | |
#define MANUAL_MODE 0 | |
#define AUTOMATIC_MODE 1 | |
// Global variables | |
bool oldState = HIGH; | |
int currColor = GREEN; | |
int currColorTimeout = GREEN_LIGHT_TIMEOUT_IN_SEC; | |
int currMode = AUTOMATIC_MODE; | |
time_t timeOfLastButtonPush = 0; | |
time_t timeOfLastColorChange = 0; | |
time_t currentTimeInSec = 0; | |
// Set up the button and pixels | |
void setup() { | |
// Set up button | |
pinMode(BUTTON_PIN, INPUT_PULLUP); | |
// Initialize all pixels to 'off' | |
strip.begin(); | |
strip.show(); | |
// Show initial color | |
showColor(currColor); | |
} | |
// Main processing loop | |
void loop() { | |
// Get current time for use within the loop | |
currentTimeInSec = now(); | |
// Check to see if manual mode has been invoked or if color change has been requested | |
// Get current button state. | |
bool newState = digitalRead(BUTTON_PIN); | |
// Check if state changed from high to low (button press). | |
if (newState == LOW && oldState == HIGH) { | |
// Short delay to debounce button. | |
delay(20); | |
// Check if button is still low after debounce. | |
newState = digitalRead(BUTTON_PIN); | |
if (newState == LOW) { | |
currColor++; | |
currColor = currColor % 3; | |
showColor(currColor); | |
currMode = MANUAL_MODE; | |
timeOfLastButtonPush = currentTimeInSec; | |
} | |
} | |
// Set the last button state to the old state. | |
oldState = newState; | |
// If the button hasn't been pressed in x seconds, return to automatic mode | |
if (currMode == MANUAL_MODE && | |
(currentTimeInSec - timeOfLastButtonPush > MANUAL_MODE_TIMEOUT_IN_SEC)) { | |
currMode = AUTOMATIC_MODE; | |
// Force an immediate color change | |
timeOfLastColorChange = 0; | |
} | |
// If we're in automatic mode, handle color changes on timeouts | |
if (currMode == AUTOMATIC_MODE) { | |
if (currColor == RED) { | |
currColorTimeout = RED_LIGHT_TIMEOUT_IN_SEC; | |
} else if (currColor == YELLOW) { | |
currColorTimeout = YELLOW_LIGHT_TIMEOUT_IN_SEC; | |
} else if (currColor == GREEN) { | |
currColorTimeout = GREEN_LIGHT_TIMEOUT_IN_SEC; | |
} | |
if (currentTimeInSec - timeOfLastColorChange > currColorTimeout) { | |
currColor++; | |
currColor = currColor % 3; | |
showColor(currColor); | |
timeOfLastColorChange = currentTimeInSec; | |
} | |
} | |
} | |
// Set the traffic signal to the given color | |
void showColor(int color) { | |
for (int i = RED_LIGHT_FIRST_PIXEL; i <= RED_LIGHT_LAST_PIXEL; i++) { | |
if (color == RED) { | |
strip.setPixelColor(i, 255, 0, 0); | |
} else { | |
strip.setPixelColor(i, 0, 0, 0); | |
} | |
} | |
for (int i = YELLOW_LIGHT_FIRST_PIXEL; i <= YELLOW_LIGHT_LAST_PIXEL; i++) { | |
if (color == YELLOW) { | |
strip.setPixelColor(i, 255, 200, 0); | |
} else { | |
strip.setPixelColor(i, 0, 0, 0); | |
} | |
} | |
for (int i = GREEN_LIGHT_FIRST_PIXEL; i <= GREEN_LIGHT_LAST_PIXEL; i++) { | |
if (color == GREEN) { | |
strip.setPixelColor(i, 0, 255, 0); | |
} else { | |
strip.setPixelColor(i, 0, 0, 0); | |
} | |
} | |
strip.show(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment