LDP8806 hardware SPI on Teensy 2.0?

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
isdale
 
Posts: 80
Joined: Wed Dec 15, 2010 12:54 am

LDP8806 hardware SPI on Teensy 2.0?

Post by isdale »

I am trying to build a rather complex LED strip beast with 15m of LDP8806 controlled by 3 PJRC Teensy 2.0s with interactive input coming from a FredBoard via EZ-Transfer. Given the length of LED, as well as need to do serial receive from UI controller, I was hoping to use the Hardware SPI. However, it does not seem to work on the Teensy 2.0.

I have been using the AdvancedLedBeltKit.pde included in AdaFruit library as an example. I note the latest version has some #ifdef USB_SERIAL at the beginning with a comment about teensy...

Code: Select all

#if defined(USB_SERIAL) || defined(USB_SERIAL_ADAFRUIT)
// this is for teensyduino support
int dataPin = 2;
int clockPin = 1;
#else 
// these are the pins we use for the LED belt kit using
// the Leonardo pinouts
int dataPin = 16;
int clockPin = 15;
#endif
Down further it says...

Code: Select all

// Instantiate LED strip; arguments are the total number of pixels in strip,
// the data pin number and clock pin number:
LPD8806 strip = LPD8806(numPixels, dataPin, clockPin);

// You can also use hardware SPI for ultra-fast writes by omitting the data
// and clock pin arguments.  This is faster, but the data and clock are then
// fixed to very specific pin numbers: on Arduino 168/328, data = pin 11,
// clock = pin 13.  On Mega, data = pin 51, clock = pin 52.
//LPD8806 strip = LPD8806(numPixels);
In preparing to use the hardware SPI, I wired the strip up to use Data =>11 Clock =>13
This works just fine and dandy on Teensy if I urn using the software SPI (first LDP9906 instantiation)
However if I switch the comment-out to use the hardware SPI, it no longer functions.
Why?
And why is the #fidef USB_SERIAL talking about Teensy and using pins 2/3?

I am hoping to use the Teensy UART to do comms with Fred board using EZ-Transfer
This worked ok with the slower LDP8806 Belt demo code and software SPI, when I showed it at TEDxMaui.

Hoping for some quick fixes!

User avatar
pburgess
 
Posts: 4161
Joined: Sun Oct 26, 2008 2:29 am

Re: LDP8806 hardware SPI on Teensy 2.0?

Post by pburgess »

Hi Jerry,

For Teensy using hardware SPI, using pin B1 for clock and B2 for data. The comments are referring to a normal Arduino board (e.g. Uno).

User avatar
isdale
 
Posts: 80
Joined: Wed Dec 15, 2010 12:54 am

Re: LDP8806 hardware SPI on Teensy 2.0?

Post by isdale »

Thanks - Paul got back to me in email on this.
Documentation on SPI for Teensy is a bit thin. And code comments in AdvancedBeltKit could use some upgrade too.
There is a comment in the ABK about teensy, but it relates to setting the Software pins.
Adding a few words that the Teensy puts hardware SPI Data/Clock (aka SCLK MOSI MISO) on different pins would help those who come along next.

I got it working now, and EZ-Transfer from the Fred Board sorta works. It seems to miss some packets. Maybe I need to up the speed a bit? I was using 9600baud. Oh well thats a whole other thread... leading to I2C, etc.

silverline
 
Posts: 17
Joined: Thu Dec 08, 2011 10:36 pm

Re: LDP8806 hardware SPI on Teensy 2.0?

Post by silverline »

i read somewhere that teensy doesn't attend to baudrate, it just uses 192000

how fast was your framerate?
Last edited by silverline on Tue Feb 14, 2012 4:36 am, edited 1 time in total.

User avatar
isdale
 
Posts: 80
Joined: Wed Dec 15, 2010 12:54 am

Re: LDP8806 hardware SPI on Teensy 2.0?

Post by isdale »

My rig is small compared to yours. I have 5 teensy, each running a strip with between 60-100 LEDs.
I found that EasyTransfer was not compatible with the advancedBelt version of the example code.
I think it is something between the serial read and Timer1 blocking but have not dug in further
I did find that the advanced effects work ok if you invoke the callback() function in loop()

My rig now does the EasyTransfer on the timer and AdvancedEffects from loop()
giving me nice interactive effects.

silverline
 
Posts: 17
Joined: Thu Dec 08, 2011 10:36 pm

Re: LDP8806 hardware SPI on Teensy 2.0?

Post by silverline »

try this.

edit: o i now see u dont want to use a pc

User avatar
paulstoffregen
 
