basp
Posts: 7
Joined: Thu May 07, 2015 10:31 am

Fastest way of writing to an SPI device

Mon May 11, 2015 7:17 am

I have an SPI device (an addressable LED strip) that I'm controlling via the Pi. From what I've read here and there, the maximum frequency for the SPI device is the CPU's clock rate, so in the case of the Pi 2, 900MHz.

All the samples provided for Windows 10 update SPI devices by setting a DispatcherTimer and writing to the SPI device in the Tick event handler. This works fine, but a DispatcherTimer can only run so fast, dealing with the UI thread and such. I think I can tell the difference between when the Interval is set at half a millisecond and when between it's a millisecond, but that's still far from 900MHz, of course, and since the DispatcherTimer is not a high-precision timer I doubt I'd be able to squeeze more out of it.

How would one write to an SPI device as fast as possible in a Universal Windows App? Is a Timer the best way or is there some other way? Spawning a separate thread and running a while() loop there? Any other way?

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: Fastest way of writing to an SPI device

Mon May 11, 2015 7:30 am

What kind of addressable LED strip? ... light board, 7 segment display, binary counter... what... commercial, your design?

The datasheet is where you start. The mcu (pi in this case, but there are others that are better for this purpose) provides the clock, yes, but the device is what determines the speed. Often the mcu can provide a faster clock than the device can tolerate... not always. Read the datasheet; if you designed it, well, the limiting factors are the chips you used to design the serial to parallel interface. Are the shift registers built-in or are they add-on devices ?

Timers are usually used to divide the master clock into something more reasonable. Sometimes its better to have a dedicated mcu handle the led board , and then talk to that from the RPi using uart. You might try looking at the pyboard and micro python. Have you considered using an Atmega mcu?
marcus
:ugeek:

basp
Posts: 7
Joined: Thu May 07, 2015 10:31 am

Re: Fastest way of writing to an SPI device

Mon May 11, 2015 7:56 am

The LED strip isn't the point, this applies to any SPI device connected to the Pi. Suppose a device has a clock speed up to 20MHz. How would I write to the device at that rate, or at least as fast as possible? DispatcherTimer is never going to reach 20MHz or even 10MHz, but maybe something else (without using a separate microcontroller board) will be able to reach those kinds of speeds in a Universal App?

User avatar
mikronauts
Posts: 2722
Joined: Sat Jan 05, 2013 7:28 pm
Contact: Website

Re: Fastest way of writing to an SPI device

Mon May 11, 2015 2:44 pm

The LED string IS the point, as the protocol matters!

For example, the WS2812 has very precise timing requirements that are a pain to meet with SPI (especially without being able to set the SPI clock to precise, high speed values), but relatively easy with a P8X32A (or other) microcontroller in assembly.

When you ask for help, and people who know more ask for data sheets or more specifics, provide the details they ask for - they are asking for a good reason, and know more than you, which is why they know the details are important.
basp wrote:The LED strip isn't the point, this applies to any SPI device connected to the Pi. Suppose a device has a clock speed up to 20MHz. How would I write to the device at that rate, or at least as fast as possible? DispatcherTimer is never going to reach 20MHz or even 10MHz, but maybe something else (without using a separate microcontroller board) will be able to reach those kinds of speeds in a Universal App?
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi

basp
Posts: 7
Joined: Thu May 07, 2015 10:31 am

Re: Fastest way of writing to an SPI device

Mon May 11, 2015 3:52 pm

I feel like I'm not getting my point across. I'm not asking "at what speed should I write to my LED strip", I'm asking "how do I achieve fast write speeds in .NET".

But alright: the LED strip has a clock rating of 20MHz. What's the best way of writing data to the spi device at 20MHz? A DispatcherTimer won't reach those kinds of speeds.
Last edited by basp on Mon May 11, 2015 3:59 pm, edited 1 time in total.

User avatar
mikronauts
Posts: 2722
Joined: Sat Jan 05, 2013 7:28 pm
Contact: Website

Re: Fastest way of writing to an SPI device

Mon May 11, 2015 3:58 pm

And you are deliberately ignoring questions asking what LED strip it is (its controller)

Try to set the SPI clock to 20MHz, then write in a tight loop from C (or use DMA), but that won't help you as depending on the clock configuration you will not necessarily get a 20MHz clock, and even if you do, if the strip requires timing like a WS2812 you will still likely have issues.

People cannot help you more without knowing what chips are used on the LED controller.

The MSFT guys will have to pipe in on how to set the SPI clock under Win10IoT
basp wrote:I feel like I'm not getting my point across, but alright: the LED strip has a clock rating of 20MHz. What's the best way of writing data to the spi device at 20MHz? A DispatcherTimer won't reach those kinds of speeds.
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: Fastest way of writing to an SPI device

Mon May 11, 2015 4:29 pm

