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

How do I create a high resolution timer for Netduino Plus


  • Please log in to reply
8 replies to this topic

#1 Mike D.

Mike D.

    New Member

  • Members
  • Pip
  • 3 posts

Posted 14 September 2011 - 02:36 AM

I am implementing a WSPR Beacon using the Netduino Plus for a Ham Radio project. Basically, WSPR transmits 162 4-FSK symbols at a symbol time of 682.7 milliseconds per symbol. The Timer class provided in C# only has millisecond resolution. Also, using Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks in a thread with a fixed period doesn't seem to be predictable. I cannot get deterministic results for the time period I need for this application. I believe the arduino has hardware timers that can be used for this application, but I chose the Netduino Plus for its C# development environment support. Does anyone know what the Netduino Plus equivalent is for arduino hardware timers? Or, does anyone have a suggestion on an approach that would allow me to create a timer with 100 microsecond resolution or better that I can have trip an interrupt when it times out?

#2 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 14 September 2011 - 06:31 AM

Welcome to the community!


Or, does anyone have a suggestion on an approach that would allow me to create a timer with 100 microsecond resolution or better that I can have trip an interrupt when it times out?

Please have a look at Chris Walker's SleepMicroseconds function.

Netduino microcontroller has hardware timer modules, but unfortunately there are no managed classes to access them in the current version of .NET Micro Framework. The resolution of system clock is ~21µs (46875 Hz), this determines the precision of all time-related functions. Also, .NET MF is not real-time system, so there is no guarantee for response times etc., and garbage collector may interrupt the application for a few milliseconds. Even if you use external timer connected to Netduino and instantiate InterruptPort, the application will not work reliably with such precision requirements - interrupt requests are queued in .NET MF, and it takes roughly hundreds of microseconds before the handlers start executing.

#3 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 14 September 2011 - 06:52 AM

Additionally, I would like to point out that the managed code is interpreted (there is no Just-In-Time compiler, unlike in the 'full' .NET Framework) and times around tens of microseconds are execution times of managed methods - for example, Port.Write() takes about 50 µs (if I remember it correctly), so the application cannot really do much in 100 µs intervals. You'd probably need to use Arduino for such time critical stuff...

#4 Stefan W.

Stefan W.

    Advanced Member

  • Members
  • PipPipPip
  • 153 posts

Posted 14 September 2011 - 10:48 AM

There's also nothing stopping you from adding another microcontroller to your project that handles timing-critical stuff and communicates with your netduino e.g. using SPI. That way, you can use c# for the high-level stuff and have exact timings for the time-critical stuff.
I believe that no discovery of fact, however trivial, can be wholly useless to the race, and that no trumpeting of falsehood, however virtuous in intent, can be anything but vicious.
-- H.L. Mencken, "What I Believe"

#5 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 14 September 2011 - 11:51 AM

There's also nothing stopping you from adding another microcontroller to your project that handles timing-critical stuff and communicates with your netduino e.g. using SPI. That way, you can use c# for the high-level stuff and have exact timings for the time-critical stuff.

Instead saying "nothing is stopping you", it would be better to say "the only way to solve this"...
Biggest fault of Netduino? It runs by electricity.

#6 Stefan W.

Stefan W.

    Advanced Member

  • Members
  • PipPipPip
  • 153 posts

Posted 14 September 2011 - 12:28 PM

Instead saying "nothing is stopping you", it would be better to say "the only way to solve this"...


Well, what I was trying to say that you don't need to give up on the netduino completely :)
I believe that no discovery of fact, however trivial, can be wholly useless to the race, and that no trumpeting of falsehood, however virtuous in intent, can be anything but vicious.
-- H.L. Mencken, "What I Believe"

#7 Mike D.

Mike D.

    New Member

  • Members
  • Pip
  • 3 posts

Posted 16 September 2011 - 03:00 AM

Thank you for quick reply. I had my suspicions that I'd might have to add an additional timer. Thanks again.

#8 Gregg Lind

Gregg Lind

    New Member

  • Members
  • Pip
  • 1 posts

Posted 22 September 2011 - 09:52 PM

What about using the PWM as a clock source and I also thought about the SPI bus to perform a clocking function. Do we have any other RTC's or sheilds that provide high quality time source.. such as Oven Controlled Crytal Oscillator OCXO.

#9 Mike D.

Mike D.

    New Member

  • Members
  • Pip
  • 3 posts

Posted 23 September 2011 - 02:43 AM

I just discovered that I could use the PWM class. Once set, it runs continually. I tied the pwm output (pin5) to pin6 where I set an interrupt handler. Then I just count 100 interrupts to get my 682 msec. Here is the PWN set code: PWM myPWM = new PWM(Pins.GPIO_PIN_D5); const uint period = 6820; // 6.82 ms const uint duration = 1000; // 1 msec myPWM.SetPulse(period, duration); Here is the entire project: namespace NetduinoPlusApplication1 { public class Program { // Led for visual indication static OutputPort led = new OutputPort(Pins.ONBOARD_LED, false); // Interrupt declaration static readonly InterruptPort pin6 = new InterruptPort( Pins.GPIO_PIN_D6, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeHigh ); static int intCounter = 0; // Declaration of the interrupt callback function static void OnInterrupt(uint port, uint state, DateTime time) { pin6.ClearInterrupt(); intCounter++; // count to 100 to get 682 msec (6.8 msec * 100) if (intCounter > 100) { intCounter = 0; // flash the led for test purposes led.Write(!led.Read()); } } public static void Main() { Debug.Print("Lets start\n"); // register the interrupt handler pin6.OnInterrupt += new NativeEventHandler(OnInterrupt); Debug.Print("Starting PWM Test\n"); // PWM declaration PWM myPWM = new PWM(Pins.GPIO_PIN_D5); const uint period = 6820; // 6.82 ms const uint duration = 1000; // 1 msec myPWM.SetPulse(period, duration); for (int i = 0; i < 1000; i++) { Thread.Sleep(500); } Debug.Print("Bye Bye\n"); } } } Thanks again for the help I received. I hope this solution will be a benefit to others.




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.