Posts: 444
Joined: Sun Oct 11, 2009 11:23 am

Re: LDP8806 hardware SPI on Teensy 2.0?

Post by paulstoffregen »

silverline wrote:i read somewhere that teensy doesn't attend to baudrate, it just uses 192000
Teensy actually always using 12 Mbit/sec native USB speed. However, USB has built-in flow control, so the actual speed depends on how the PC sends and how Teensy receives.

Currently, Teensyduino's Serial object only provides Serial.read() and Serial.available() (the same as all other Arduino boards). By reading 1 byte at a time, the Teensy is only able to sustain about 120 to 200 kbytes/sec speed, and that's if it's not doing any other work! The 16 MHz CPU just isn't fast enough to process the full USB speed when calling a function for each individual byte.

In future versions of Teensyduino, I plan to greatly optimize Serial.readBytes(), which is a new function defined by Arduino 1.0. If you want maximum speed for future versions, I'd highly recommend considering switching to Serial.readBytes(). You can set the timeout parameter to 0 make it work in non-blocking mode if necessary.

Good bandwidth depends on the PC is sending efficiently. You might think a multi-GHz, multi-core, 64 bit processor with gigabytes of RAM at its disposal would not be the limiting factor. But often the PC-side software is what ultimately limits the effective speed.

On Macs, the operating system does a good job of making USB bandwidth get used efficiently, even if the software has poor coding. One Linux and Windows, each write to the operating system turns into a transaction to the USB controller. If the application writes 1 byte at a time, tiny and horribly inefficient 1-byte USB packets will travel across the wire.

Windows also has a terrible limitation. It only allows a single "transaction" per 1 ms USB frame. So if the PC software writes 1 byte at a time, the maximum possible speed will always be 1 kbyte/sec! Many programs written with Processing work this way, and are unable to fully utilize the speed of 57600 baud serial. However, if the application writes a large chunk of data, the host controller will automatically break it into 64 byte packets, and the last bit will go into a less-than-64-byte packet (or a zero length packet is send if an exact multiple of 64 bytes is sent). Mac and Linux don't have this 1-transaction-per-frame limitation.

So the effective speed depends on a LOT of factors, mostly efficient programming on both sides.

User avatar
pburgess
 
Posts: 4161
Joined: Sun Oct 26, 2008 2:29 am

Re: LDP8806 hardware SPI on Teensy 2.0?

Post by pburgess »

paulstoffregen wrote:In future versions of Teensyduino, I plan to greatly optimize Serial.readBytes()
Oh, heck yeah! Do keep us apprised of your progress.

I did some benchmark tests a while back when folks were clamoring for a way to control an obscene metric ton of LPD8806 LED strip (tethered to a PC). Using Teensy and Serial.read(), this maxed out at about 2.5 Mbps (on Mac)...which is quite decent, could potentially drive about 3,000 RGB LEDs at 30 Hz...but folks were talking about even larger installations. Meanwhile, FTDI bitbang mode could push close to 8 Mbps (10K LEDs)…but, looking at the prerequisite software setup and some of the driver issues, I did not like what I saw...absolute tech support nightmare, and shelved the idea for the time being. So if you manage to narrow this gap even part way, that'll be great news for people who push a lot of pixels!

User avatar
paulstoffregen
 
Posts: 444
Joined: Sun Oct 11, 2009 11:23 am

Re: LDP8806 hardware SPI on Teensy 2.0?

Post by paulstoffregen »

Phillip, please email me directly - paul at pjrc dot com

I'd like to look into this optimization, but it doesn't make sense to attempt in isolation. To achieve best throughput, a specific example has to be developed and tested together with the host-side software. I looked at the LDP8806 library, and all the examples are autonomous. None involve using Serial at all. I'm not very familiar with these LEDs and what software people are using on the PC/Mac side. To make this really happen, let's chat about this in email, if you're interested.

Arduino 1.0.1 is scheduled in only a couple weeks, and of course I've been planning but holding off a new release of Teensyduino until 1.0.1 comes out. If we hurry, a massively optimized receive path might be possible for this next release....

mhenstell
 
Posts: 11
Joined: Thu Dec 25, 2008 5:00 pm

Re: LDP8806 hardware SPI on Teensy 2.0?

Post by mhenstell »

pburgess wrote:
paulstoffregen wrote:In future versions of Teensyduino, I plan to greatly optimize Serial.readBytes()
Using Teensy and Serial.read(), this maxed out at about 2.5 Mbps (on Mac)...which is quite decent, could potentially drive about 3,000 RGB LEDs at 30 Hz...but folks were talking about even larger installations.
Sorry for the late post, but as one of those folks building an even larger installation, would you mind sharing the teensy sketch you were using to pump data from USB out to SPI, if you still have it? :D

