Hi, im a racing dad for two girls in power boating, i got tired of running up and down from the jetty downloading data logger data so i made a telemetry box with a mega, gps, gyro and a 433 mhz transmitter. that works ok, i receive data on a raspberry pi running node red to display the info from the box. The problem is RPM, both engines has one cable that is to be used for rpm and tachometer, i have checked the signal and its digital and around 5 volt. Problem is that when the rpm goes over 4500 its starts to be unstable almost like it just counts half. There are 6 magnets under the flywheel so i have a divider in the code that divide it by 6. I have also had problem with other data loggers bought like AIM and Starlane with same problem. If I use the original analog tachometer it works fine. Anyone got any idea what the problem could be ? can it be to much to handle for the mega ? 4500 rpm x 6 magnes is 27000 signals ?.
Please read the first post in any forum entitled how to use this forum. http://forum.arduino.cc/index.php/topic,148850.0.html .
Then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.
Have you used a pulse generator to simulate the RPM input on the bench?
Have you tried a hardwired divide by 6 before the Arduino?
The problem is RPM, both engines has one cable that is to be used for rpm and tachometer,
Could that be because what a tachometer shows is engine RPM?
You may be getting unstable reads at 4500+ because of the code that you have not posted only keeps up till then.
You have another possible weak point in the RPi if it is also expected to count pulses.
Unless there is something extra tricky about these pulses, Arduino should be able to count over 45000/sec while printing results about 10x/sec and still have many cycles to spare.
Just from the description I'd also say it is a program resource issue.
I guess you are using external interrupts and may have packed either too much code in the interrupt service routine or your loop() is too heavy and missing samples. That, or you are de-bouncing samples and the dead period is now too long.
void ignitionIsr()
{
unsigned long now = micros();
unsigned long interval = now - lastPulseTime;
if (interval > 2000)
{
rpm = 60000000UL / (interval * pulsesPerRev);
lastPulseTime = now;
}
}
That check for interval being over 2000 means that if the interval between pulses are any shorter, you ignore them. That happens at around 5000 rpm. It also explains why you see half the actual rpm then.
An easy test would be to reduce that 2000 to 1000 or so. What is the maximum rpm the engine will be hitting?
Really though, it needs a rewrite. Interrupt service routines are intended to be as short and fast as possible. It would be more conventional to simply use it to count pulses and do the rpm calc in the main code.