Hey, y'all...it's Curbside from Texas. I was wondering if y'all could be of assistance, as I'm at a bit of a dead end with my project. Before going any further, I'll ask that y'all forgive me for being such a noob. Aside from a bit of HTML back in college and some AppleBasic from when I was in junior high, I haven't done a whole lot of programming! The Arduino Mega board I'm using is my first experience with the Arduino family, and I'm only about a week into it.
Project background: I'm working on a digital dashboard for a race bike, importing signals from the bike into the Arduino Mega and exporting them via HC-05 Bluetooth to an Android tablet running the “RealDash” app. RealDash is typically used by folks with fuel-injected vehicles, but they have released CAN and example files so people can build application-specific hardware with the Arduino boards when used with old-school carbureted vehicles like my Harley.
I have a square-wave 50%-duty pulse going into an input pin, let's use Pin 4 as the input. The pulse is of varying frequency, as it's coming from the “Tach Output” lead from my bike's ignition module (and yes, I've reduced the voltage via a voltage divider circuit, down to 4v). The frequency will range anywhere from 0 to 75 pulses per second, but will generally be below 30 pulses per second. Because the data will need to be sampled about 20x per second to keep the gauges from getting jittery, I'm assuming I'll need to be timing the pulses, as opposed to counting the number of pulses in a given time period.
I need that input to be calculated as variable “RPM” for use elsewhere in the sketch.
I have no idea how to code that! If any of y'all out there could help me out with this, it'd be greatly appreciated!
Because the data will need to be sampled about 20x per second to keep the gauges from getting jittery, I'm assuming I'll need to be timing the pulses, as opposed to counting the number of pulses in a given time period.
I'm guessing (because you are not very clear) that when you say "the data will need to be sampled about 20x per second to keep the gauges from getting jittery" you are referring to the data being sent from the Mega to the Tablet.
The frequency of that data can be entirely independent of the method for timing the pulses.
If the interval between pulses represents the RPM then I would detect the pulses using an interrupt and for each pulse save the value of micros(). To figure out the speed just subtract the previous saved value from the new value. I use that system with a small DC motor that runs up to 15,000 RPM.
If the pulse really is 50%-duty then you could use the pulseIn() function
The input period for, say, 1 to 75 pulses per second = 1,000,000uS to 13,333uS
50% of that period is 500,000uS to 6,666uS
#define TACH_PIN 4
unsigned long microsecs;
// read HIGH part of input pulse, timeout if it's longer than 500000uS
microSecs= pulseIn( TACH_PIN, HIGH, 500000 );
if( (microSecs == 0) || (microSecs >= 500000) )
rpm= 500000.0 / (float)microsecs;
Note that the program will stop while it is timing the input pulse, if you need to do other things at the same time you will have to take up Robin2's suggestion of an interrupt
To use interrupts, move the signal to one of these pins: 2, 3, 18, 19, 20, 21.
Of course if the RPM's drop to 0 you will stop getting pulses. You should include some code to check for a "really long delay since the last pulse" and report that as 0 RPM.