User avatar
paulstoffregen
 
Posts: 444
Joined: Sun Oct 11, 2009 11:23 am

Re: LDP8806 hardware SPI on Teensy 2.0?

Post by paulstoffregen »

mhenstell wrote:would you mind sharing the teensy sketch you were using to pump data from USB out to SPI, if you still have it? :D
Sure, why not?

Well, actually, one good reason would be because nobody has written corresponding code on the Processing side, to convert a video stream to the bits-packed-in-bytes format this needs. Philip intends to do so at some point, but he's been very busy and unable to work on this. He wanted to avoid a problematic tech support situation. Since then (I wrote this on March 2, 2012), several people have expressed interest and I've emailed the code, but never posted it publicly anywhere.

Well, maybe it's worthwhile to just make it available here? It's sort a catch-22 situation, not releasing publicly because nobody has written the host-side code, but few (if any) people are working on the host side code because the device side isn't publicly released.

One caveat is this code requires reformatting the LED data. It drives 8 strips, not just one. So you need to divide the image into 8 bit streams, and then pack them into bytes. Each byte you send causes 1 bit to shift out to each of the 8 LED strips. This code also requires you transmit data in multiples of 64 bytes. If your strips plus the end-of-frame latch stuff works out to be less than a multiple of 64, you must pad the end with zeros (or anything you like) to make the total write a multiple of 64. Of course, don't just send 64 bytes at a time, write the largest mulitple-of-64 block you can, so the USB host controller and drivers handle it efficiently (especially on Windows which has some special driver limitations).

So, with all these issues in mind, here it is.
Serial2Parallel.txt
(9.08 KiB) Downloaded 1283 times
This forum wouldn't let me upload a .pde or .ino extension, so I changed it to .txt. Changing the extension back ought to be the least of your worries. The special organization of the bitstreams will require some significant coding. Until somebody does that, this code is pretty much worthless, other than proving 1 Mbyte/sec speed is indeed possible.

This code is extremely fast. It's able to keep up with full speed (12 Mbit/sec) USB. In fact, in the 3 #defines, you can usually add 3 more nop instructions for even slower waveform output and still (usually) keep up with data at full USB speed. The main speed limitations are scheduling limitation in the USB driver code (especially on Windows) and bandwidth taken away by other USB devices.

On the other USB devices issue, on thing that helps is connecting Teensy through a USB hub. Hubs have a "transaction translator" (TT) which converts from 12 Mbit/sec to 480 Mbit/sec in crafty ways. Some hubs have only a single TT, so they only optimize bandwidth to 1 device. Other hubs are "multi-TT", where they optimize all connected devices. On Linux, you can use "lsusb -v" and look through the long list for you hub to check which type it is.

Good luck, and please, if you redistribute this code (as its open source license allows), I would like to personally request you do so only together with a well documented example that sends data in the special format it requires.

mhenstell
 
Posts: 11
Joined: Thu Dec 25, 2008 5:00 pm

Re: LDP8806 hardware SPI on Teensy 2.0?

Post by mhenstell »

You are a god. I was up until 2am trying to get this to work using serial read and writing that straight to PORTD and getting nowhere. If I can get this working, I'll be sure to post back with our finished code repo and project posts. Thank you!

mhenstell
 
Posts: 11
Joined: Thu Dec 25, 2008 5:00 pm

Re: LDP8806 hardware SPI on Teensy 2.0?

Post by mhenstell »

Sorry for the late reply, we used your code as a starting point for our project, and it works fabulously. It's a work in progress, so it's not quite finished or well documented yet, but here it is for anyone who needs it.

https://github.com/hackrockcity/domeFirmware

Repo contains the teensy firmware, python host, c++ host (same as python but much faster), and the custom boards we designed.

More info available here:
http://hackrockcity.org/post/2436304242 ... red-on-the
http://wiki.hackrockcity.org/DomeStar

User avatar
ivo.knutsel
 
Posts: 2
Joined: Tue Oct 02, 2012 4:10 pm

Re: LDP8806 hardware SPI on Teensy 2.0?

Post by ivo.knutsel »

I have this code working and written a blog post about it :

http://www.knutsel.org/2012/10/08/drivi ... ed-strips/

Thanks, Ivo

Locked
Please be positive and constructive with your questions and comments.

Return to “Glowy things (LCD, LED, TFT, EL) purchased at Adafruit”