Skip to content

Instantly share code, notes, and snippets.

@jbdatko
Created October 21, 2014 23:34
Show Gist options
  • Save jbdatko/069f03a02415d5adef2a to your computer and use it in GitHub Desktop.
Save jbdatko/069f03a02415d5adef2a to your computer and use it in GitHub Desktop.
Cylon SAINTCON Blinky
#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