basp wrote:I feel like I'm not getting my point across. I'm not asking "at what speed should I write to my LED strip", I'm asking "how do I achieve fast write speeds in .NET".
It seems that you do not understand spi. The 'write' as you put it happens (at whatever speed) at a lower level than (.NET) provides. But, the maximum speed is determined by the device you are writing to. As an example, I wrote some code (some call it bit banging) to write to a seven segment LED panel (8 digit) that uses two embedded 74hc595 shift registers. To know how fast I can write to the LED panel I need to know several things about the 74hc595 shift registers employed: minimum pulse width, maximum frequency (at what voltage, yes it matters), setup time, hold time, and several other factors. Also, as others will tell you, you probably want to avoid trying to be your own clock (bit banging) because for some devices the imprecise timing will cause you troubles. In my LED seven segment panels that is not an issue, and the 'bit banging' worked very well. But--and its a big butt-- my bit banging cannot force the 595(s) to accept the data 'faster' then they can accept it! --period. If you're doing WinIoT stuff, then you're going to have to get the Microsoft girls and boys opinion(s) for the best way to use their SPI library... but I would recommend you use their library (if you're doing WinIoT) rather than inventing your own clock...
marcus
:ugeek:

jtanner_msft
Posts: 105
Joined: Fri May 01, 2015 7:12 pm

Re: Fastest way of writing to an SPI device

Mon May 11, 2015 6:45 pm

While these might not address the full nuances of the speed / write question I did want to share a few samples that we have that involve an SPI display, and then another one that shows how to turn on / off an array of LEDs. Possibly from reviewing these samples you’ll get an answer to your questions about the speed of writes to these devices:

SPI Display: http://ms-iot.github.io/content/win10/s ... isplay.htm

Shift Register (LEDs) sample: http://ms-iot.github.io/content/win10/s ... Sample.htm

I hope that helps.
Jonathan Tanner | Microsoft | Windows 10 IoT Core Insider Preview Support | This posting is provided 'as is' with no warranties and confers no rights.

User avatar
joan
Posts: 14260
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Fastest way of writing to an SPI device

Mon May 11, 2015 7:04 pm

It's going to be running on the Pi. However the driver is implemented it will be using the Pi's SPI peripheral.

Assuming the core clock is 250MHz then two dividers bracket 20Mbps. A divider of 12 gives 20.83Mbps. A divider of 14 gives 17.86Mbps.

basp
Posts: 7
Joined: Thu May 07, 2015 10:31 am

Re: Fastest way of writing to an SPI device

Mon May 11, 2015 9:36 pm

It's an LPD8806 LED strip. The data sheet tells me the max speed is 20MHz. I'm using the winiot library. I've created an SpiDevice instance like they've shown in the WinIoT documentation, and set it to 20MHz.

Theoretically, I'd be able to change an LED's color 20,000,000 times a second, correct? I'd be able to do this if I could call SpiDevice.Write() 20,000,000 times a second, correct?

I can create a dispatchertimer, set it's interval to 1ms, and call SpiDevice.Write() in its Tick event handler. That way, the strip gets updated 1,000 times a second.

That's roughly as fast as a dispatcherytimer can go. I nerd something that allows me to call SpiDevice.Write 20,000,000 times a second. How do I achieve this?

User avatar
joan
Posts: 14260
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Fastest way of writing to an SPI device

Mon May 11, 2015 9:47 pm

basp wrote:It's an LPD8806 LED strip. The data sheet tells me the max speed is 20MHz. I'm using the winiot library. I've created an SpiDevice instance like they've shown in the WinIoT documentation, and set it to 20MHz.

Theoretically, I'd be able to change an LED's color 20,000,000 times a second, correct? I'd be able to do this if I could call SpiDevice.Write() 20,000,000 times a second, correct?
...
No. Look at the datasheet for the LED strip.
basp wrote: ...
I can create a dispatchertimer, set it's interval to 1ms, and call SpiDevice.Write() in its Tick event handler. That way, the strip gets updated 1,000 times a second.

That's roughly as fast as a dispatcherytimer can go. I nerd something that allows me to call SpiDevice.Write 20,000,000 times a second. How do I achieve this?
You can't.

User avatar
mikronauts
Posts: 2722
Joined: Sat Jan 05, 2013 7:28 pm
Contact: Website

Re: Fastest way of writing to an SPI device

Mon May 11, 2015 10:56 pm

Go read everything on Adafruits page.

http://www.adafruit.com/product/306

Do not skim. Read carefully.

Your posts make it very clear that you do NOT understand these LED's, SPI, spi speed, or the concept of one bit per clock for the data transfer.

You can find some source code at https://github.com/adafruit/LPD8806

People on this forum are glad to help beginners, however it behooves the beginners to actually listen to the questions asked, and respond with enough data so that they can be helped - instead of ignoring questions, and repeating pre-conceived notions formed without understanding the subject matter.

And notice that people tried to help you even though you were not helping us help you.
basp wrote:It's an LPD8806 LED strip. The data sheet tells me the max speed is 20MHz. I'm using the winiot library. I've created an SpiDevice instance like they've shown in the WinIoT documentation, and set it to 20MHz.

Theoretically, I'd be able to change an LED's color 20,000,000 times a second, correct? I'd be able to do this if I could call SpiDevice.Write() 20,000,000 times a second, correct?

I can create a dispatchertimer, set it's interval to 1ms, and call SpiDevice.Write() in its Tick event handler. That way, the strip gets updated 1,000 times a second.

That's roughly as fast as a dispatcherytimer can go. I nerd something that allows me to call SpiDevice.Write 20,000,000 times a second. How do I achieve this?
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi

basp
Posts: 7
Joined: Thu May 07, 2015 10:31 am

Re: Fastest way of writing to an SPI device

Wed May 13, 2015 11:45 am

Thanks mikronauts, but I read that product page before getting started on this. Unfortunately, it doesn't actually contain or link to a datasheet for the LPD8806 as they state on the page itself. I then found this LPD8806 datasheet elsewhere, and read it through as well.

I then found this tutorial on controlling an LPD8806 LED strip on the Adafruit wiki, and followed it using a Netduino rather than a Raspberry pi. It worked.

I then followed this sample project about controlling an SPI display with the Raspberry Pi 2. Using what I learned from that, I managed to recreate the LED-strip sample from the Adafruit wiki on the Raspberry Pi 2 instead of the Netduino.

After that, I decided to see what I could do myself and attempted to have the LED strip cycle through all color values at a fast rate. Defying all odds, I managed it, as seen here.

It's a mystery how I managed to achieve exactly the result I wanted without, as you say, understanding these LEDs or SPI, but here it is, somehow cycling away on my desk. I managed to do this by using SpiDevice.Write() to write a byte array containing color values to the LED strip as often as I possibly could, like I explained in previous posts here. My guess is that the SpiDevice class takes care of the subtler timing issues, and communication via SPI, so that you can more or less call SpiDevice.Write() whenever you want without dealing with all that stuff. Hence my original question: how can I call SpiDevice.Write() faster, if the only thing limiting me currently is the DispatcherTimer.

I'm aware that my knowledge of SPI is minimal at best, but I'm willing to wager that part of the problem in this thread can also be attributed to a lack of knowledge of the WinIoT SpiDevice class on the part of some of those participating in this discussion, or this whole issue wouldn't have come up. "Ignoring questions, and repeating pre-conceived notions formed without understanding the subject matter" apparently works both ways.

Meanwhile, my original question was "How would one write to an SPI device as fast as possible in a Universal Windows App?" For the sake of anyone finding this thread in the future, I'll provide the answer I've found elsewhere: create an endless loop on a different thread, and use System.Diagnostics.Stopwatch to time any calls to SpiDevice.Write(). It's not much faster than DispatcherTimer, but still noticeably so.

User avatar
joan
Posts: 14260
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Fastest way of writing to an SPI device

Wed May 13, 2015 11:59 am

If you had let us know the LED strip type in the first post you probably wouldn't have got the responses you did get. You are lucky in that the LED strip type you are using has example Pi software which can be copied and works with standard SPI.

User avatar
mikronauts
Posts: 2722
Joined: Sat Jan 05, 2013 7:28 pm
Contact: Website

Re: Fastest way of writing to an SPI device

Wed May 13, 2015 1:39 pm

basp wrote:Thanks mikronauts, but I read that product page before getting started on this. Unfortunately, it doesn't actually contain or link to a datasheet for the LPD8806 as they state on the page itself. I then found this LPD8806 datasheet elsewhere, and read it through as well.
I am glad that once you were provided with a link to a product page, which had a link to the data sheet, you were able to find another data sheet.
basp wrote: I then found this tutorial on controlling an LPD8806 LED strip on the Adafruit wiki, and followed it using a Netduino rather than a Raspberry pi. It worked.
Yes, Adafruit's product page also links to some Arduino source code for the LPD8806 LED strip.
basp wrote: I then followed this sample project about controlling an SPI display with the Raspberry Pi 2. Using what I learned from that, I managed to recreate the LED-strip sample from the Adafruit wiki on the Raspberry Pi 2 instead of the Netduino.
Good, we finally prodded you into doing some research for yourself.
basp wrote: After that, I decided to see what I could do myself and attempted to have the LED strip cycle through all color values at a fast rate. Defying all odds, I managed it, as seen here.
Nope, if you can adapt sample code from somewhere, you are not defying odds, as you don't really have to fully understand what is going on if the code ports easily.
basp wrote: It's a mystery how I managed to achieve exactly the result I wanted without, as you say, understanding these LEDs or SPI, but here it is, somehow cycling away on my desk. I managed to do this by using SpiDevice.Write() to write a byte array containing color values to the LED strip as often as I possibly could, like I explained in previous posts here. My guess is that the SpiDevice class takes care of the subtler timing issues, and communication via SPI, so that you can more or less call SpiDevice.Write() whenever you want without dealing with all that stuff. Hence my original question: how can I call SpiDevice.Write() faster, if the only thing limiting me currently is the DispatcherTimer.
You proved you did not understand SPI, bit rates etc in your earlier post where you wrote:

"Theoretically, I'd be able to change an LED's color 20,000,000 times a second, correct? I'd be able to do this if I could call SpiDevice.Write() 20,000,000 times a second, correct?"

My response was:

"Your posts make it very clear that you do NOT understand these LED's, SPI, spi speed, or the concept of one bit per clock for the data transfer."

This was due to the following:

- 20Mhz, is one bit per clock, you cannot update RGB values with a single bit. You CANNOT change an LED's color per clock. With 24 bit RGB data you need at least 24 clock (you should have known this)

- Calling SpiDevWrite() 20,000,000 times per second is nuts, and likely not even possible. It sends at least eight bits per call, so to call it 20M times would send 160,000,000 bits. To change a single LED 20M times per second, at just 24 bits per led (ignoring overhead etc) would need 480,000,000Hz clock.

- if you have more than one LED on the strip, multiply 480,000,000Hz by number of LED's to get how high a clock you would need to update 20M times (ignoring overhead)

This is why I wrote what I did, and why I knew you did not understand any of this.

What was bothering me was that you were not even trying to understand.
basp wrote: I'm aware that my knowledge of SPI is minimal at best, but I'm willing to wager that part of the problem in this thread can also be attributed to a lack of knowledge of the WinIoT SpiDevice class on the part of some of those participating in this discussion, or this whole issue wouldn't have come up. "Ignoring questions, and repeating pre-conceived notions formed without understanding the subject matter" apparently works both ways.
No. I was trying to prod you into getting the information needed to help you (data sheet etc).

WinIoT SpiDevice class was totally irrelevant until you know how to control the device over SPI, and until you figured out some basic facts like how many bytes per LED, what the actual clock rate needed was, which is independent of the OS or library.
basp wrote: Meanwhile, my original question was "How would one write to an SPI device as fast as possible in a Universal Windows App?" For the sake of anyone finding this thread in the future, I'll provide the answer I've found elsewhere: create an endless loop on a different thread, and use System.Diagnostics.Stopwatch to time any calls to SpiDevice.Write(). It's not much faster than DispatcherTimer, but still noticeably so.
Your question was very premature, as you did not understand what you were trying to control, and how to control it.

Regarding porting Arduino code and getting it running... that still does not require really understanding SPI, it is like translating from one language to another - to put it in every day terms, most people can drive a car without understanding how it really works.

For future reference, you would have gotten help much faster if you had, in your initial post:

- identified the LED controller chip (LPD8806)
- specified how many LED's were on the strip you are trying to control

Once you know the data format the LED needs, the rest is relatively simple.

Simplified explanation:

(number of LED's) * (24 bits) * (string refresh rate per second) = minimum SPI speed needed

100 * 24 * 60 = 144000

Now depending on framing etc, SPI latency between transactions etc, you might need 200,000 bps from SPI. A far cry from 20Mbps
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi

DoSJoS
Posts: 1
Joined: Tue Jun 02, 2015 12:58 pm

Re: Fastest way of writing to an SPI device

Tue Jun 02, 2015 1:00 pm

Hi

All arguments aside, I am curious if you could share the code you used to get it working?

I have the same type of LED strip and I would like to do the same with it as I have already done with arduino.

juanpaexpedite
Posts: 15
Joined: Fri May 15, 2015 10:27 am

Re: Fastest way of writing to an SPI device

Wed Jun 03, 2015 5:25 am

I have question about timing and GPIO PWM and I got the answer that it can be in the pipeline
https://social.msdn.microsoft.com/Forum ... WindowsIoT

I have an issue to know what I have to write in the writebuffer to use the channel 1 instead the CH0 any idea?

markrad_msft
Posts: 58
Joined: Thu May 07, 2015 7:46 pm

Re: Fastest way of writing to an SPI device

Wed Jun 03, 2015 9:04 pm

juanpaexpedite wrote:I have an issue to know what I have to write in the writebuffer to use the channel 1 instead the CH0 any idea?
Can you be more specific about what it is you are trying to accomplish? I'm not sure to what you are referring.
Mark Radbourne | Microsoft | Windows 10 IoT Core Insider Preview Support | This posting is provided 'as is' with no warranties and confers no rights.

Return to “Windows 10 for IoT”