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
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.
Boots507:
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?
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.
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.
dc42:
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.
That will give you a resolution of about 0.125us,
0.0625us. No prescaler means the clock ticks with the processor.
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).
michinyon:
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.
It's the circuit that matters more. You have to be able to charge the cap much quicker than it bleeds.
There must be some other physical events that you could use. With radar and a CRT display you 'see' the return time as distance along a sweep trace. On our 1950's sets the minimum was about 250 meters because the outgoing pulse took that long but 500 m travel time (out and back) when light moves about 300,000,000 m/s is just over 1 usec, and we could tell 10 m differences in range easily.
Maybe you could invert the delay, have that interval cut from something bigger that's known or some way take a ratio with a known and get a measure from that?
I think I could make such a circuit. If the pulse switches a transistor that charges a cap then the charge in the cap couldn't bleed back through the transistor when the pulse ended, could it?