0

RGB LED Strip (LPD8806) Arduino Speed
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

RGB LED Strip (LPD8806) Arduino Speed

by CraigKC on Wed Sep 14, 2011 2:29 pm

I received my LPD8806-based LED strip last night and was initially disappointed at the frame rate possible with a 16mhz Arduino using the library supplied by Adafruit. I did some poking around and updated the LPD8806.c file to use direct port manipulation for the SPI data push which, as expected, increased the frame rate drastically. There's plenty to be read all over about digitalWrite() being very slow but I thought I'd just post my code changes to help anyone else that wasn't as familiar with the Arduino/Atmega168/328 to do this themselves.

A couple things to note (basically just direct port manipulation warnings):

-- This will likely only work as-is with the Atmega168/328. The registers are different on different microcontrollers. If you're using something else make sure and research your registers first.

-- This requires you to know your CI/DI pins at compile-time as they are then hard-coded (I used the same pins as the Adafruit tutorial for this code, 2=data, 3=clock)

-- Be careful if you modify this to not mess with digital pins 0 & 1. They're your serial pins and can be a big headache reprogramming your Arduino if you accidentally change their I/O mode.

Just replace the write8() function in the LPD8806.c file with this code for a substantially faster framerate (old digitalWrite code left commented out for readability). Also, if anyone else has any similar tricks to better push this strip throw them in here. I'd love to hear them as I'm working on prototyping a fair sized project using these.

Code: Select all | TOGGLE FULL SIZE
//Hard-coded direct port manipulation assuming DI=pin2 and CI=pin3
void LPD8806::write8(uint8_t d)
{
   for (uint8_t i=0; i<8; i++)
   {
     if (d & _BV(7-i))
       //digitalWrite(dataPin, HIGH);
       PORTD |= B00000100; // sets data pin (2) HIGH leaving 0 & 1 alone
     else
       //digitalWrite(dataPin, LOW);
       PORTD &= B11111011; // sets data pin (2) LOW leaving 0 & 1 alone

     //Set clock pin (3) high then low (leaving 0 & 1 alone)
     //digitalWrite(clockPin, HIGH);
     PORTD |= B00001000;
     //digitalWrite(clockPin, LOW);
     PORTD &= B11110111;
    }
}
CraigKC
 
Posts: 8
Joined: Thu Aug 18, 2011 4:36 pm

Re: RGB LED Strip (LPD8806) Arduino Speed

by adafruit_support_bill on Wed Sep 14, 2011 2:45 pm

If you have not already, you may want to compare notes with these people:
http://forums.adafruit.com/viewtopic.php?f=47&t=22891
http://forums.adafruit.com/viewtopic.php?f=47&t=22858

adafruit_support_bill
 
Posts: 62973
Joined: Sat Feb 07, 2009 10:11 am

Re: RGB LED Strip (LPD8806) Arduino Speed

by CraigKC on Wed Sep 14, 2011 3:43 pm

Thanks! I did see the other LPD8806 related post but didn't follow the link to the WS2801 that, as it turns out, was indeed the exact same concept I implemented here.

Great work on the supplied code -- it helped me get the strips running literally in minutes when they arrived yesterday. Especially after making the speed improvement I couldn't be more happy with this entire setup!
CraigKC
 
Posts: 8
Joined: Thu Aug 18, 2011 4:36 pm

Re: RGB LED Strip (LPD8806) Arduino Speed

by adafruit_support_bill on Wed Sep 14, 2011 4:35 pm

Great! Thanks for posting your results :D

adafruit_support_bill
 
Posts: 62973
Joined: Sat Feb 07, 2009 10:11 am

Re: RGB LED Strip (LPD8806) Arduino Speed

by cjbaar on Sat Sep 17, 2011 12:50 pm

FYI... I have pieced together a native SPI version of this library with the help of others' comments here.
http://forums.adafruit.com/viewtopic.php?f=47&t=22982

cjbaar
 
Posts: 73
Joined: Fri Aug 26, 2011 5:58 pm

Please be positive and constructive with your questions and comments.