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

Increasing the resolution of the system timer


  • Please log in to reply
12 replies to this topic

#1 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 16 September 2011 - 08:03 PM

As you probably know, the resolution of Netduino's system timer (aka 'slow clock') is 21.33 µs (46875 Hz). This determines the precision of time-related functions, such as various DateTime methods or Utility.GetMachineTime(), and it also means the time will always be a multiple of ~21 µs, which may cause problems for example with precise measurement of pulse duration.

I have hit this problem during development of DHT11/22 sensor managed driver - the communication protocol consists of pulses about 50 + 27µs, resp. 50 + 70 µs long for bit '0', resp. '1', but the real world devices have about +10% deviation (plus strange behavior like DHT22 having every 7th bit shorter and 8th bit longer than specified), and 21 µs resolution is just not enough - sometimes, bit '0' pulses were reported as bit '1', or vice-versa, causing the readout to fail due to invalid checksum.

After examining the source code, I have realized that it is possible to increase the resolution of the system timer 8× by changing the clock source from DIV5 (MCK/1024) to DIV4 (MCK/128), so the resolution is 2.6667 µs (375000 Hz). The required changes are as follows:

In Netduino solution platform_selector.h modify slow clock frequency and greatest common divisor constants

//TClk 4 ( Select MCK/128)
#define SLOW_CLOCKS_PER_SECOND        375000
#define SLOW_CLOCKS_TEN_MHZ_GCD        125000
#define SLOW_CLOCKS_MILLISECOND_GCD    1000
In DeviceCode/Targets/Native/AT91/DeviceCode/AT91_TIME/AT91_TIME.cpp change the timer clock source from AT91_TC::TC_CLKS_TIMER_DIV5_CLOCK to AT91_TC::TC_CLKS_TIMER_DIV4_CLOCK

...
if(!AT91_TIMER_Driver::Initialize(AT91_TIMER_Driver::c_SystemTimer, TRUE, AT91_TC::TC_CLKS_TIMER_DIV4_CLOCK, AT91_TIME_Driver::ISR, NULL))
...
That's it! I have asked Microsoft team about possible consequences of this change, still awaiting the answer. All basic operations such as deployment, debugging, threading, managed timers etc. appears to be running fine and the measurement of DHT11/22 sensor pulses does not give false readings anymorePosted Image

If there is anybody able and willing to test it, I am looking forward to hearing your feedback.

#2 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 17 September 2011 - 05:25 AM

If we are considering just one MCU model, and be the only users of the MF, I guess the Netduino board could be hugely improved. There are several "mysterious" issues and choices made by the MF team, some are still unanswered. I think they're chosen as 21.33us the base clock for accomplish many different CPUs, but...however that will leak the optimum. IMHO, having a well-defined timebase would be good choice, as the old PC-DOS had the 55ms clock. Instead, the actual problem is the missing ability to write native drivers. Even better would be the ability to leave the base firmware, then add/remove (plug) just the desired driver. I wonder why that could be so hard to create: a stupid assembler/C++ routine called by your managed program using some (smart) trick. Bah!... Anyway, congrats for the news. Did you check the DateTime progression as well? Cheers PS: until a decent native-way is not available, I'd prefer the hardware way.
Biggest fault of Netduino? It runs by electricity.

#3 Valkyrie-MT

Valkyrie-MT

    Advanced Member

  • Members
  • PipPipPip
  • 315 posts
  • LocationIndiana, USA

Posted 07 October 2011 - 05:49 PM

I have built a firmware version with your changes (about a week ago). So far it works fine. I have not yet done a comparison of clock time-keeping improvements though... -Valkyrie-MT

#4 Valkyrie-MT

Valkyrie-MT

    Advanced Member

  • Members
  • PipPipPip
  • 315 posts
  • LocationIndiana, USA

Posted 24 October 2011 - 05:47 AM

Did you check the DateTime progression as well?


