9

I'm programming a Netduino board using the .NET Micro Framework 4.1 and want to get a higher time resolution than milliseconds. This is because I'm attempting to dim an LED by blinking it really fast.

The issue is that the sample code uses Thread.Sleep(..) which takes a number of milliseconds.

Sample code from http://netduino.com/projects/ showing the issue in question:

OutputPort ledOnboard = new OutputPort(Pins.ONBOARD_LED, false);
while (true)
{
    ledOnboard.Write(true);
    Thread.Sleep(1); // << PROBLEM: Can only get as low as 1 millisecond

Even if there's another way to accomplish dimming by not using a greater time resolution, I'm game.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
John K
  • 28,441
  • 31
  • 139
  • 229
  • Personally I'd use hardware and talk to it via SPI or I2C eg http://www.ltech.cn/english/product/DMX-512-Driver.html – Peter Wone Apr 01 '12 at 13:28

5 Answers5

17

This doesn't answer your question about getting a better time resolution, but it does solve your problem with changing the brightness on an LED. You should be using the PWM module for the Netduino.

Netduino Basics: Using Pulse Width Modulation (PWM) is a great article on how to use it.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
superfro
  • 3,327
  • 1
  • 18
  • 14
8

I have had a similar problem in the past and used the following method to time in the microsecond range. The first line determines how many ticks are in a millisecond (its been a while since I used this, but I think 1 tick was 10 microseconds). The second line gets the amount of time the system has been on (in ticks). I hope this helps.

public const Int64 ticks_per_millisecond = System.TimeSpan.TicksPerMillisecond;

public static long GetCurrentTimeInTicks()
{
    return Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks;
}
Seidleroni
  • 1,044
  • 3
  • 15
  • 31
  • NETMF doesn't seem to support the Timer constructor that accepts a TimeSpan object, which is what would allow John to set the period in ticks. – Dave Sep 22 '11 at 13:02
  • This works great, just wrote a quick Wait function. Dave, what are you smoking? Not only does NETMF support a TimeSpan in the constructor of a Timer (look at the overloads, bro), but that's completely irrelevant to this solution. Just sit in a busy loop and wait for the desired number of ticks to elapse. See the function I added in the edit. – BrainSlugs83 Dec 17 '11 at 08:18
  • 1
    Handy to know but personally I'd still use PWM for the LED thing. – Peter Wone Jan 11 '12 at 06:42
3

You can use a timer to raise an event instead of using sleep.

The Interval property on a timer is a double so you can have less than a millisecond on it.

http://msdn.microsoft.com/en-us/library/0tcs6ww8(v=VS.90).aspx

Phill
  • 18,398
  • 7
  • 62
  • 102
  • I upvoted this before testing it... oops. The interval is actually either an int or a TimeSpan, and looks like it has ms resolution as well. Thus, I do not think this is a valid solution for John. – Dave Sep 21 '11 at 18:14
  • I take that back -- while I still need to test it, one of the other answers indicates that you can get the number of ticks per ms, and on my board I get back 10,000. So 10 ticks per us isn't too shabby (if it actually works) :) – Dave Sep 21 '11 at 18:24
  • This won't actually work. While System.TimeSpan DOES have sub-millisecond resolution, it will NOT actually fire your event at the requested resolution. Your best event is peeking at Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks in a while loop. As suggested below, TimeSpan has a static property which will tell you how many ticks are in a second, millisecond, minute, hour, etc... – BrainSlugs83 Dec 17 '11 at 08:12
0

In his comment to Seidleroni's answer BrainSlugs83 suggests "sit in a busy loop and wait for the desired number of ticks to elapse. See the function I added in the edit". But I cannot see the function added to the edit. I assume it would be something like this:

using System;
using Microsoft.SPOT.Hardware;

private static long _TicksPerMicroSecond = TimeSpan.TicksPerMillisecond/1000;

private void Wait(long microseconds)
{
    var then = Utility.GetMachineTime().Ticks;
    var ticksToWait = microseconds * _TicksPerNanoSecond;
    while (true)
    {
        var now = Utility.GetMachineTime().Ticks;
        if ((now - then) > ticksToWait) break;
    }
}
Community
  • 1
  • 1
dumbledad
  • 16,305
  • 23
  • 120
  • 273
0

A point that you might not be thinking about is that your code is relying on the .NET System namespace, which is based on the real time clock in your PC. Notice that the answers rely on the timer in the device.

Moving forward, I would suggest that you take a moment to qualify the source of the information you are using in your code -- is it .NET proper (Which is fundamentally based on your PC), or the device the code is running on (Which will have a namespace other than System, for example)?

PWM is a good way to control DC current artificially (by varying the pulse width), but varying the PWM frequency will still be a function of time at the end of the day.

Rather than use delays....like Sleep....you might want to spawn a thread and have it manage the brightness. Using Sleep is still basically a straight line procedural method and your code will only be able to do this one thing if you use a single thread.

jinzai
  • 436
  • 3
  • 9