Created
October 21, 2014 23:34
-
-
Save jbdatko/069f03a02415d5adef2a to your computer and use it in GitHub Desktop.
Cylon SAINTCON Blinky
This file contains hidden or 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 <tlc_shifts.h> | |
#include <tlc_config.h> | |
#include <tlc_animations.h> | |
#include <tlc_fades.h> | |
#include <tlc_servos.h> | |
#include <Tlc5940.h> | |
#include <tlc_progmem_utils.h> | |
/* | |
Blinky code for SAINTcon 2014 | |
v .5 | |
Matt Lorimer | |
This code uses the TLC5940 library created by <SOURCE URL foo>. | |
Changelog: | |
Todo: | |
Change Func button to pin 1 or 2 and use interrupts rather than infinite loops | |
Additional patterns | |
POV stuff? | |
*/ | |
#include "Tlc5940.h" | |
//Which button is the function button | |
const int funcButton = 2; // the number of the pushbutton pin | |
//const int badgeLight = 6; | |
const int topRight = 9; | |
const int bottomRight = 6; | |
const int topLeft = 10; | |
const int bottomLeft = 11; | |
//Standard delay for animations | |
int pause = 100; | |
//These RGB LEDs are BRIGHT. Set this between 0 and 1 to scale that brightness | |
float intensity = .1; | |
void setup() | |
{ | |
reInitTLC(); | |
//Function button | |
pinMode(funcButton, INPUT); | |
//The top right badge LED isn't used by the TLC5940's so lets have it on all the time for the Acrylic | |
pinMode(bottomRight, OUTPUT); | |
analogWrite(bottomRight, 255); | |
} | |
void loop() | |
{ | |
//Each function is an infinite loop. If you push the button, a return statement exits the infinite loop and runs the next animation | |
testPattern1(); | |
//Give them time to pull their finger off the button | |
delay(400); | |
//Next clear the RGB LEDs and light the acrylic with all LEDs | |
lightAcrylic(); | |
//Give them time to pull their finger off the button | |
delay(400); | |
reInitTLC(); | |
testPattern2(); | |
//Give them time to pull their finger off the button | |
delay(400); | |
solid(); | |
//Give them time to pull their finger off the button | |
delay(400); | |
} | |
void reInitTLC() | |
{ | |
// init the TLC library/chip | |
Tlc.init(0); | |
//The TLC5940 needs a bit of time or it can do weird things for the first pin or two. | |
delay(200); | |
} | |
void lightAcrylic() | |
{ | |
//Turn off all the LEDs | |
clearBlinkies(); | |
/* pinMode(topRight, OUTPUT); | |
pinMode(topLeft, OUTPUT); | |
pinMode(bottomLeft, OUTPUT); | |
*/ | |
analogWrite(topRight, 255); | |
analogWrite(topLeft, 255); | |
analogWrite(bottomLeft, 255); | |
//Infinite loop runs until return is called | |
while(true) | |
{ | |
//Check for button press | |
if (digitalRead(funcButton) == HIGH) | |
{ | |
//Clear any programming currently set for LEDs | |
Tlc.clear(); | |
//Now go back to loop() function | |
return; | |
} | |
} | |
// Could probably skip this delay to make the program more responsive.... | |
delay(150); | |
} | |
//Turn off all LEDs | |
void clearBlinkies() | |
{ | |
//Clear all the LEDs | |
Tlc.clear(); | |
//Tell the TLC5940 to activate newly stored valus | |
Tlc.update(); | |
} | |
//Light up all LEDs the same random color | |
void solid() | |
{ | |
//list of colors | |
unsigned long colors[] = {0xFFFFFF, 0xFF0000, 0xFF6600, 0xFFFF66, 0xFFFF00, 0x00FF00, 0x00CCCC, 0x0099FF, 0x0000FF, 0x9900CC, 0xFF00FF}; | |
// array to hold pointer to current pin | |
int ledPins[3]; | |
//choose color from the list randomly | |
unsigned long color = colors[random(11)]; | |
//Light up each of the LEDs accordingly | |
for(int i = 0; i < 32; i += 3) | |
{ | |
//We need to skip pin 16, there is nothing there | |
if(i == 15) | |
{ | |
i++; | |
} | |
//Specify the pins for the current LED - There is likely a better way to do this | |
ledPins[0] = i; | |
ledPins[1] = i+1; | |
ledPins[2] = i+2; | |
colorLED(ledPins, color); | |
} | |
//Tell drivers to output newly stored values | |
Tlc.update(); | |
//Infinite loop runs until return is called | |
while(true) | |
{ | |
//Check for button press | |
if (digitalRead(funcButton) == HIGH) | |
{ | |
//Clear any programming currently set for LEDs | |
Tlc.clear(); | |
//Now go back to loop() function | |
return; | |
} | |
} | |
// Could probably skip this delay to make the program more responsive.... | |
delay(150); | |
} | |
//Scan from outside to middle with test color pattern | |
void testPattern1() | |
{ | |
unsigned long colors[] = {0xFF0000, 0x00FF00, 0x0000FF, 0xFF7F00, 0xFFFF00, 0xB266FF}; | |
//2 LED pin values for each end | |
int ledPins1[3]; | |
int ledPins2[3]; | |
//Infinite loop runs until return is called | |
while(true) | |
{ | |
//Specify the pins for the current LED - There is likely a better way to do this | |
ledPins1[0] = 0; | |
ledPins1[1] = 1; | |
ledPins1[2] = 2; | |
ledPins2[0] = 28; | |
ledPins2[1] = 29; | |
ledPins2[2] = 30; | |
Tlc.update(); | |
for(int pinLoop = 0; pinLoop < 5; pinLoop++) | |
{ | |
for(int colorLoop = 0 ; colorLoop < 6 ; colorLoop++) | |
{ | |
//Clear any programming | |
Tlc.clear(); | |
//Color the 2 LEDs | |
colorLED(ledPins1, colors[colorLoop]); | |
colorLED(ledPins2, colors[colorLoop]); | |
//Tell drivers to output newly stored values | |
Tlc.update(); | |
//Delay so users can see the pretty colors | |
delay(pause); | |
//Check for button press | |
if (digitalRead(funcButton) == HIGH) | |
{ | |
//Clear any programming currently set for LEDs | |
Tlc.clear(); | |
//Now go back to loop() function | |
return; | |
} | |
} | |
//Move ledPins1 to the next LED | |
ledPins1[0] += 3; | |
ledPins1[1] += 3; | |
ledPins1[2] += 3; | |
//Move ledPins2 to the previous LED | |
ledPins2[0] -= 3; | |
ledPins2[1] -= 3; | |
ledPins2[2] -= 3; | |
} | |
} | |
} | |
void update(int *ledPins, int up) | |
{ | |
//Update the value for this pin | |
colorLED(ledPins, 0x0000FF); | |
//Tell drivers to output newly stored values | |
Tlc.update(); | |
//Delay so users can see the pretty colors | |
delay(50); | |
if (up) | |
{ | |
//Increment pins | |
ledPins[0] += 3; | |
ledPins[1] += 3; | |
ledPins[2] += 3; | |
} | |
else | |
{ | |
ledPins[0] -= 3; | |
ledPins[1] -= 3; | |
ledPins[2] -= 3; | |
} | |
} | |
//Scan LEDs in order with pre-defined color pattern | |
void testPattern2() | |
{ | |
//Color pattern | |
unsigned long colors[] = {0xFF0000, 0xFF6600, 0xFFFF66, 0xFFFF00, 0x00FF00, 0x00CCCC, 0x0099FF, 0x0000FF, 0x9900CC, 0xFF00FF}; | |
//arry containing pins for the LED to be lit | |
int ledPins[3]; | |
//Infinite loop runs until return is called | |
while(true) | |
{ | |
//Initialize ledPins, so we start at the first LED | |
ledPins[0] = 0; | |
ledPins[1] = 1; | |
ledPins[2] = 2; | |
//Loop through all the LEDs | |
for(int patternLoop = 0; patternLoop < 3; patternLoop++) | |
{ | |
//Clear any stored values | |
Tlc.clear(); | |
update(ledPins, 1); | |
update(ledPins, 1); | |
update(ledPins, 1); | |
//Nothing is plugged into pin 16, so we need to skip it | |
if(patternLoop == 5) | |
{ | |
ledPins[0] += 1; | |
ledPins[1] += 1; | |
ledPins[2] += 1; | |
} | |
} | |
for(int patternLoop = 0; patternLoop < 3; patternLoop++) | |
{ | |
//Clear any stored values | |
Tlc.clear(); | |
update(ledPins, 0); | |
update(ledPins, 0); | |
update(ledPins, 0); | |
//Check for button press | |
if (digitalRead(funcButton) == HIGH) | |
{ | |
//Clear any programming currently set for LEDs | |
Tlc.clear(); | |
//Now go back to loop() function | |
return; | |
} | |
} | |
} | |
} | |
// Function to color the LED the given hex color code | |
void colorLED(int ledPins[], unsigned long color) | |
{ | |
/* | |
Code and explanation adapted from: http://ardx.org/src/code/CIRC12-code-MB-SPAR.txt | |
Sets the color of the RGB LED to the color specified by the | |
HTML-style hex triplet color value supplied to the function. | |
The color value supplied should be an unsigned long number | |
of the form: | |
0xRRGGBB | |
e.g. 0xFF7F00 is orange | |
where: | |
0x specifies the value is a hexadecimal number | |
RR is a byte specifying the red intensity | |
GG is a byte specifying the green intensity | |
BB is a byte specifying the blue intensity | |
How it works (you don't need to understand this to use the function): | |
The supplied value of the form 0xRRGGBB is an unsigned long which can | |
store four bytes. If we view the number in bit form the bits of the | |
unsigned long look like this: | |
iiiiiiiirrrrrrrrggggggggbbbbbbbb | |
where: | |
i are bits that are ignored (because we only need three bytes for the value) | |
r are bits specifying the red intensity | |
g are bits specifying the green intensity | |
b are bits specifying the blue intensity | |
We use bit shifting and masking to extract the individual values. | |
Bit shifting moves the bits in a number along in one direction to produce | |
a new number. For example ">> n" means shift the bits n positions to the | |
right. | |
e.g. iiiiiiiirrrrrrrrggggggggbbbbbbbb >> 8 gives: | |
00000000iiiiiiiirrrrrrrrgggggggg | |
The number 0xFF represents the bit mask: | |
00000000000000000000000011111111 | |
The "&" character means the two values are "and"ed together--for each bit | |
in the two numbers being "and"ed together the resulting bit is only set in | |
the result if the same bits are set in both the input numbers. | |
So, continuing our example: | |
00000000iiiiiiiirrrrrrrrgggggggg && 0xFF gives: | |
00000000iiiiiiiirrrrrrrrgggggggg && | |
00000000000000000000000011111111 = | |
000000000000000000000000gggggggg | |
And we now have extracted only the green bits from our hex triplet. | |
More details on bit math can be found here: | |
<http://www.arduino.cc/playground/Code/BitMath> | |
*/ | |
// Extract the intensity values from the hex triplet | |
int redIntensity = (color >> 16) & 0xFF; | |
int greenIntensity = (color >> 8) & 0xFF; | |
int blueIntensity = color & 0xFF; | |
//Do some software based color calibrations | |
redIntensity = redIntensity * 4 * intensity; | |
greenIntensity = greenIntensity * 3 * intensity; | |
blueIntensity = blueIntensity * 4 * intensity; | |
//Make sure the value isn't too high | |
if (redIntensity > 4095) { | |
redIntensity = 4095; | |
} | |
if (greenIntensity > 4095) { | |
greenIntensity = 4095; | |
} | |
if (blueIntensity > 4095) { | |
blueIntensity = 4095; | |
} | |
//Now turn on each color with the intensity adjustment | |
Tlc.set(ledPins[0], redIntensity); | |
Tlc.set(ledPins[1], greenIntensity); | |
Tlc.set(ledPins[2], blueIntensity); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment