IR Tachometer With Debounce Code

by wierzbickimc in Circuits > Arduino

60 Views, 1 Favorites, 0 Comments

IR Tachometer With Debounce Code

IMG_7026.jpg

There are quite a few good IR based tachometer instructions out there, but the IR module I have seems very susceptible to bounce (seeing 10's or 100's of on/offs per transition.) No matter what I did with sensitivity, I could not get an accurate count.

Using the interrupts approach seems like the correct way to go, but also prevents the use of the typical delay() function to ignore bounces. Also, hardware changes were not appealing.

There is also a great instruction for adding debouncing (filtering) to the sketches that use interrupt, but it took me far longer than I'm willing to admit for figure out where everything fit into the code.

This sketch below is a combined application of both.

The intended application is for a diesel MK1 Rabbit. They didn't come with tachometers and I thought it would be cool to use the camshaft gear to count RPM.


Proof of concept video below!

Downloads

Supplies

Arduino Nano

Arduino Nano screw terminal shield

IR sensor module (should have a clear, black, and knob for potentiometer) like this

The Code

volatile unsigned int counter = 0; // Counter variable for revolutions
unsigned long previousMillis = 0; // Variable to store previous time
unsigned int rpm = 0; // Variable to store RPM value
int readFreq = 1000;
//volatile int objects;

volatile unsigned long last_micros;
long debouncing_time = 10; //Debouncing Time in Milliseconds


#include <SoftwareSerial.h>// this is needed for Bluetooth
SoftwareSerial BlueTooth(10, 11 ); // RX, TX for bluetooth, not needed for the tach.


void setup() {

Serial.begin(9600);
Serial.println("serial check");
BlueTooth.begin(9600); // Turn on bluetooth serial output
BlueTooth.println("Bluetooth On ");
}


void debounceInterrupt() {
if((long)(micros() - last_micros) >= debouncing_time * 1000) {
Interrupt();
last_micros = micros();
}
}
void Interrupt() {
counter++;

}
void loop() {

unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= readFreq) {
detachInterrupt(digitalPinToInterrupt(3));
rpm = (counter / 6) * 60 * 2; // Calculate RPM. Remember Camshafts spin at 1/2
// the RPM of the crankshaft; multiple result by two

Serial.print(rpm);
BlueTooth.print("RPM:");
BlueTooth.println(rpm);
Serial.print (". Count. ");
Serial.println(counter);
counter = 0;
attachInterrupt(digitalPinToInterrupt(3), debounceInterrupt, FALLING);
previousMillis = currentMillis;

}


}