Xyvind Kaurstad [oyvind@SAFETEL.NO] wrote: > Ok, guys. > > I'm having some trouble, and I can't get it figured out. > > I'm building a device that's sampling the RPM of an engine. > The incoming signal is therefore in the range of max 350 Hz, and it > is connected to RB0. > > I need to accurately count the time *between* pulses, to get a number > that is inversely proportional to the RPM. > > The TMR0 and the external interrupt is used. (16F84) > > I've programmed the TMR0 to run with a prescaler of 1:2, so the TMR0 > frequency should be 1.25 MHz. > So that would be a 10MHz crystal then? > I want to have a 16 bit counter, so in the interrupt routine I > increment a register for each TMR0 interrupt. This is the high byte > of my counter. > > When the external interrupt occurs, I read both the TMR0 and this > register. Together they are transferred to another 16 bit variable > that is used by the rest of the code. Then the TMR0 and the high byte > register is cleared, and I exit the ISR. > > What troubles me is that I get a lot of jitter on my count value. > A lot more than I would expect. The latency of the TMR0 interrupt > should not bother me, since in the part of the ISR that handles this > I just increment the high byte and then exits. The TMR0 itself is not > tampered with. > > The latency that I get when the external interrupt occurs will cause > a little bit of jitter, since I'm reading the TMR0, but it shouldn't > be more than a couple of bits, especially since the TMR0 is running > at half the instruction cycle. > > Any good hints? > > I don't have the code here, but I can post that later if necessary. > Ok, I did almost exactly this about 6 months back. It was for a digital tachometer which also used software PWM to drive a conventional meter movement and had all sorts of bells and whistles such as max RPM memory. All on a 16F84 with lots of room to spare. I didn't bother with the external interupt to detect the ignition pulses, I just used polling as the frequency was so slow. I did use TMR0 with another 8 bit register though. Jitter was a problem. The reason is that you are measuring the period between sparks with a very high precision, and engines just do not run at constant speed. In fact even during one revolution the crank doesn't turn at a constant velocity. The fewer cylinders the engine has, the worse this effect is. Unfortunately you need 16 bits because of the dynamic range of the counter. Unless you use a large counter, it will either overflow at low RPM or run out of resolution at higher RPM. What I did was to convert to RPM, and feed the results into a simple (digital) low pass filter. I could get a reading steady to within a few RPM on a 4 cylinder engine this way. You could lose either one or two significant figures depending on your requirements. A least significant digit which constantly changes is very irritating, I'd rather not see it :o) Cheers Mike