Pages: [1] 2   Go Down
Author Topic: Getting a 1us delay  (Read 1031 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

I am trying to measure a time of 1us. I realized the micros() function is only accurate to 4us. I was trying to use the following code to increment a variable every 1us. So far "MicroSecClock is always equal to 0. Is that the right strategy to capture 1us resolution? Thank you

Code:
uint32_t MicroSecClock = 0;

ISR(TIMER2_OVF_vect) {
  static uint8_t count;            // interrupt counter

  if( (++count & 0x01) == 0 )     // bump the interrupt counter
    MicroSecClock++;              // & count uSec every other time.

  TCNT2 = 253;                    // reset counter 2MHz interrupt rate
  TIFR2 = 0x00;                   // clear timer overflow flag
};
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Perhaps, I may add that my goal is to make my own "micros()" function that is precise up to 1us rather than 4 us. Since I read that the micros() function is based upon the timers, I figured I had to come up with my own manipulation of the timers to achieve a 1us granularity. I'm just looking for pointers on the best way to accomplish this.

Thank you
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

At 16Mhz, it takes 1us to execute 16 nop instructions.
Logged

Left Coast, CA (USA)
Online Online
Brattain Member
*****
Karma: 331
Posts: 16553
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Perhaps, I may add that my goal is to make my own "micros()" function that is precise up to 1us rather than 4 us. Since I read that the micros() function is based upon the timers, I figured I had to come up with my own manipulation of the timers to achieve a 1us granularity. I'm just looking for pointers on the best way to accomplish this.

Thank you

Probably harder then it might first appear depending on if you make it a blocking function or have to have it co-exist in an interruptible environment?

Lefty
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 178
Posts: 12288
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I am trying to measure a time of 1us.

Is that the right strategy to capture 1us resolution?

Which?  Measure an elapsed time of 1 us or measure something with a resolution of 1 us?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I am trying to measure a time of 1us.

Is that the right strategy to capture 1us resolution?

Which?  Measure an elapsed time of 1 us or measure something with a resolution of 1 us?


Hi,

I am trying to measure something with a resolution of 1us. I was thinking that measuring and elapse time of 1us would allow me to do just that.

Jean
Logged

Poole, Dorset, UK
Offline Offline
Edison Member
*
Karma: 25
Posts: 1882
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think that you will find that the Arduinos are just to slow to do this.

Mark
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 220
Posts: 6587
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I would set up timer 1 to run direct from the system clock, no prescaler. Wait in a tight loop for the input pin to change, using direct port i/o, then read the timer. Wait in another tight loop for the pin to change again, then read the timer again. You should be able to code the loops to run in less than 0.5us (i.e. less than 8 clock cycles), so 1us resolution should be just about achievable.

Alternatively, feed the signal to the input capture pin (or to the analog comparator), and use the input capture facility of timer 1 to record the times of the input transitions. That will give you a resolution of about 0.125us, however the shortest time you can record will be a few us.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Offline Offline
Edison Member
*
Karma: 29
Posts: 2048
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you are trying to measure some small interval,  devise a circuit which starts a pulse when
the first event occurs and ends the pulse when the second event occurs.

Then use the pulse you created to charge up a capacitor.

And then measure the voltage achieved in the capacitor while it was accumulating current
during the pulse.

It is not that easy to measure 1 us,  the Arduino is not fast enough to do it using software.
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 178
Posts: 12288
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I think that you will find that the Arduinos are just to slow to do this.

That is not correct.
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 178
Posts: 12288
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Alternatively, feed the signal to the input capture pin (or to the analog comparator), and use the input capture facility of timer 1 to record the times of the input transitions.

That's what I would do.  It works very well.  There are examples available on the internet and probably on this forum.

Quote
That will give you a resolution of about 0.125us,

0.0625us.  No prescaler means the clock ticks with the processor.

Quote
however the shortest time you can record will be a few us.

If I remember correctly, the shortest elapsed time I was able to "input capture" was 3 us.

The drawback is that you have to use a 16 bit timer (timer 1 on the Uno).
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 178
Posts: 12288
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It is not that easy to measure 1 us,  the Arduino is not fast enough to do it using software.

That is not correct.
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Use the capture function.
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 58
Posts: 4036
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you are trying to measure some small interval,  devise a circuit which starts a pulse when
the first event occurs and ends the pulse when the second event occurs.

Then use the pulse you created to charge up a capacitor.

And then measure the voltage achieved in the capacitor while it was accumulating current
during the pulse.

It is not that easy to measure 1 us,  the Arduino is not fast enough to do it using software.

I have charged a cap (I forget the circuit but it included changing a pin from OUTPUT to INPUT to take advantage of the high INPUT impedance -- to me that is like <usec circuit rewiring) and counted loops till it bled out to ground through a resistor. That let me -stretch out- the measure. IIRC I was playing around with capsense at the time.



Logged

Examples can be found in your IDE.

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Does anybody have a working code snippet I could use to achieve that?
Logged

Pages: [1] 2   Go Up
Jump to: