A while back I discussed a IR emitter / detector pair, and talked about building a optical tachometer for determining the RPM of a fan or motor. So now I’m making good on that promise. Connect the emitter / detector as shown in the previous post, using pin 2 on the Arduino (interrupt 0). Put something reflective on one blade of the fan, or cover one half of the motor shaft with black tape, to get one trigger per revolution. We based this project on the work found at http://elimelecsarduinoprojects.blogspot.com/2013/06/measure-rpms-arduino.html.
Become the Maker you were born to be. Try Arduino Academy for FREE!
// based on http://elimelecsarduinoprojects.blogspot.com/2013/06/measure-rpms-arduino.html
// read RPM and calculate average every then readings.
const int numreadings = 10;
int readings[numreadings];
unsigned long average = 0;
int index = 0;
unsigned long total;
volatile int rpmcount = 0;
unsigned long rpm = 0;
unsigned long lastmillis = 0;
void setup(){
Serial.begin(9600);
attachInterrupt(0, rpm_fan, FALLING);
}
void loop(){
if (millis() – lastmillis >= 1000){ //Update every one second, this will be equal to reading frequency (Hz).
detachInterrupt(0); //Disable interrupt when calculating
total = 0;
readings[index] = rpmcount * 60; // Convert frequency to RPM, note: this works for one interruption per full rotation. For two interrupts per full rotation use rpmcount * 30.
for (int x=0; x<=9; x++){
total = total + readings[x];
}
average = total / numreadings;
rpm = average;
rpmcount = 0; // Restart the RPM counter
index++;
if(index >= numreadings){
index=0;
}
if (millis() > 11000){ // wait for RPMs average to get stable
Serial.print(” RPM = “);
Serial.println(rpm);
}
lastmillis = millis(); // Update lastmillis
attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
}
}
void rpm_fan(){ // this code will be executed every time the interrupt 0 (pin2) gets low.
rpmcount++;
}