Need better timer resolution

I need a recommendation on how to increase the resolution of the timer functions. I currently use “micros()”.

My application: Six events take place in the outside world which I monitor with digital input pins on the Arduino. The events happen in no particular order. My sketch waits for the first one and reads and saves the current time (via micros). As each subsequent event takes place, it saves the time of each event. The final event happens within about 5ms from the first.

After reading all the event times, I send them up to a PC for postprocessing. The PC thus knows the time interval between events and the order of events. I then reset the sketch to wait for the next set of events. That wait could be many minutes.

The sketch does not use interrupts.

Using “micros()” I only get 4us resolution. Based on when the external events occur within the 4us window, the overall accuracy from the application’s viewpoint works out to +/- 4us.

The basic physics of what the overall problem requires a little bit better resulution. To that end, I have produced a counter board containing about 25 ICs. It runs at 10MHz which is just fine for accuracy. It monitors the outside events directly. As events happen, the counter board strobes the value of its internal clock into latches whose contents can be serially shifted out. The Arduino sketch handles this nicely.

I believe the application can live with plus/minus 1us or, better yet, 500ns.

I want to eliminate the 25 IC counter board. (Cost, hassle, packaging issues.) To do that, I need better resolution from the Arduino. I don’t know how to get it. Any ideas?

Many posts to the forum (and other places) refer to lower level programming available for the Arduino. In particular I see references to constructs like “timer2”. Unfortunately there is no nice, high level user documentation on what these constructs are, how to access them, or how to write additional code to use them. I assume at the hardware level, these are features which exist in the microprocessor but the Arduino developers have chosen (probably very wisely!) not to surface them – not to make available to the users.

Alternatively perhaps someone can suggest a different microcontroller system? Probably key would be an easy to use development environment such as the one that Arduino offers. By easy to use I would include: Integrated edit/compile/download, fully assembled PC board containing the microcontroller and support chips including what’s needed for downloading the program. A godsend would be a true debugger but I can live with print statements.

Feel free to reply to the forum or to me directly via email.

Thanks,
--jim Hahn Hahn_02493@yahoo.com

A simpler solution: have a free running timer, with an isr that increments a variable as a msb counter. So with a 16-bit timer + 16-bit msb counter, you have created a 32-bit timer.

Route the outside signals to trigger external interrupts. In the isr for the interrupts, you save the timer + msb values. This approach essentially creates a software-based capture function. The minimum resolution is the pulse train fed to the timer. So it can be 1/16us.

Depending on your application, this may have a few issues. For example, latency in the isr for the INTx can be 10 - 20 ticks. The good news is that such a latency is consistent from invocation to invocation.

Are you proposing something like the following EXAMPLE?

An external free running counter. Say 8 bits. When it overflows, it triggers an interrupt. ISR keeps track of true time MSB bits.

When I detect one of my six events, what do I do? Do I read back the value of the external counter? Won't that take a large amount of time, killing the accuracy? And, how would I read them back? I currently use most of the IO pins on the Arduino to monitor the events and reset FF control latches. I guess if I give up my counter board, that frees up 3 or 4 of the pins.

So it sounds like a good idea, I just can't get the block diagram into my head!
--jim

Timer1 has an Input Capture Trigger Source (ICP1, PORTB pin 0). This is a pin that saves the current timer value into ICR1H and ICR1L. You can then use the corresponding Input Capture Interrupt service routine to save the timer value and grab a byte of input bits to tell you which event occurred. I think the only external hardware you would need is a six-input OR gate so that all the inputs can connect to the Input Capture pin and a set of latches so that you can keep track of which inputs have occurred.

This should get you 62.5 nanosecond resolution.

The LPC178x has 8 capture inputs. If I read the data sheet correctly you can capture the timestamp of up to 8 events with multi-MHz resolution.

The LPCXpresso dev boards are about $25 and include a full debugger, Eclipse-based IDE (free for C but not C++) etc. Just write code and hit download to program over USB.

I've been using the LPC1227 version for a while, it's not as turn-key as Arduino but almost. I had simple apps running in no time.

http://ics.nxp.com/lpcxpresso/

It looks like the SAM3X8E that will be used in the Arduino Due has similar features as well. Maybe you should wait for that.


Rob

When I detect one of my six events, what do I do?

Those events will trigger an isr and in the isr you will save the timer's value (lsb) and the msb -> software capture.

Won't that take a large amount of time, killing the accuracy?

The isr + execution will likely take 20 ticks. So whatever value you have "saved" in the isr (mostly the lsb) will be "wrong" by the 20 or so ticks.

So, yes, this approach will "kill" the accuracy from that perspective.

However, the latency is deterministic so every captured value will be "wrong" by the same 20 ticks or so -> making the differences in the captured values accurate.

And if you are looking for absolute accuracy down to a few ticks, the arduino is the wrong platform for that.