LED Strip Test

Here’s a test of a couple of WS2801’s. Once I understood how this worked, I implemented it on a strip of WS2801 based LED’s.


/*

This code was slightly modified by that from:

Nathan Seidle
SparkFun Electronics 2011

This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).

Controlling an LED strip with individually controllable RGB LEDs. This stuff is awesome.

The SparkFun (individually controllable) RGB strip contains a bunch of WS2801 ICs. These
are controlled over a simple data and clock setup. The WS2801 is really cool! Each IC has its
own internal clock so that it can do all the PWM for that specific LED for you. Each IC
requires 24 bits of 'greyscale' data. This means you can have 256 levels of red, 256 of blue,
and 256 levels of green for each RGB LED. REALLY granular.

To control the strip, you clock in data continually. Each IC automatically passes the data onto
the next IC. Once you pause for more than 500us, each IC 'posts' or begins to output the color data
you just clocked in. So, clock in (24bits * 32LEDs = ) 768 bits, then pause for 500us. Then
repeat if you wish to display something new.

This example code will display bright red, green, and blue, then 'trickle' random colors down
the LED strip.

You will need to connect 5V/Gnd from the Arduino (USB power seems to be sufficient).

For the data pins, please pay attention to the arrow printed on the strip. You will need to connect to
the end that is the begining of the arrows (data connection)--->

If you have a 4-pin connection:
Blue = 5V
Red = SDI
Green = CKI
Black = GND

If you have a split 5-pin connection:
2-pin Red+Black = 5V/GND
Green = CKI
Red = SDI
*/

int SDI = 11; // Red wire (not the red 5V wire!)
int CKI = 13; // Green wire

#define STRIP_LENGTH 2 // Start with 2, and expand from there
long strip_colors[STRIP_LENGTH];

void setup() {
pinMode(SDI, OUTPUT);
pinMode(CKI, OUTPUT);

//Clear out the array
for(int x = 0 ; x < STRIP_LENGTH ; x++)
strip_colors[x] = 0;

randomSeed(analogRead(0));

Serial.begin(9600); // Possible debugging

}

void loop() {
addRandom();
post_frame(); //Push the current color frame to the strip
delay(1000); // wait for a second

}

//Throws random colors down the strip array
void addRandom(void) {
int x;

//First, shuffle all the current colors down one spot on the strip
for(x = (STRIP_LENGTH - 1) ; x > 0 ; x--)
strip_colors[x] = strip_colors[x - 1];

//Now form a new RGB color
long new_color = 0;
new_color = random(0xffffff) & 0x0f0f0f; // Give a random colour that's not too bright
strip_colors[0] = new_color; //Add the new random color to the strip
}

//Takes the current strip color array and pushes it out
void post_frame (void) {
//Each LED requires 24 bits of data
//MSB: R7, R6, R5..., G7, G6..., B7, B6... B0
//Once the 24 bits have been delivered, the IC immediately relays these bits to its neighbor
//Pulling the clock low for 500us or more causes the IC to post the data.

for(int LED_number = 0 ; LED_number < STRIP_LENGTH ; LED_number++) {
long this_led_color = strip_colors[LED_number]; //24 bits of color data

for(byte color_bit = 23 ; color_bit != 255 ; color_bit--) {
//Feed color bit 23 first (red data MSB)

digitalWrite(CKI, LOW); //Only change data when clock is low

long mask = 1L << color_bit;
//The 1'L' forces the 1 to start as a 32 bit number, otherwise it defaults to 16-bit.

if(this_led_color & mask)
digitalWrite(SDI, HIGH);
else
digitalWrite(SDI, LOW);

digitalWrite(CKI, HIGH); //Data is latched when clock goes high
}
}

//Pull clock low to put strip into reset/post mode
digitalWrite(CKI, LOW);
delayMicroseconds(500); //Wait for 500us to go into reset
}

Comments are closed.