Go Down

Topic: realtime clock, microseconds, etc. (Read 10604 times) previous topic - next topic

mellis

How much time does the increment add to the execution time of the overflow handler?  That affects everyone, not just people using micros().  On the other hand, people using micros() probably are the ones who really need good performance.

mem

#61
Nov 12, 2008, 02:06 pm Last Edit: Nov 12, 2008, 02:09 pm by mem Reason: 1
Incrementing a long would add 11 instructions to the handler, at 16mhz this would take around 700 nanoseconds. The existing handler takes 9 microseconds, so the added functionality would increase the execution time by 8%.

Although I don't agree with the assumption that only those that use micros() care about performance, the loss of 700 nanoseconds per interrupt would seem acceptable.

dcb

#62
Nov 12, 2008, 02:33 pm Last Edit: Nov 12, 2008, 02:51 pm by dcb Reason: 1
Thanks Mem :)

Another way of looking at it is that the interrupt handler got 12 times longer in 0013.

I must admit I am not wild about having another 32 bit global lying around, but I also don't see how millis and micros can both rollover cleanly and make nice bitwise subtraction when separated by a factor of 1000 without it (without basing millis on micros)

Of course the first person to say "hey I cannot mix my millis and micros calls without strange behavior after x number of hours" gets a punch in the arm :)

Fedro

Hi All,

I've just bought an Arduino duemilanove (mhz ??) and installed the sw 0012 alpha on windows. I'm an absolute beginner.
I'm trying to control a Flynn motor, similar to a stepper motor.
"millis" are not enough for me.
Microseconds would be OK; hpticks would be OK.
If microseconds are only an approximation, obtained by multiplying hpticks * 4 (do I understand correctly previous posts ?), in this case, I would prefer to use directly hpticks.
I would like to read hpticks from the inside of a function called by attachInterrupt; is this possible ?
Could some official guru, please summarize:

1 - Which is the most accurate and best performing method ? hpticks or microseconds ? Would you please post the last version of the function code ? Will it work if triggered by an interrupt ?

2 - How to get it work and compile: which files of the IDE have to be modified ? Code to insert ? Is it available a version of hpticks or microseconds, which everything included in the code and nothing to modify in the IDE ?

3 - Is it possible to reset that timer ? How to do that ?

4- Is it possible to simply read, and reset to zero, the value of that register containing hpticks, without any conversion ? Assuming that I'm using a "duemilanove" ? How ?

Thank you in advance




Fedro

What about changing (via code) the prescalers of TCNT0/1/2/3, and set them in such a way that it would be possible to aquire microseconds, milliseconds, seconds and minutes ?

Example: the prescaler of TCNT0 would be set to 16 for Arduino duemilanove, in order to tick microseconds ?

dcb

a prescalar of 16 would mean the timer0 interrupt gets called 4 times as often as a prescalar of 64.  That would be a fair bit of extra overhead.

One thing that might be useful, and I don't really know how to quantify usefulness here except for my own nefarious purposes :), is to somehow make the built in timer0 interrupt handler optional, like the ISR only gets generated if millis (or micros) is called, otherwise anyone can do what they want with timer0 without using timer 1/2.  

RIDDICK

#66
Dec 07, 2008, 06:53 pm Last Edit: Dec 08, 2008, 09:08 am by RIDDICK Reason: 1
in the initial idea the while-loop should be a simple "if", because that saves in the rare case an unnecessary comparison...

have u seen this thread:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1227051174/0#11 ?
it includes some enhancements during cli-phases... about factor 2 at 16MHz...

then i think in millis() we could use this trick:
instead of "cli() ... restore SREG"
we use "register int safe = VAR, result; while ((result=VAR) != safe) safe = result; return result;"
if the interrupt happens after the first byte of VAR is read, the second read would recognize that...
this would make sure, that we do not spend more time with interrupts disabled than necessary... calling cli() introduces the risk of missing about a milli second (at 16MHz), doesn't it?
btw: the comment is wrong/misleading (timer0_millis++ can't be interrupted)

i have another enhancement, that is similar to the initial idea (but with a 12byte cache for millis and remainder and the counter)...
is somebody interested?
-Arne

bussy77

This whole discusion is very close to what I'm looking for, but I need everybody's help.  What I need to do is measue time in microseconds, from an event to an event.  Like how much time it takes for a trigger, and then as soon as that trigger is tripped the timer starts again from zero, and that just goes on forever and ever.  The average time that will be measured is between 10 and 80 milliseconds, but I need more resolution hence the need for microseconds.  If possible I would like it to reset everytime it figures out the elapsed time.  If the reset could be done I will have no problem with overflow.

RIDDICK

#68
Dec 11, 2008, 01:33 am Last Edit: Dec 11, 2008, 01:35 am by RIDDICK Reason: 1
@bussy77:
if there r no multiple overflows between 2 micro()-calls, u may just subtract the 2 numbers (stored value (last micro()) and new value)...

binary numbers r so friendly:
example: :P
let a,b be 1-byte-integers (unsigned char)
a=250, b=5
b - a = (5 - 250) mod 256 = 5 + ((~250)+1) mod 256 = 5 + (5+1) = 5 + 6 = 11 *yahoo!*  :D
-Arne

bussy77

But the problem is that I not able to get any microsecond timings.  I'm kinda new to this, I do have a fair amount of knowledge with the arduino and programming, just nothing this complex before.

RIDDICK

#70
Dec 11, 2008, 02:00 pm Last Edit: Dec 11, 2008, 02:02 pm by RIDDICK Reason: 1
@bussy77:
here u can find the function micros():
http://svn.berlios.de/viewcvs/arduino/trunk/hardware/cores/arduino/wiring.c?view=markup
(URL taken from the first page of this thread)
(maybe it will be necessary to include "wiring_private.h" somehow, if u copy the function into ur own program)
(or u wait for arduino-0013)  ;)
-Arne

bussy77

Is there a way to reset the clock to make everything easier?

RIDDICK

hm - i dont think so...

is a subtraction and maintaining a further state-variable so complicated?
-Arne

bussy77

It's not really that hard at all.  How long does it take for it to overflow?

mikalhart

#74
Dec 11, 2008, 02:49 pm Last Edit: Dec 11, 2008, 02:50 pm by mikalhart Reason: 1
Quote
Is there a way to reset the clock to make everything easier?


Yes.

Code: [Select]
void ResetSystemClock()
{
 extern volatile unsigned long timer0_overflow_count;
 extern volatile unsigned long timer0_clock_cycles;
 extern volatile unsigned long timer0_millis;

 uint8_t oldSREG = SREG;
 cli();
 timer0_overflow_count = timer0_clock_cycles = timer0_millis = 0;
 SREG = oldSREG;
}


(This is for the prerelease version referenced above.  For v. 0012, remove the references to timer0_overflow_count.  And, as always, it's generally bad practice to rely upon undocumented features.  This will very likely break in a future release.)

Go Up