Last active
January 3, 2016 04:59
-
-
Save jotux/8413007 to your computer and use it in GitHub Desktop.
Bit-banged ws2801 arduino driver
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
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
// __ __________ _____ __ _ | |
// / / / ____/ __ \ / ___// /______(_)___ | |
// / / / __/ / / / / \__ \/ __/ ___/ / __ \ | |
// / /___/ /___/ /_/ / ___/ / /_/ / / / /_/ / | |
// /_____/_____/_____/ /____/\__/_/ /_/ .___/ | |
// /_/ | |
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
// Data and clock pin locations on the arduino | |
#define DATA 20 | |
#define CLOCK 21 | |
#define NUM_LED_TOTAL 128 | |
// Each LED has three parameters that determine color and brightness | |
typedef struct | |
{ | |
uint8_t r; | |
uint8_t g; | |
uint8_t b; | |
} Led; | |
// In memory, we'll represent the state of all LEDs as an array of colors | |
Led led_buf[NUM_LED_TOTAL]; | |
// Initialize the pins used to control the WS2801 driver | |
void StripInit(void) | |
{ | |
pinMode(DATA,OUTPUT); | |
pinMode(CLOCK,OUTPUT); | |
digitalWrite(DATA,LOW); | |
digitalWrite(CLOCK,LOW); | |
} | |
// Toggle the clock 8 times and clock out the bit for the color we're sending | |
inline void StripSend(uint8_t b) | |
{ | |
#define _BIT(x) (1<<(x)) | |
for(int i = 7;i >= 0;i--) | |
{ | |
digitalWrite(CLOCK,LOW); | |
digitalWrite(DATA,(b & _BIT(i))); | |
digitalWrite(CLOCK,HIGH); | |
} | |
digitalWrite(CLOCK,LOW); | |
} | |
// Clock our the blue-green-red colors and then latch the colors | |
void StripRefresh(void) | |
{ | |
for (int i = 0; i < NUM_LED_TOTAL;i++) | |
{ | |
StripSend(led_buf[i].b); | |
StripSend(led_buf[i].g); | |
StripSend(led_buf[i].r); | |
} | |
// WS2801 spec says hold the line for > 500 microseconds to latch colors | |
delayMicroseconds(501); | |
} | |
// The following function prototypes are required to suppress an error related to | |
// the "Led" type, defined above. | |
// Given an LED number and a color save it to the LED array | |
void StripSetColor(uint16_t n, Led l); | |
void StripSetColor(uint16_t n, Led l) | |
{ | |
led_buf[n] = l; | |
} | |
// Given a color defined by r/g/b, return an Led type with those values | |
Led ColorRGB(uint8_t r, uint8_t g, uint8_t b); | |
Led ColorRGB(uint8_t r, uint8_t g, uint8_t b) | |
{ | |
Led l; | |
l.r = r; | |
l.g = g; | |
l.b = b; | |
return l; | |
} | |
// Given an LED and a brightness, change each colors in the same proportional | |
// to change the brightness | |
Led BrightnessAdjust(Led l, uint8_t brightness); | |
Led BrightnessAdjust(Led l, uint8_t brightness) | |
{ | |
l.r = (l.r * brightness) / 100; | |
l.g = (l.g * brightness) / 100; | |
l.b = (l.b * brightness) / 100; | |
return l; | |
} | |
// Given a number between 0-1023, set a color on the spectrum from red-blue | |
// Useful for driving the strip directly from a 10-bit ADC value. | |
Led ColorCalculate(uint16_t n); | |
Led ColorCalculate(uint16_t n) | |
{ | |
Led new_color = {0,0,0}; | |
// red | |
if (n >= 0 && n < 511) | |
{ | |
new_color.r = (255 - (n / 2)); | |
} | |
// green | |
if (n > 0 && n <= 511) | |
{ | |
new_color.g = n / 2; | |
} | |
else if (n > 511 && n <= 1024) | |
{ | |
new_color.g = (511 - (n / 2)); | |
} | |
// blue | |
if (n >= 511 && n < 1023) | |
{ | |
new_color.b = ((n / 2) - 255); | |
} | |
else if (n >= 1023) | |
{ | |
new_color.b = 255; | |
} | |
return new_color; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment