Go Down

Topic: Timer2 problem (Read 939 times) previous topic - next topic

Hauge

Don´t know if this is the right sub-forum for this topic or not but here is my problem.

I need to count pulses from an external source (a VR speed sensor, signal converted to square wave with fixed amplitude).
My arduino already contains time sensitive code (ignition control for a 8 cyl engine)

I cannot use a interrupt directly because of the frequency of the signal (12 Hz at 1 km/h) since I believe that the interrupts will interfere with the timing at high speed.

I decided to use the eight bit internal timer2 with no prescaler and use the output compare match function, together with an external clock for that timer to get reasonable update of speed  at 0,2-0,3 s interval. The external clock would then be the square wave signal from the speed sensor

Today when i studied the datasheet it said to use the TOSC1 pin ... ok which one is that?....oh that one...BUT IT IS ALREADY OCCUPIED BY THE 16 MHz CRYSTAL.... *ARRRGH*.

So now I am a little frustrated.

As i see it i have two options
1: Try using a interrupt directly anyway... me no like
2: Learn some more elektronics to use an external counter/divider an connect a interrupt to that one (= 1 interrupt per 100 pulses)
A count to 100 from the external counter gives me a update frequency of 0,27s at 30 km/h.. could live with that, but at 220 km/h (yes, illegal) its every 4 ms, which means that it could interfere with every second ignition pulse. At that rpm i need to time my ignition pulse about 26 us accuracy (= 1 degree of ignition advance). If it interferes with a timing pulse its to often

No 2 might, maybe, perhaps work to my liking IF the interrupts has different priorities. The Atmel datasheets suggests that they might have, but every thread in the forums say that thay have equal priority.
Nah.. when i come to think about it, i´m using timer1 interrupts already for the precise timing and that interrupt is lower in the interrupt list than external interrupts.... *sigh*

Any bright idea anyone ???





ArduinoM

How about ditching the external crystal and use the 4MHz internal instead?
You would have to use lillypad config to upload sketches though......

D.

Coding Badly


dafid

So 26 uSec is 416 clocks.

You could write your own interrupt handler that does not block further interrupts..

http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

See the section that talks about this.
Code: [Select]
ISR(XXX_vect, ISR_NOBLOCK)


Then the additonal latency that the timer interrupt could add would be the 5 clocks to set up the interupt, one more for the SEI, and one or two more more for the instruction after the SEI (which is always executed before the interrupt is taken).

That seems quite small to me, relative to the 416 clocks that 26 uSec accuracy represents.

Hope this helps - have fun



ArduinoM

Sorry 8MHz, was thinking of this:
http://www.arduino.cc/playground/Learning/Atmega83-3V
and this
http://www.sparkfun.com/products/9220

The arduino pro mini is running on the internal 8MHz of the 328 chip
so the pin is not used ;)

You could just use the guide from the sparkfun site on using it. If you are comfortable with halving the speed of processing ....

D.

ps: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1257928887

Hauge

thanks for the quick replies :-)

(and its a arduino uno)
Changing processor speed could be done of course. I have to think about it implications regarding accuracy and other implications. One thing that comes up is that the code that calculates all the data and sets timer 1 to give a interrupt when its time to charge the coil takes 92-96 us.. half speed means 92-96 less available time for charging the coil (dwell).. it should work fine anyway... buts it does not feel good. (The coil discharge is handled by timer1 itself)

A interrupt that does not interfere with other more important interrupts :-) ... more my melody.. if the speed calc has to wait a ms (would be less) doesnt matter. It would be far more accurate that the cheap factory speedo from 1975 anyway (and i have changed the rear axle ratio, so i have to approximate the speed based on what the meter says). The processor hasnt anything important to from the time the coil charges til it discharges.. which is between 1,8-3,2 ms if i remember correctly.. plenty of time if the interrupt can wait.

I´ll look into "ISR_NOBLOCK"   :-)


THANK YOU




Hauge

aha...  ISR_NOBLOCK tells the compiler to put a _sei (enable global interrupts) directly on the first line of the interrupt code.

I suspect one could put that statement manually instead in the C-code.

If i understand it correctly: If I get another 2:nd interrupt during the execution of the first one (with isr_noblock) the code will continue when the 2:nd is finished. If so, it would work fine as long as the code in "isr_noblock" is short enough to aviod further nesting of interrupts.




dafid

That is correct, but the ISR_NOBLOCK puts it before the registers are pushed onto the stack, reducing the impact on the latency.

And when writing interrupt driven code, the impact of 'too slow' is harder to understand than in simple procedural code, so you do need to be careful how it is written.


Go Up