Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Any chance of being able to speed up SPI - NP2?


  • Please log in to reply
13 replies to this topic

#1 Bamboosam

Bamboosam

    New Member

  • Members
  • Pip
  • 8 posts

Posted 20 January 2013 - 07:38 PM

I've noticed my lpd8806 strips running significantly slower than on an arduino. So the max SPI clock rate is 2000 kHz, is there any way I can speed that up? 



#2 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 20 January 2013 - 07:56 PM

I run SPI on the Mini at 25Mhz. Are you sure there's a 2Mhz limit on the N2P? I assumed it isn't fixed but configurable to much higher rates. Also, what dou you mean, the LED strip runs slower? I thougt ncontrolling a LED strip would be fast even at 2Mhz.

#3 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 20 January 2013 - 08:03 PM

Hi Bamboosam, The SPI bus on Netduino Plus 2 runs at up to 21MHz. What does your project's code look like? It's possible that the SPI transactions are very quick...but that there's a lot of MCU cycles taken up by other code. Chris

#4 Bamboosam

Bamboosam

    New Member

  • Members
  • Pip
  • 8 posts

Posted 20 January 2013 - 08:16 PM

The code is very simple right now, and I created the exact pattern on my arduino and it is noticeably slower on the NP2.  I've pretty much maxed out my last project using an Atmega 1284p @ 16mHz, so I am in the jump to a better processor to achieve more complex patterns. 

public static void LightStripSpi()

        {

            int i = 0;

            var spi = new SPI(new SPI.Configuration(Cpu.Pin.GPIO_NONE,

                false, 0, 0, false, true, 2000, SPI.SPI_module.SPI1));

           

            var colors = new byte[3 * 94];

         

            var zeros = new byte[3 * ((32 + 63) / 64)];

 

            byte r = 0;

            byte g = 0;

            byte b = 0;

            byte spin = 0;

 

            while (true)

            {

             

                // all pixels off

            for (int ix = 0; ix < colors.Length; ++ix) colors[ix] = (byte)(0x80 | 0);

 

            switch (i)

            {

                case 0: r = 127; b = 0; g = 0; break;

                case 1: r = 0; b = 127; g = 0; break;

                case 2: r = 0; b = 0; g = 127; break;

                case 3: r = 127; b = 0; g = 127; break;

                case 4: r = 0; b = 127; g = 127; break;

                case 5: r = 127; b = 127; g = 0; break;

                case 6: r = 127; b = 127; g = 127; break;

            }

 

                for (byte o = 0; o < 94; o+=47){

                for (byte e = 0; e < 4; e++)

                {

 

                    colors[(((o + e + spin) % 94) * 3) + 0] = (byte)(0x80 | r); //blue

                    colors[(((o + e + spin) % 94) * 3) + 1] = (byte)(0x80 | g); //red

                    colors[(((o + e + spin) % 94) * 3) + 2] = (byte)(0x80 | B); //green

 

                    colors[(((93 - (o + e + spin) % 94)) * 3) + 0] = (byte)(0x80 | r); //blue

                    colors[(((93 - (o + e + spin) % 94)) * 3) + 1] = (byte)(0x80 | g); //red

                    colors[(((93 - (o + e + spin) % 94)) * 3) + 2] = (byte)(0x80 | B); //green                  

                }            

                }

                spi.Write(colors);

                spi.Write(zeros);

                i++;

                i %= 7;

                spin++; spin %= 94;                

            }

        }

 


#5 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 20 January 2013 - 08:18 PM

On 2nd thought I think Bamboosam meant to say i2c since the controller d/s says "2-wire". EDIT: Delayed post, sorry.

#6 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 20 January 2013 - 08:24 PM

You do some calculations in each loop round and managed Net MF code is considerably slower than an Arduino. I guess you either have to optimize the calculations or increase the amount of data transfered in each round. Simply speeding up SPI probably wont help much.

#7 Bamboosam

Bamboosam

    New Member

  • Members
  • Pip
  • 8 posts

Posted 20 January 2013 - 08:30 PM

ok, I thought it had to do with SPI, I was hoping the NP2 @ 168mHz even though using .Net would be considerably faster than an Atmega @ 16mHz. Bummer



#8 Bamboosam

Bamboosam

    New Member

  • Members
  • Pip
  • 8 posts

