zanor
Member level 4
Just for fun I'm trying to make a digital RPM meter for my car. But I'm not able to get exact readings.
I have measured with an oscilloscope that there should be ~0,06802721 sec (14,7Hz) between the pulses when my engine is idling. "TMR_count" in my source code should be 66 then. But I'm getting 61. It is ~0.00512 sec too slow, why?
Is there some delays in timer/interrupt operation I don't know?
I am using a PIC16F84a on a breadboard. Could the "long" way from the crystal to the microchip slow it down? Cables are ~3-4 cm...
Here is my code, in MikroC format.
I have measured with an oscilloscope that there should be ~0,06802721 sec (14,7Hz) between the pulses when my engine is idling. "TMR_count" in my source code should be 66 then. But I'm getting 61. It is ~0.00512 sec too slow, why?
Is there some delays in timer/interrupt operation I don't know?
I am using a PIC16F84a on a breadboard. Could the "long" way from the crystal to the microchip slow it down? Cables are ~3-4 cm...
Here is my code, in MikroC format.
Code:
#include <built_in.h> // For Lo(); & Hi();
int i = 0;
int TMR_count = 0; // 1x = 0.001024 sec
int TMR_value = 0; // 1x = 0.000004 sec
int RPM = 0;
float TIME = 0;
void interrupt() {
if (INTCON.INTF)
{
if (i <= 63)
{
TMR_value = TMR0;
TMR0 = 0;
TIME = (TMR_count * 0.001024) + (TMR_value * 0.000004); // Time between two sparks
RPM = (1 / TIME) * 60; // RPM , 2 coiler and wasted spark = 1 spark/revolution
EEPROM_WRITE(i, TMR_count);
i++;
EEPROM_WRITE(i, TMR_value);
i++;
TMR_count = 0;
}
INTCON.INTF = 0;
}
if (INTCON.T0IF)
{
TMR_count++;
INTCON.T0IF = 0;
}
}
void main() {
PORTA = 0;
TRISA = 0b00001000;
PORTB = 0;
TRISB = 0b00000001;
PORTB.B3 = 1;
Delay_MS(1000);
PORTB.B3 = 0;
INTCON.RBIF = 0;
INTCON.GIE = 1; // Enable Interrupts
INTCON.INTE = 1; // Enable Interrupt on RB
INTCON.T0IE = 1; // Enable timer 0 owerflow interrupt
OPTION_REG = 0x81; // Pullups DISABLED!!!
while(1);
}