0

New High-Speed SPI Library for LPD8806 LED Strips
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Re: New High-Speed SPI Library for LPD8806 LED Strips

by sparr on Mon Oct 24, 2011 2:29 pm

Thank you for writing this! I had planned to try doing this myself when I ordered my LED strips and was happily surprised to find that you'd already done the heavy lifting.

I haven't had a chance to time it yet, but I believe this change will speed up the code. It lets serial output happen in the background while other code is running and only delays if the last write hasn't finished by the time the next write starts:
Code: Select all | TOGGLE FULL SIZE
SPDR = 0x00;
void LPD8806::write8(uint8_t d) {
   while (!(SPSR & (1<<SPIF))) {};
   SPDR = d & 0xff;
}


Also, I made this addition which seemed obvious to me:
Code: Select all | TOGGLE FULL SIZE
uint32_t LPD8806::getPixelColor(uint16_t n) {
    return pixels[n];
}


I haven't really USED github before. Is there a better way for me to make suggestions like this through the site with a fork or a patch or something?

Also, just to throw it out there, here's my addition to Wheel() so that I can specify a brightness (0-255) for the color. brightness=127 is supposed to give the same results as the original wheel, 255 gives white, and 0 gives black. It's got some off-by-one errors that I haven't charted out yet.
Code: Select all | TOGGLE FULL SIZE
  if(bright>127) {
   r=r+(127-r)*(bright-128)/128;
   g=g+(127-g)*(bright-128)/128;
   b=b+(127-b)*(bright-128)/128;
  } else {
   r=r*(bright)/128;
   g=g*(bright)/128;
   b=b*(bright)/128;
  }
sparr
 
Posts: 196
Joined: Tue Nov 04, 2008 5:21 pm

Re: New High-Speed SPI Library for LPD8806 LED Strips

by cjbaar on Mon Oct 24, 2011 4:47 pm

I haven't had a chance to time it yet, but I believe this change will speed up the code. It lets serial output happen in the background while other code is running and only delays if the last write hasn't finished by the time the next write starts:

What I had is essentially taken directly from the Arduino development kit library for SPI. I am not sure what effect moving the wait statement would have, but I'd be interested if you time the difference. Either way, it's still a while loop that waits for a condition, so I don't the function will return any quicker.

Also, I made this addition which seemed obvious to me:

A good idea.

I haven't really USED github before. Is there a better way for me to make suggestions like this through the site with a fork or a patch or something?

I am new to it as well, but I basically created a fork of the original Adafruit project. You have to subscribe to the fork, then upload the edited code. It's a few steps, but their tutorials are very well done.

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

Re: New High-Speed SPI Library for LPD8806 LED Strips

by adafruit on Mon Oct 24, 2011 6:51 pm

OK I dont want to disrupt this SPI party but I updated the LPD8806 code to have higher-speed updating using pin-flexible SPI

https://github.com/adafruit/LPD8806

it *also* supports hardware SPI, by calling
LPD8806 strip = LPD8806(32);
without a data/clock pin

please try this out and see if it works well enough for your applications. we could write a 32 LED strip in about 8ms with the pin-flexible code, and 3.5ms with the hardware SPI code

we'd like to have just this version instead of two, since it makes support a little easier :)

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: New High-Speed SPI Library for LPD8806 LED Strips

by sparr on Mon Oct 24, 2011 8:24 pm

cjbaar wrote:I am not sure what effect moving the wait statement would have, but I'd be interested if you time the difference. Either way, it's still a while loop that waits for a condition, so I don't the function will return any quicker.

The trick is that SPI transfer can take place in the background while other unrelated code is running. Your code said "start to send, wait for send to finish, return from loop, do other stuff, repeat". My code says "wait for previous send to finish, start to send, return from loop, do other stuff, repeat". In my version, the previous send will have had extra "free" time to finish while our code was executing elsewhere. I'm going to re-base my improvements against the new adafruit library and then do some timing tests.
sparr
 
Posts: 196
Joined: Tue Nov 04, 2008 5:21 pm

Re: New High-Speed SPI Library for LPD8806 LED Strips

by cjbaar on Tue Oct 25, 2011 2:49 pm

Thanks, Ada. I agree it's easier to have one library... however, I still can't get enough speed out of the new one you posted, even using the hardware SPI. I have done testing against each version. Below are the average update times for a single call to strip.show():
Code: Select all | TOGGLE FULL SIZE
library             32px      160px
-------------    -------    -------
adafruit/flex    10.93ms    42.20ms
adafruit/SPI      6.27ms    19.04ms
cjbaar/SPI         2.24ms     3.08ms


