Skip to content

Instantly share code, notes, and snippets.

@jotux
Last active January 3, 2016 04:59
Show Gist options
  • Save jotux/8413007 to your computer and use it in GitHub Desktop.
Save jotux/8413007 to your computer and use it in GitHub Desktop.
Bit-banged ws2801 arduino driver
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// __ __________ _____ __ _
// / / / ____/ __ \ / ___// /______(_)___
// / / / __/ / / / / \__ \/ __/ ___/ / __ \
// / /___/ /___/ /_/ / ___/ / /_/ / / / /_/ /
// /_____/_____/_____/ /____/\__/_/ /_/ .___/
// /_/
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
// 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