Go Down

Topic: Code for Optical Motor Speed Sensor (Read 7137 times) previous topic - next topic


Can anyone point me in the right direction for some code to run a :

OptoCoupler Optical Sensor Motor Speed Counter Sensor For Arduino AVR H2010 RC

We're modifying a hard drive and hard drive motor and would like to be able to measure RPMs.

Any help would be awesome. Let me know if additional info is needed. All we would really need is to output RPM to the console.



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: http://playground.arduino.cc/Code/SMlib
Code: [Select]
#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(){

void loop(){
  //your code goes here, must be non-blocking

State RpmReset(){

State RpmCount(){
  if(RE(digitalRead(2), RpmEncState)) RpmPulseCount++;
  if(RpmPulseCount == Samples){
    Speed = TimeBase*Samples/NoSensors/Rpm.Statetime();

State ES(){
  Serial.print("Rpm: ");

State ESwait(){
  if(EachSec.Timeout(1000)) EachSec.Restart();


What is meant by "const int NoSensors = 3;"


"NoSensors" is short for "number of sensors".
It's not going to change so it's a constant, and you can't have a part sensor, so it is an integer


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:
Code: [Select]

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)

Go Up