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

Netduino driver for the AdaFruit VC0706 Camera


  • Please log in to reply
6 replies to this topic

#1 Fabien Royer

Fabien Royer

    Advanced Member

  • Members
  • PipPipPip
  • 406 posts
  • LocationRedmond, WA

Posted 13 August 2011 - 12:56 AM

Hi,

I wrote a driver for the AdaFruit VC0706 serial camera and wrote a blog post about my experience using it:
http://fabienroyer.w...ith-a-netduino/

Cheers,
-Fabien.

#2 Stefan

Stefan

    Moderator

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

Posted 13 August 2011 - 07:27 AM

Nice! Very cool photos as well, with the tripod+ducttape and retro television :D
"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

#3 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 13 August 2011 - 08:52 AM

Hi Fabien! It's a very nice application. I think it could be an inspiring basis, where to create several concrete apps (e.g. motion capture, surveillance systems, etc) Just a word about the limitation on the UART. I have found a similar limitation on the SPI, and that's something to solve, IMHO. What I have found is about sending a (long) stream. I guess the low-level sending should be performed by DMA, not by firmware. The problem is that you easily notice short pauses during the streaming, without any apparent reason. For instance, if you are sending a 500-bytes long stream at 4MHz, you'd expect to make the whole transfer in a short as about 1ms. If that transfer is performed cyclically (e.g. every 100mS), you may experience often "broken" packets. The transfer begins, flows 200-300 bytes, then pauses for several millisecs, then flushes the remaining bytes. I may imagine that on receiving data would be pretty harder than transmitting. This behavior isn't so good, because either the UART (asynchronous), and the SPI (synchronous), work better when the bytes are flowing continuously. So, the limitation that you have found may be originated by this interruption. I would consider to improve the lo-level routines about the serials (both UARTs and SPIs). Cheers
Biggest fault of Netduino? It runs by electricity.

#4 Fabien Royer

Fabien Royer

    Advanced Member

  • Members
  • PipPipPip
  • 406 posts
  • LocationRedmond, WA

Posted 13 August 2011 - 05:46 PM

@Stefan: thanks. I knew that old TV would come in handy some day :) @Mario: thanks for sharing your observations about SPI / UART behavior. Are you referring specifically to the Netduino or are your observations more general? In my experience, UART communication is always much trickier and less reliable than SPI, even considering the lower UART speeds. Also, are you suggesting improving the native .NET MF routines dealing with USART0/1 and SPI0/1 to improve their usage of the Peripheral DMA Controller on the SAM7X? Cheers, -Fabien.

#5 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 13 August 2011 - 06:43 PM

Fabien -- another very cool creation! Dang! Mario -- are you seeing interruptions in SPI transmission on the Netduino or Netduino Plus? The SPI transfers happen in firmware based on interrupts (i.e. when a byte is transmitted, a call to the SPI routine is called which then sends the next byte). But there are priorities there...and if the network interrupts are taking a while this could result in the behavior you're seeing. I'm interested in any feedback you have here; maybe we can help optimize the NETMF interrupt queueing system. Chris

#6 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 13 August 2011 - 07:17 PM

I'm interested in any feedback you have here; maybe we can help optimize the NETMF interrupt queueing system.

Personally, I would vote for Mario's suggestion to rewrite communication routines to be based on DMA transfers, which should give the best performance, although there are priorities too...

#7 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 14 August 2011 - 05:21 AM

@Chris: I own only a Netduino Plus, so I don't know how another model behaves. No network cable plugged in.

@Fabien: I've seen the interruptions on the SPI only, since I didn't try on the UART yet. However, I may assume would be the same thing. If it wasn't the same for the UART, it would be looks like a bug.

In the meantime, I have noticed an interesting thing. It seems that the probability to see the interruption is depending on the software pattern. I am not able to understand why there are differences, but here's some detail:
Consider the basic Netduino app:

public class Program
    {
        private static SPI _spi;
        private static InterruptPort _sync;
        private static readonly byte[] _buffer = new byte[576];

        public static void Main()
        {
            // Defines the first SPI slave device with pin 10 as SS
            SPI.Configuration Device1 = new SPI.Configuration(
                Pins.GPIO_PIN_D10, // SS-pin
                false,             // SS-pin active state
                0,                 // The setup time for the SS port
                0,                 // The hold time for the SS port
                true,              // The idle state of the clock
                true,              // The sampling clock edge (this must be "true" for the 74HC595)
                4000,              // The SPI clock rate in KHz
                SPI_Devices.SPI1   // The used SPI bus (refers to a MOSI MISO and SCLK pinset)
            );

            // Initializes the SPI bus, with the first slave selected
            _spi = new SPI(Device1);

            _sync = new InterruptPort(
                Pins.GPIO_PIN_D8, 
                false, 
                Port.ResistorMode.PullUp, 
                Port.InterruptMode.InterruptEdgeLow);

            _sync.OnInterrupt += new NativeEventHandler(_sync_OnInterrupt);
 
            while (true)
            {
                Thread.Sleep(100);
                
                // ... do some stuff ...
            }
        }

        static void _sync_OnInterrupt(
            uint data1, 
            uint data2, 
            DateTime time)
        {
            _spi.Write(_buffer);
        }
    }
It is clearly incomplete, but it is working. The goal is to trigger the byte-block transfer all at once, as soon a falling edge is detected.
By using this pattern there are a couple of issues:
  • the responsiveness of the interrupt handler routine (_sync_OnInterrupt) is very unstable. It is never the same, and it takes a "long delay" to be served (several millisecs as average).
  • the SPI transfer is broken sometime. However, it is easy to see that by lowring the SPI clock to 1-2MHz.

An attempt to solve the problem using another pattern.
The "do some stuff" block is moved on a separate thread, as follows:

...   ...   ...

            _sync.OnInterrupt += new NativeEventHandler(_sync_OnInterrupt);

            new Thread().Start();

            Thread.Sleep(Timeout.Infinite);
        }
 
        static void DoWork()
        {
            while (true)
            {
                Thread.Sleep(100);
                
                // ... do some stuff ...
            }
        }
The result is the same.

Now, let's change the pattern again by using a timer:

...   ...   ...

            _clock = new Timer(
                ClockTick,
                null,
                100,
                100);

            Thread.Sleep(Timeout.Infinite);
        }

        static void ClockTick(object state)
        {
            // ... do some stuff ...
        }
Now the responsiveness is excellent: less than 500uS most of the time, with a very little jitter.
Almost impossible to see the SPI transfer broken.
I may also increase the timer frequency (20-30Hz), and/or get the work heavier, but it seems very stable anytime.

Chris, the DMA is not involved because the raw/managed incompatibility, or what else?
  • asciiman likes this
Biggest fault of Netduino? It runs by electricity.




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.