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
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.
(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.
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.
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.