Posted 20 January 2013 - 08:34 PM

Great job guys on the netduino though! Using Visual C# is next to heaven, too bad there is just too much over head.



#9 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 20 January 2013 - 08:49 PM

I've never worked with this so perhaps you'd better verify it. You could for example try doing significantly less calculation in each loop round, for instance prepare two fixed color arrays - one setting all leds red and another array for setting all to blue and simply toggling between these two or something like that. This way you would boil it down to the highest theretical speed. I think I just realized how these controllers are chained together and I guess you could prepare longer arrays for more than one "frame" thus increasing the SPI overhead in comparison to the calculations, thus making the latter less significant overall. Also, you can use two threads to implement a double buffering scheme and let the SPi transfer run in background while preparing the next (one or more frames). This would work almost like a game engine works with a graphics frame buffer. I'm pretty sure you would see some drastic performance increase. EDIT: If and when you get this double (or triple etc) buffering scheme using two synchronized threads up and running you can increase the SPI speed. The LED controller absolute max rating is 20Mhz according to the d/s.

#10 Bamboosam

Bamboosam

    New Member

  • Members
  • Pip
  • 8 posts

Posted 20 January 2013 - 08:53 PM

Ok, Ill try that. Thank you :)



#11 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 20 January 2013 - 09:00 PM

Cool, looking forward to learn of the results!

#12 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 21 January 2013 - 05:30 AM

Hanzibal is right: you should create a byte array in advance, then write it via SPI all at once.

 

The SPI is blazing fast in any Netduino flavor: is able to transfer data much faster than any Arduino can do. That's simply because the Netduino uses the DMA for achieve the transfer while the Arduino must perform it via software.

 

Furthermore, your above code can be optimized a lot.

Some hints:

 

 

 

while (true)            {                                //create a template array, then use Array.Copy for fast filling               for (int ix = 0; ix < colors.Length; ++ix) colors[ix] = (byte)(0x80 | 0);               //use a map instead, where "i" is the pointer               switch (i)               {                   case 0: r = 127; b = 0; g = 0; break;                   case 1: r = 0; b = 127; g = 0; break;                   case 2: r = 0; b = 0; g = 127; break;                   case 3: r = 127; b = 0; g = 127; break;                   case 4: r = 0; b = 127; g = 127; break;                   case 5: r = 127; b = 127; g = 0; break;                   case 6: r = 127; b = 127; g = 127; break;               }                //using "int" is lot faster than "byte"                for (byte o = 0; o < 94; o+=47){                for (byte e = 0; e < 4; e++)                {                    //the indexing function can be calculated once only                    colors[(((o + e + spin) % 94) * 3) + 0] = (byte)(0x80 | r); //blue                    colors[(((o + e + spin) % 94) * 3) + 1] = (byte)(0x80 | g); //red                    colors[(((o + e + spin) % 94) * 3) + 2] = (byte)(0x80 | ; //green                    //same as above                    colors[(((93 - (o + e + spin) % 94)) * 3) + 0] = (byte)(0x80 | r); //blue                    colors[(((93 - (o + e + spin) % 94)) * 3) + 1] = (byte)(0x80 | g); //red                    colors[(((93 - (o + e + spin) % 94)) * 3) + 2] = (byte)(0x80 | ; //green                                  }                            }                //join the array pair in a single one                spi.Write(colors);                spi.Write(zeros);                i++;                i %= 7;                spin++; spin %= 94;                            }

 

Also bear in mind that the SPI clock of 2 MHz is fast enough for most applications. Higher clock rates may lead to bad results/malfunctioning, especially whereas the wiring is long and/or noise is relevant.

 

Hope it helps.
Cheers

Biggest fault of Netduino? It runs by electricity.

#13 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 21 January 2013 - 08:47 AM

That's simply because the Netduino uses the DMA for achieve the transfer
Unfortunately, the current implementation of SPI does not use DMA. AFAIK it is planned for Netduino Go (GoBus SPI transport), so hopefully it will be available on other STM32-based boards too.

#14 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 21 January 2013 - 11:15 AM

Fyi; I wrote a driver for those strips which is pretty fast;

 

http://netmftoolbox....are.RgbLedStrip

 

Maybe you can be inspired by it? :)


"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.