I tested the Date/Time drift with and without this change and it made no difference for the clock. :(

Just an FYI, the clock appears to drift 0.5 seconds per hour for a grand total of 12 seconds per day! Yikes, make sure to sync up with the NTP servers frequently (although not too frequently as the NTP servers will block frequent access). Once a day should be good.

-Valkyrie-MT

#5 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 24 October 2011 - 06:21 AM

I tested the Date/Time drift with and without this change and it made no difference for the clock. :(

Sorry, but the change was not supposed to affect the clock drift. The microcontroller has Real-Time Timer, but unlike other micros, it does not support [32768 Hz] external crystal and does not have any calendar/time logic (it's just simple second counter), so apart from NTP, you'd probably need to use external RTC integrated circuit to have precise time. Another option would be to use a special hardware process "Timing Interval Acquisition" described in Atmel's application note Using a Real-time Timer with Non-calibrated RC Oscillator as a Real-time Clock (pdf) to improve the clock accuracy.

#6 Igor Kondrasovas

Igor Kondrasovas

    Advanced Member

  • Members
  • PipPipPip
  • 105 posts
  • LocationPorto, Portugal

Posted 21 November 2011 - 12:25 PM

As you probably know, the resolution of Netduino's system timer (aka 'slow clock') is 21.33 µs (46875 Hz). This determines the precision of time-related functions, such as various DateTime methods or Utility.GetMachineTime(), and it also means the time will always be a multiple of ~21 µs, which may cause problems for example with precise measurement of pulse duration.

I have hit this problem during development of DHT11/22 sensor managed driver - the communication protocol consists of pulses about 50 + 27µs, resp. 50 + 70 µs long for bit '0', resp. '1', but the real world devices have about +10% deviation (plus strange behavior like DHT22 having every 7th bit shorter and 8th bit longer than specified), and 21 µs resolution is just not enough - sometimes, bit '0' pulses were reported as bit '1', or vice-versa, causing the readout to fail due to invalid checksum.

After examining the source code, I have realized that it is possible to increase the resolution of the system timer 8× by changing the clock source from DIV5 (MCK/1024) to DIV4 (MCK/128), so the resolution is 2.6667 µs (375000 Hz). The required changes are as follows:

In Netduino solution platform_selector.h modify slow clock frequency and greatest common divisor constants

//TClk 4 ( Select MCK/128)
#define SLOW_CLOCKS_PER_SECOND        375000
#define SLOW_CLOCKS_TEN_MHZ_GCD        125000
#define SLOW_CLOCKS_MILLISECOND_GCD    1000
In DeviceCode/Targets/Native/AT91/DeviceCode/AT91_TIME/AT91_TIME.cpp change the timer clock source from AT91_TC::TC_CLKS_TIMER_DIV5_CLOCK to AT91_TC::TC_CLKS_TIMER_DIV4_CLOCK

...
if(!AT91_TIMER_Driver::Initialize(AT91_TIMER_Driver::c_SystemTimer, TRUE, AT91_TC::TC_CLKS_TIMER_DIV4_CLOCK, AT91_TIME_Driver::ISR, NULL))
...
That's it! I have asked Microsoft team about possible consequences of this change, still awaiting the answer. All basic operations such as deployment, debugging, threading, managed timers etc. appears to be running fine and the measurement of DHT11/22 sensor pulses does not give false readings anymorePosted Image

If there is anybody able and willing to test it, I am looking forward to hearing your feedback.



Hello,


I think I still cannot help you on this, but I would like to ask you how can we use such small timespans on .NETMF. The managed Timer Functions work in a milliseconds units base and the TimeSpan constructor overload has a "tick" unit, that I believe is equals to 100 nanoseconds...

So, even knowing this is not precise and easy to make calculation, how can I program a timer to fire at 21.33 us? Can I do that via managed code?

Thank you,

Igor.

Igor Kondrasovas

www.inovativatec.com


#7 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 21 November 2011 - 12:47 PM

So, even knowing this is not precise and easy to make calculation, how can I program a timer to fire at 21.33 us? Can I do that via managed code?

Unfortunately, this is not possible to do in managed code, there is no support for accessing hardware timer modules in the .NET MF. Also, you'd need to consider the performance of managed code - you cannot really execute much of it in ~20 µs. What would you like to do?

#8 Igor Kondrasovas

Igor Kondrasovas

    Advanced Member

  • Members
  • PipPipPip
  • 105 posts
  • LocationPorto, Portugal

Posted 21 November 2011 - 01:13 PM

Unfortunately, this is not possible to do in managed code, there is no support for accessing hardware timer modules in the .NET MF. Also, you'd need to consider the performance of managed code - you cannot really execute much of it in ~20 µs. What would you like to do?



Thank you for the reply back,

I want to control a stepper motor using the GPIOs on Netduino. How can I mix native code to control the timers with the rest of my application logic?


Thank you,

Igor.

Igor Kondrasovas

www.inovativatec.com


#9 <Jeremy>

<Jeremy>

    Advanced Member

  • Members
  • PipPipPip
  • 31 posts
  • LocationNorthern Ireland

Posted 20 July 2012 - 03:18 PM

Hi there I've built this firmware with the changes to the 'slow clock' time, but I'm not seeing any improvement in performance in my DHT11. Is there a command to query the Netduino properties to find the slow clock time? I just want to check that my new binaries actually have this change built into them. Thanks, Jeremy

#10 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 20 July 2012 - 06:36 PM

The Cpu.SlowClock property value should be 375000 (Netduino default is 46875).

#11 <Jeremy>

<Jeremy>

    Advanced Member

  • Members
  • PipPipPip
  • 31 posts
  • LocationNorthern Ireland

Posted 28 July 2012 - 11:31 PM

Hi CW2 - thanks for this, I just saw this reply, sorry for not replying sooner! I'll try it and let you know how I get on, Jeremy

#12 <Jeremy>

<Jeremy>

    Advanced Member

  • Members
  • PipPipPip
  • 31 posts
  • LocationNorthern Ireland

Posted 29 July 2012 - 12:27 AM

Hi again - no luck with the DHT11 after increasing my firmware resolution I'm afraid. My firmware is definitely now running at 375kHz, and the Netduino doesn't seem to be distinctly seeing all 43 pulses for each temperature/humidity reading (usually half that or less). Oh well. (This is of course just on my system - other people's mileage may vary.)

#13 Shadi

Shadi

    Member

  • Members
  • PipPip
  • 12 posts

Posted 26 April 2013 - 06:05 PM

If you use the InterruptPort class and compare the time parameter on the event with the last event, you can get pulse duration. On the DHT22, I watch for more/less than 500.

 

public const long PulseDurationBarrier = 500;public const int DataLength = 5;public const int BitShiftMax = 7;this.ipSensor = new InterruptPort(IOPin, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);this.ipSensor.OnInterrupt += new NativeEventHandler(ipSensor_OnInterrupt);void ipSensor_OnInterrupt(uint data1, uint data2, DateTime time){	if (data2 == 0)	{		curPulse.LowTicks = time.Ticks;		if (curPulse.HighTicks > 0)		{			if (curPulse.GetDuration() > PulseDurationBarrier)			{				Data[idxData] |= (byte)(1 << bitData);			}			bitData--;			if (bitData < 0)			{				idxData++;				bitData = BitShiftMax;			}			if (idxData == DataLength)			{				ProcessResults();			}			this.curPulse = new Pulse();		}	}	else	{		curPulse.HighTicks = time.Ticks;	}}

Pulse is just a simple storage structure with LowTicks & HighTicks and a method that returns LowTicks - HighTicks






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.