I'm working on a fairly simple sketch and need some help. I'm driving a 32 LED PWM RGB light strip from Sparkfun (RGB LED Strip - 32 LED/m Addressable - 1m - COM-10312 - SparkFun Electronics) My brother wrote some code up for me, I played with it some but it isn't working. I have a feeling Pins/States have been over defined or defined incorrectly. It's the leftState vs leftPin, rightState vs rightPin etc. that I can't figure..Please Help! I'd be glad to pay. JOSH
Complete code added 23 DEC 2011
/*
Refer to Nathan Seidles notes from original LED sketch at end
2-pin Red+Black = 5V/GND
Green = CKI = Digital Pin 5
Red = SDI = Digital Pin 2
Make sure you use pins with ----------> going away not towards!
Acc sensor is var analog resistor on pin 7
Left Turn is switched to pin 8
Right Turn is switched to pin 9
Hazards are pins 8 and 9 both closed
Left Turn is switched to pin 10
Left Turn is switched to pin 11
*/
#include <MsTimer2.h>
// Switch on LED on pin 13 each second.....doesn't work
long loopCount = 0;
long sumMe = 0;
long lastAve = 0;
int sensorPin = A7;
int accel = 0;
long trnSigTim = 0;
boolean trnState = false;
int SDI = 2; //Red wire (not the red 5V wire!)
int CKI = 5; //Green wire
int ledPin = 13; //On board LED
long colBrk = 0xFF0000;
long colRev = 0xFFFFFF;
long colTrn = 0xFFFFFF;
long colOFF = 0x000000;
int LeftPin = 8; // Left is connected to pin 8
int RightPin = 9; // Right is connected to pin 9
int RevPin = 10; // Reverse is connected to pin 10
int BrakePin = 11; // Brake is connected to pin 11
#define STRIP_LENGTH 32 //32 LEDs on this strip
long strip_colors[STRIP_LENGTH];
void setup() {
pinMode(SDI, OUTPUT);
pinMode(CKI, OUTPUT);
pinMode(ledPin, OUTPUT); // blinking light function pin 13.. why?
pinMode(LeftPin, INPUT); // Set pin 8 as left turn input
pinMode(RightPin, INPUT); // Set pin 9 as right turn input
pinMode(RevPin, INPUT); // Set pin 10 as reverse input
pinMode(BrakePin, INPUT); // Set pin 11 as center brake switch input
//Clear out the array
for(int x = 0 ; x < STRIP_LENGTH ; x++)
strip_colors[x] = 0;
randomSeed(analogRead(0));
Serial.begin(9600);
MsTimer2::set(40, flash); // 5ms period
MsTimer2::start();
trnSigTim = millis();
}
void flash() {
//Calculate Acceleration
long aveSpeed = 0;
aveSpeed = sumMe/loopCount; //get avereage value over this iteration
accel = aveSpeed-lastAve; //dv/dt
lastAve = aveSpeed;
aveSpeed = 0;
sumMe = 0;
loopCount = 0;
//manage left and right flashers
}
void loop() {
int sensorValue;
int bLevel;
bLevel = map(accel, 0, 100, 0, 11);
leftState=digitalRead(leftPin);
rightState=digitalRead(rightPin);
brakeState=digitalRead(brakePin);
revState=digitalRead(revPin);
refreshStrip(bLevel, leftState, rightState, brakeState, revState);
post_frame(); //Push the current color frame to the strip
sensorValue = analogRead(sensorPin);
Serial.println(bLevel);
sumMe += sensorValue;
loopCount +=1;
if ((millis() - trnSigTim) >= 500){
trnState = !trnState;
trnSigTim = millis();
}
}
void refreshStrip(int accLev, boolean BrakePin, boolean LeftPin, boolean RightPin, boolean RevPin){
//right 12, if the right turn signal is on and in the blink cycle
//then turn it red
//otherwise, if it is reversing turn it white
//otherwise, put the brake level in
//sanity check on accLev
if (accLev > 11){
accLev = 11;
}else if (accLev < 0){
accLev = 0;
}
//left segment logic
if (LeftPin){ //is the left bit on
postSeg(0, 11, colOFF); //turn the left signal segment OFF
if(trnState && LeftPin){ //but if it is our time to blink turn it back on
postSeg(0, 11, colTrn);
}
}else if(RevPin) {
postSeg(0, 11, colRev);
}else{ //we aren't blinking and we aren't reversing, display the fade strip for this segment
postSeg(0, 11, colOFF);
postSeg(11-accLev, 11, colBrk);
}
//right logic (should be identical)
//left segment logic
if (RightPin){
postSeg(21, 32, colOFF);
if(trnState && RightPin){
postSeg(21, 32, colTrn);
}
}else if(RevPin) {
postSeg(21, 32, colRev);
}else{
postSeg(21, 32, colOFF);
postSeg(21, 21+accLev, colBrk);
}
}
//set a segment of the LED state array to a particular color
//all leds in this segment of the strip will be either blanked
//or set to the specified color
//startLED is the first LED of the segment
//endLED is the last LED of the segment to be lit
//color is the color to use
//This functions name is sort of a misnomer because it doesn't actually post (send)
//anything to the LED strip, it simply prepares a segment of the array that will
//presumably be sent to the post_frame function later
void postSeg(int startLED, int endLED, long color){
int x;
for(x = startLED; x < endLED ; x++){
strip_colors[x] = color;
}
}
//this last function is sort of a black box, I didn't modify it
//I just modify strip_colors and call this function when I am ready to transfer
//those colors into the LEDs
//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
}
/*
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
*/