As you can see, the longer the strip, the more efficient the original SPI library becomes. On a 32-LED strip, it is around 3x faster, but on a 160-LED strip, it is 6x faster. I think the biggest difference is due to the fact that you are still flushing an extreme amount of zeroes on each call. You're sending what appear to be 32 zeroes before the data stream (SPI lib is sending 4), and up to 960 zeroes after (SPI lib is sending another 4). In effect, this is tripling the amount of data being sent for each call.

Unless you've seen problems with updating, I haven't found a reason to spend the extra time on all those zeroes. I have seen no problems using only a handful of zeroes to latch the data.

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

Re: New High-Speed SPI Library for LPD8806 LED Strips

by adafruit on Tue Oct 25, 2011 5:08 pm

thats a good point, unfortunately, lacking the protocol datasheet we have no idea how many zeros are necessary to latch the data. the controller we reverse engineered sent out as many as we do, but who knows if that was designed right? :)

we do suspect you need to send out a couple to start - do you want to see if you can figure out how many zeros you need to latch a 5m strip?

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: New High-Speed SPI Library for LPD8806 LED Strips

by cjbaar on Tue Oct 25, 2011 6:32 pm

I've been using just 4 zeroes to start and 4 zeroes to latch on a 160-LED (5m) strip, and I don't notice any problems. I would love to hear from others who have been using the SPI library on a long strip to know if they've seen any issues.

FYI... when I say 4 zeroes, I technically mean 4 bytes worth. I am calling the write8(0) function 4 times. A call to write8(0) is functionally equivalent to SPI.transfer(0).

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

Re: New High-Speed SPI Library for LPD8806 LED Strips

by adafruit on Wed Oct 26, 2011 11:15 am

OK we updated the code, please try the latest pull! it should be ultra fast now :) if its OK we will simplify it by removing the special 'writezeros' function

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: New High-Speed SPI Library for LPD8806 LED Strips

by smeggles on Thu Oct 27, 2011 11:01 am

I tried to port this over to Netduino Plus, but was unfortunately unable to get the lights to change faster than about 7 FPS (160 LEDs). Is this a limitation of the .NET MicroFramework, their implementation of SPI, or do you think I just did something wrong?

To try to speed things up, instead of writing pixel by pixel, I write the whole buffer at once, and that got me to the ~7 FPS.

Any thoughts? I'm not at home right now, but I can post the code when I get there.
smeggles
 
Posts: 3
Joined: Thu Oct 27, 2011 10:50 am

Re: New High-Speed SPI Library for LPD8806 LED Strips

by adafruit on Thu Oct 27, 2011 1:32 pm

there is a high speed netduino port in the works, watch the blog in the next week or two :)

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: New High-Speed SPI Library for LPD8806 LED Strips

by smeggles on Thu Oct 27, 2011 1:44 pm

I am developing something for these lights that I need by 10/29 (Saturday!). Is there any way you could share with me any insight you have so that I can adapt it for my own use for the time being? You can PM me or post here, it would be _GREATLY_ appreciated.

Thanks.
smeggles
 
Posts: 3
Joined: Thu Oct 27, 2011 10:50 am

Re: New High-Speed SPI Library for LPD8806 LED Strips

by adafruit on Thu Oct 27, 2011 3:47 pm

we didnt do the work, fabien at codeplex did - sorry we dont know anything else

http://netduinohelpers.codeplex.com/

might have working code!

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: New High-Speed SPI Library for LPD8806 LED Strips

by smeggles on Thu Oct 27, 2011 3:54 pm

Great, thanks for the heads up! I will post back more information if I get a faster working version.
smeggles
 
Posts: 3
Joined: Thu Oct 27, 2011 10:50 am

Re: New High-Speed SPI Library for LPD8806 LED Strips

by sparr on Fri Oct 28, 2011 4:08 am

For adafruit's new library...

Code: Select all | TOGGLE FULL SIZE
void LPD8806::writezeros(uint16_t n) {
  if (hardwareSPI) {
    for (uint16_t i=0; i<8*n; i++)
      SPI.transfer(0);
    return;
  }
[trim]
}


SPI.transfer(0) already sends a full byte of zeroes, so why the 8*n?
sparr
 
Posts: 196
Joined: Tue Nov 04, 2008 5:21 pm

Re: New High-Speed SPI Library for LPD8806 LED Strips

by pburgess on Fri Oct 28, 2011 7:13 pm

sparr: Oops! Fixed, thanks. Also fixed some probable latch issues with longer strands while there. Let us know if you encounter any strangeness.

pburgess
 
Posts: 4020
Joined: Sun Oct 26, 2008 2:29 am

Please be positive and constructive with your questions and comments.