Created
August 3, 2017 08:37
-
-
Save mneuschaefer/cf8ad3addde6a379c487d7a0a1566073 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
/* Activity board for my nephew | |
* lasercut MDF box with http://www.makercase.com/ | |
* two WS2812 LED strips (left and right) | |
* two c470 Ohm resistors (to connect WS2812 data) | |
* 1 Potentiometer / Dial | |
* 1 8x8 LED Matrix (MAX7219) | |
*/ | |
#include <Button.h> // https://github.com/JChristensen/Button | |
#include "LedControl.h" //https://github.com/wayoda/LedControl | |
#include "FastLED.h" // https://github.com/FastLED/FastLED | |
FASTLED_USING_NAMESPACE | |
/* | |
* Setup 8x8 LED Matrix (Max7219) | |
* | |
* pin 8 is connected to the DataIn | |
* pin 10 is connected to the CLK | |
* pin 9 is connected to LOAD | |
* We have only a single MAX72XX. | |
*/ | |
LedControl lc=LedControl(8,10,9,1); //DIN, CLK, LOAD, Number of matrices | |
/* | |
* Setup Potentiometer and LED strip Data Pins | |
*/ | |
#define POTPIN A5 // Potentiometer | |
// define data pin1 here (upper lights) | |
#define DATA_PIN_UP 6 | |
// define data pin2 here (leftlights) | |
#define DATA_PIN_LEFT 7 | |
// define number of LEDs and brightness for LED strips | |
#define NUM_LEDS_UP 10 | |
#define NUM_LEDS_LEFT 18 | |
#define BRIGHTNESS 100 | |
// #define FRAMES_PER_SECOND | |
int FRAMES_PER_SECOND = 5; | |
#define LED_TYPE WS2811 | |
#define COLOR_ORDER GRB | |
CRGB leds[NUM_LEDS_UP]; | |
CRGB ledsLeft[NUM_LEDS_LEFT]; | |
// Define Buttons | |
#define BTN_PIN_RED 1 // Red Button | |
#define BTN_PIN_LED_RIGHT 2 // Button for right LED strip | |
#define BTN_PIN_LED_LEFT 5 // Button for left LED Strip | |
#define PULLUP true //To keep things simple, we use the Arduino's internal pullup resistor. | |
#define INVERT true //Since the pullup resistor will keep the pin high unless the | |
//switch is closed, this is negative logic, i.e. a high state | |
//means the button is NOT pressed. (Assuming a normally open switch.) | |
#define DEBOUNCE_MS 20 //A debounce time of 20 milliseconds usually works well for tactile button switches. | |
Button BtnLedRight(BTN_PIN_LED_RIGHT, PULLUP, INVERT, DEBOUNCE_MS); //black button, controls right led strip | |
Button BtnLedLeft(BTN_PIN_LED_LEFT, PULLUP, INVERT, DEBOUNCE_MS); //big black button on the left, controls left led strip | |
Button BtnRed(BTN_PIN_RED, PULLUP, INVERT, DEBOUNCE_MS); //Declare the red button | |
int val = 0; // variables to store the value coming from the Potentiometer | |
int percentageTurn = 0; | |
uint8_t gHue = 0; // rotating "base color" used by many of the patterns | |
// define font for 8x8 LED matrix | |
int numChar = 29; // number of characters stored in arr1 (below) | |
int arr1[][8] = { | |
{ | |
B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000 // Space | |
}, | |
{ | |
B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000 // Space | |
}, | |
{ | |
B00000000, B00000000, B01111110, B00010001, B00010001, B01111110, B00000000, B00000000 // A | |
}, | |
{ | |
B00000000, B00000000, B01111111, B01001001, B01001001, B00110110, B00000000, B00000000 // B | |
}, | |
{ | |
B00000000, B00000000, B00111110, B01000001, B01000001, B00100010, B00000000, B00000000 // C | |
}, | |
{ | |
B00000000, B00000000, B01111111, B01000001, B01000001, B00111110, B00000000, B00000000 // D | |
}, | |
{ | |
B00000000, B00000000, B01111111, B01001001, B01001001, B01000001, B00000000, B00000000 // E | |
}, | |
{ | |
B00000000, B00000000, B01111111, B00001001, B00001001, B00000001, B00000000, B00000000 // F | |
}, | |
{ | |
B00000000, B00000000, B00111110, B01000001, B01001001, B01111010, B00000000, B00000000 // G | |
}, | |
{ | |
B00000000, B00000000, B01111111, B00001000, B00001000, B01111111, B00000000, B00000000 // H | |
}, | |
{ | |
B00000000, B00000000, B01000001, B01111111, B01000001, B00000000, B00000000, B00000000 // I | |
}, | |
{ | |
B00000000, B00000000, B00110000, B01000000, B01000001, B00111111, B00000000, B00000000 // J | |
}, | |
{ | |
B00000000, B00000000, B01111111, B00001000, B00010100, B01100011, B00000000, B00000000 // K | |
}, | |
{ | |
B00000000, B00000000, B01111111, B01000000, B01000000, B01000000, B00000000, B00000000 // L | |
}, | |
{ | |
B00000000, B00000000, B01111111, B00000010, B00001100, B00000010, B01111111, B00000000 // M | |
}, | |
{ | |
B00000000, B00000000, B01111111, B00000100, B00001000, B00010000, B01111111, B00000000 // N | |
}, | |
{ | |
B00000000, B00000000, B00111110, B01000001, B01000001, B00111110, B00000000, B00000000 // O | |
}, | |
{ | |
B00000000, B00000000, B01111111, B00001001, B00001001, B00000110, B00000000, B00000000 // P | |
}, | |
{ | |
B00000000, B00000000, B00111110, B01000001, B01000001, B10111110, B00000000, B00000000 // Q | |
}, | |
{ | |
B00000000, B00000000, B01111111, B00001001, B00001001, B01110110, B00000000, B00000000 // R | |
}, | |
{ | |
B00000000, B00000000, B01000110, B01001001, B01001001, B00110010, B00000000, B00000000 // S | |
}, | |
{ | |
B00000000, B00000000, B00000001, B00000001, B01111111, B00000001, B00000000, B00000000 // T | |
}, | |
{ | |
B00000000, B00000000, B00111111, B01000000, B01000000, B00111111, B00000000, B00000000 // U | |
}, | |
{ | |
B00000000, B00000000, B00001111, B00110000, B01000000, B00110000, B00001111, B00000000 // V | |
}, | |
{ | |
B00000000, B00000000, B00111111, B01000000, B00111000, B01000000, B00111111, B00000000 // W | |
}, | |
{ | |
B00000000, B00000000, B01100011, B00010100, B00001000, B00010100, B01100011, B00000000 // X | |
}, | |
{ | |
B00000000, B00000000, B00000111, B00001000, B01110000, B00001000, B00000111, B00000000 // Y | |
}, | |
{ | |
B00000000, B00000000, B01100001, B01010001, B01001001, B01000111, B00000000, B00000000 // Z | |
}, | |
{ | |
B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000 // Space | |
} | |
}; | |
void setup(){ | |
delay(3000); // 3 second delay for recovery | |
// tell FastLED about the LED strip configuration | |
FastLED.addLeds<LED_TYPE,DATA_PIN_UP,COLOR_ORDER>(leds, NUM_LEDS_UP).setCorrection(TypicalLEDStrip); | |
FastLED.addLeds<LED_TYPE,DATA_PIN_LEFT,COLOR_ORDER>(ledsLeft, NUM_LEDS_LEFT).setCorrection(TypicalLEDStrip); | |
// set master brightness control | |
FastLED.setBrightness(BRIGHTNESS); | |
lc.shutdown(0,false); | |
/* Set the brightness to a medium values */ | |
lc.setIntensity(0,1); // Set Brightness for small LED Matrix here (0,1 - 1) | |
/* and clear the display */ | |
lc.clearDisplay(0); | |
// setup serial monitor | |
Serial.begin(9600); | |
} | |
// List of patterns to cycle through. Each is defined as a separate function below. | |
typedef void (*SimplePatternList[])(); | |
uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current | |
// define patterns here, e.g. (full list): | |
// SimplePatternList gPatterns = {lightsOff, sinelon, confetti, bpm, rainbow, rainbowWithGlitter, juggle}; | |
SimplePatternList gPatterns = {sinelon, confetti, bpm, rainbow, rainbowWithGlitter, juggle}; | |
typedef void (*SimplePatternListLeft[])(); | |
uint8_t gCurrentPatternNumberLeft = 0; // Index number of which pattern is current | |
// SimplePatternListLeft gPatternsLeft = {lightsOffLeft, confettiLeft, sinelonLeft, bpmLeft, rainbowLeft, rainbowWithGlitterLeft, juggleLeft}; | |
SimplePatternListLeft gPatternsLeft = {confettiLeft, sinelonLeft, bpmLeft, rainbowLeft, rainbowWithGlitterLeft, juggleLeft}; | |
void loop(){ | |
checkPotentiometer(); | |
// transform Poti val to values 0-100 (0 = turned left, 100 = turned right) | |
percentageTurn = map(val, 13, 978, numChar, 1); | |
//print poti val to serial (Debug) | |
// Serial.println(percentageTurn); | |
// print red letters on 8x8 led matrix | |
printLetters(); | |
BtnLedRight.read(); // read the right black button | |
BtnLedLeft.read(); // read the left black button | |
BtnRed.read(); // read the left red button | |
if (BtnLedRight.wasReleased()) { //If the button was released, change the LED state | |
// do stuff, e.g. | |
nextPattern(); | |
} | |
if (BtnLedLeft.wasReleased()) { //If the button was released, change the LED state | |
// do stuff, e.g. | |
nextPatternLeft(); | |
} | |
if (BtnRed.wasReleased()) { //If the button was released, change the LED state to first in arrays | |
// do stuff, e.g. | |
offPattern(); | |
} | |
//EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically (optional) | |
//update led strips | |
// Call the current pattern function once, updating the 'leds' and 'ledsLeft' arrays | |
gPatterns[gCurrentPatternNumber](); | |
// send the 'leds' array out to the UPPER LED strip | |
gPatternsLeft[gCurrentPatternNumberLeft](); | |
// send the 'ledsLeft' array out to the LEFT 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 | |
} | |
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) | |
/* functions for Right LED strip (array 'led') | |
*/ | |
void offPattern() | |
{ | |
// add one to the current pattern number, and wrap around at the end | |
gCurrentPatternNumber = 0; | |
gCurrentPatternNumberLeft = 0; | |
} | |
void nextPattern() | |
{ | |
// add one to the current pattern number, and wrap around at the end | |
gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns); | |
} | |
void nextPatternLeft() | |
{ | |
// add one to the current pattern number, and wrap around at the end | |
gCurrentPatternNumberLeft = (gCurrentPatternNumberLeft + 1) % ARRAY_SIZE( gPatternsLeft); | |
} | |
void lightsOff() | |
{ | |
// a black dot clearing all in the upper LED field | |
for(int dot = 0; dot < NUM_LEDS_UP; dot++) { | |
// clear this led for the next time around the loop | |
leds[dot] = CRGB::Black; | |
FastLED.show(); | |
} | |
} | |
void rainbow() | |
{ | |
// FastLED's built-in rainbow generator | |
fill_rainbow( leds, NUM_LEDS_UP, 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_UP) ] += CRGB::White; | |
} | |
} | |
void confetti() | |
{ | |
// random colored speckles that blink in and fade smoothly | |
fadeToBlackBy( leds, NUM_LEDS_UP, 15); | |
int pos = random16(NUM_LEDS_UP); | |
leds[pos] += CHSV( gHue + random8(64), 200, 255); | |
} | |
void sinelon() | |
{ | |
// a colored dot sweeping back and forth, with fading trails | |
fadeToBlackBy( leds, NUM_LEDS_UP, 20); | |
int pos = beatsin16(13,0,NUM_LEDS_UP); | |
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_UP; 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_UP, 20); | |
byte dothue = 0; | |
for( int i = 0; i < 8; i++) { | |
leds[beatsin16(i+7,0,NUM_LEDS_UP)] |= CHSV(dothue, 200, 255); | |
dothue += 32; | |
} | |
} | |
/* | |
* functions for Left LED strip (array 'ledLeft') | |
*/ | |
void lightsOffLeft() | |
{ | |
// a black dot clearing all to the left | |
for(int dot = 0; dot < NUM_LEDS_LEFT; dot++) { | |
// clear this led for the next time around the loop | |
ledsLeft[dot] = CRGB::Black; | |
FastLED.show(); | |
} | |
} | |
void rainbowLeft() | |
{ | |
// FastLED's built-in rainbow generator | |
fill_rainbow( ledsLeft, NUM_LEDS_LEFT, gHue, 7); | |
} | |
void rainbowWithGlitterLeft() | |
{ | |
// built-in FastLED rainbow, plus some random sparkly glitter | |
rainbowLeft(); | |
addGlitterLeft(80); | |
} | |
void addGlitterLeft( fract8 chanceOfGlitterLeft) | |
{ | |
if( random8() < chanceOfGlitterLeft) { | |
ledsLeft[ random16(NUM_LEDS_LEFT) ] += CRGB::White; | |
} | |
} | |
void confettiLeft() | |
{ | |
// random colored speckles that blink in and fade smoothly | |
fadeToBlackBy( ledsLeft, NUM_LEDS_LEFT, 15); | |
int pos = random16(NUM_LEDS_LEFT); | |
ledsLeft[pos] += CHSV( gHue + random8(64), 200, 255); | |
} | |
void sinelonLeft() | |
{ | |
// a colored dot sweeping back and forth, with fading trails | |
fadeToBlackBy( ledsLeft, NUM_LEDS_LEFT, 20); | |
int pos = beatsin16(13,0,NUM_LEDS_LEFT); | |
ledsLeft[pos] += CHSV( gHue, 255, 192); | |
} | |
void bpmLeft() | |
{ | |
// 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_LEFT; i++) { //9948 | |
ledsLeft[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10)); | |
} | |
} | |
void juggleLeft() { | |
// eight colored dots, weaving in and out of sync with each other | |
fadeToBlackBy( ledsLeft, NUM_LEDS_LEFT, 20); | |
byte dothue = 0; | |
for( int i = 0; i < 8; i++) { | |
ledsLeft[beatsin16(i+7,0,NUM_LEDS_LEFT)] |= CHSV(dothue, 200, 255); | |
dothue += 32; | |
} | |
} | |
void checkPotentiometer(){ | |
val = analogRead(POTPIN); // read the value from the sensor | |
} | |
void printLetters(){ | |
print(percentageTurn - 1); | |
// lc.clearDisplay(0); | |
} | |
void print(int charNum) | |
{ | |
for (int i = 0; i < 8; i++) | |
{ | |
lc.setRow(0,i,arr1[charNum][i]); | |
//lc.setRow(0,i,arr1[0][i]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment