I wrote this code for measuring the rpm of a fan. I think it can be adapted. It works by timing a specified number of pulses (by the saples constant). The NoSensors determines the number of pulses/revolution. Just change these constants to suit your needs.
The code is based on my state machine libray found here: Arduino Playground - SMlib
#include <SM.h>
const int Samples = 32;
const int NoSensors = 3;
const unsigned long TimeBase = 60000;//one min
SM Rpm(RpmReset, RpmCount);//statemachine for counting
int RpmPulseCount;
int Speed;
int RpmEncState;
SM EachSec(ES, ESwait);//statemachine for display
void setup(){
Serial.begin(115200);
Serial.println("ready..");
}//setup()
void loop(){
EXEC(Rpm);
EXEC(EachSec);
//your code goes here, must be non-blocking
}//loop()
State RpmReset(){
RpmPulseCount=0;
}//FanReset()
State RpmCount(){
if(RE(digitalRead(2), RpmEncState)) RpmPulseCount++;
if(RpmPulseCount == Samples){
Speed = TimeBase*Samples/NoSensors/Rpm.Statetime();
Rpm.Restart();
}//if(FanPulseCount)
}//FanCount()
State ES(){
Serial.print("Rpm: ");
Serial.println(Speed);
}//ES()
State ESwait(){
if(EachSec.Timeout(1000)) EachSec.Restart();
}//ESwait()
There are two basic ways of calculating rpm by measuring pulses.
Measure the time between two (or any fixed number of) pulses. This will give a value that is proportional to the rotation period and inversely proportional to the rotating frequency. This method gives the best results when the number of counted time intervals is high, meaning accuracy is best in the low range
Measure the number of pulses during a fixed time period. This will give you a value that is proportional to the rotational frequency. This method gives the best accuracy when the number of counted pulses is high ie in the high measuring range.
My program uses the first method an increases accuracy by using a selectable number of pulses. This is done by setting the Samples constant to an appropriate value depending on the desired measuring range. The higher this value the greater accuracy but the slower the response. If you are using a sensor configuation that produces multiple pulses per revolution this should be reflected in the NoSensors constant.
Time is measured in milliseconds and the desired output value is in rpm so the TimeBase constant is set to 60(s/min)*1000(ms/s)=60000.
The rpm value is calculated in this line:
TimeBase*Samples/NoSensors/Rpm.Statetime()
For example suppose you have a 3-bladed fan rotating at 120 rpm and each blade triggering the sensor. In this case NoSensors should be 3. 120 rpm means 500ms/rev and 3 pulses/rev gives you a pulse time of 166,7 ms. After 32 pulses the Rpm.Statetime function should return a value of approximately 5333.
If we check: 6000(TimeBase)*32(NoSaples)/3(NoSensors)/5333(Time for 32 pulses) = 120 (plus some fraction that will be truncated)