Hi, im still new to PIC microprocessor programming and im busy with a project that i need to test in a car. I need to calculate the rpm of the engine. I am using the PIC16F877 with the primary side of the ignition coil of the car connected to RB0 via an opto-isolator.
The problem i am having is that the rpm reading is not very accurate and fluctuates all over the place.
This is the code for calculating RPM,
#define INTERRUPT_PERIOD 0.0000357 // 35.7uS at 20MHz
#define COUNTER_0_PRELOAD 189
#INT_TIMER0
void TIMER0_isr(void) //TMR0 interrupt is generated when the TMR0 register overflows
{
Timer0_Overflow_Counter++; // Increment the counter
(char) TMR0 = COUNTER_0_PRELOAD; // Preload Timer0
T0IF = 0; // Reset the TMR0 interrupt flag
}
#INT_EXT
void RB0_isr(void) //RB0 interrupt is generated on every falling edge of RB0/INT pin
{
Interrupts_Per_Revolution = Timer0_Overflow_Counter;
RPM = 1/(Interrupts_Per_Revolution * INTERRUPT_PERIOD);
RPM = 60*RPM;
Timer0_Overflow_Counter=0;
INTF=0;
}
Any suggestions to what could be the problem?
Calculating RPM?
Hey hits,
The code posted looks like C so perhaps posting in the forum for that would get more results, but as for the theory behind what you're doing..
First off the variable Timer0_Overflow_Counter I hope is at least 16 bits since that counter will probably overflow an 8-bit counter.
Second, engine RPM varies a LOT even though it seems like it is stable. Deriving RPM from an ignition signal is difficult since whatever system is governing ignition will vary timing and coil dwell and that can cause variations.
Third, you don't seem to account for more than 1 cylinder. The calculation seems to assume there is 1 ignition per revolution, which would only work for a 1-cylinder two-stroke, or a 2-cylinder four-stroke engine.
You may want to consider averaging the readings over several revolutions to reduce fluctuations. I don't know what you are doing with the RPM data, but if you are displaying it on a digital readout, a few averages will probably help.
- Droz
The code posted looks like C so perhaps posting in the forum for that would get more results, but as for the theory behind what you're doing..
First off the variable Timer0_Overflow_Counter I hope is at least 16 bits since that counter will probably overflow an 8-bit counter.
Second, engine RPM varies a LOT even though it seems like it is stable. Deriving RPM from an ignition signal is difficult since whatever system is governing ignition will vary timing and coil dwell and that can cause variations.
Third, you don't seem to account for more than 1 cylinder. The calculation seems to assume there is 1 ignition per revolution, which would only work for a 1-cylinder two-stroke, or a 2-cylinder four-stroke engine.
You may want to consider averaging the readings over several revolutions to reduce fluctuations. I don't know what you are doing with the RPM data, but if you are displaying it on a digital readout, a few averages will probably help.
- Droz
Hey Droz,
Thanks for the reply.
- All rpm measuring products, eg rev counters, that i know of get wired to the same point that i am tapping off for my reading, so im not sure where else to get the rpm reading from.
- Just remembered now that i need to multiply the RPM value by 30 instead of 60 for a 4 cylinder engine.
Any further suggestions?
Thanks for the reply.
- All rpm measuring products, eg rev counters, that i know of get wired to the same point that i am tapping off for my reading, so im not sure where else to get the rpm reading from.
- Just remembered now that i need to multiply the RPM value by 30 instead of 60 for a 4 cylinder engine.
Any further suggestions?
Droz wrote:Hey hits,
The code posted looks like C so perhaps posting in the forum for that would get more results, but as for the theory behind what you're doing..
First off the variable Timer0_Overflow_Counter I hope is at least 16 bits since that counter will probably overflow an 8-bit counter.
Second, engine RPM varies a LOT even though it seems like it is stable. Deriving RPM from an ignition signal is difficult since whatever system is governing ignition will vary timing and coil dwell and that can cause variations.
Third, you don't seem to account for more than 1 cylinder. The calculation seems to assume there is 1 ignition per revolution, which would only work for a 1-cylinder two-stroke, or a 2-cylinder four-stroke engine.
You may want to consider averaging the readings over several revolutions to reduce fluctuations. I don't know what you are doing with the RPM data, but if you are displaying it on a digital readout, a few averages will probably help.
- Droz
Perhaps if you could indicate what exactly its doing wrong then it would be easier to suggest more options. First things that come to mind are:
some kind of ripple or ringing on that line that is causing multiple triggering of the interrupt, or possibly EMI causing false triggers. Auto environments are notoriously hard to get good clean signals.
Do you have access to a scope you could trace the input with and make sure you're getting a clean signal?
- Droz
some kind of ripple or ringing on that line that is causing multiple triggering of the interrupt, or possibly EMI causing false triggers. Auto environments are notoriously hard to get good clean signals.
Do you have access to a scope you could trace the input with and make sure you're getting a clean signal?
- Droz
Yes it is, i am just trying to use their setup with the caps to see if that will help. I have had a look at their code but cant seem to figure out how they calculating RPM.
I have found that some people are using the capture and compare module to calculate RPM, im not sure if this would be a more stable option...
I have found that some people are using the capture and compare module to calculate RPM, im not sure if this would be a more stable option...
Droz wrote:Thats an exact duplicate of the Megasquirt tach input signal (even so far as labeling the 4N25 as U4). Perhaps you can look over their source code to see how they are stabilizing the rpm input.
-
- Posts: 573
- Joined: 25 Apr 2006 15:39
- Location: Cape Town, South Africa
I still fail to see how this circuit can work
RB0 is shorted to ground, via the 0.01, I assume uF ?, capacitor.
I'm not too clued up on what pulse duration the pick needs, but I would expect to see somewhat more intricate pulse shaping happening.
Even on the low voltage end of the coil, there might just be enough ringing to bugger up your input to the pic.
The ideal would be some form of monostable, to give a clean pulse into the pic.
Giving away my age here, but many years ago a mag called ETI had a bunch of articles on CDI's, tacho's, etc, all analogue stuff, but the pulse shaping was of prime importance, for accurate results.
RB0 is shorted to ground, via the 0.01, I assume uF ?, capacitor.
I'm not too clued up on what pulse duration the pick needs, but I would expect to see somewhat more intricate pulse shaping happening.
Even on the low voltage end of the coil, there might just be enough ringing to bugger up your input to the pic.
The ideal would be some form of monostable, to give a clean pulse into the pic.
Giving away my age here, but many years ago a mag called ETI had a bunch of articles on CDI's, tacho's, etc, all analogue stuff, but the pulse shaping was of prime importance, for accurate results.
"Copy'nPaste"
RB0 input has a Schmitt trigger input so that should also help getting a "cleaner" input signal
Copy'nPaste wrote:I still fail to see how this circuit can work :?
RB0 is shorted to ground, via the 0.01, I assume uF ?, capacitor.
I'm not too clued up on what pulse duration the pick needs, but I would expect to see somewhat more intricate pulse shaping happening.
Even on the low voltage end of the coil, there might just be enough ringing to bugger up your input to the pic.
The ideal would be some form of monostable, to give a clean pulse into the pic.
Giving away my age here, but many years ago a mag called ETI had a bunch of articles on CDI's, tacho's, etc, all analogue stuff, but the pulse shaping was of prime importance, for accurate results.
-
- Posts: 231
- Joined: 14 Nov 2004 19:43