Best Sensor for RPM counting.

I am very new to building electronic stuffs because of our school project.
i am building a 3 bladed fan with motor controlled via arduino but i need to read the RPM of the fan.
I tried using infrared sensors but it does not work as expected and give random readings but was able to detect if the blade
of the fan is passing.
I am now thinking of using Hall effect sensor to count the RPM.
Do you think the Hall effect sensor is a better sensor for RPM? or is there anything else?

This is the link on for the schematic of the motor: http://www.instructables.com/files/deriv/F9L/KDFG/GU7FXUMH/F9LKDFGGU7FXUMH.LARGE.jpg

link for the schematic of the IR sensor

Thank you

Using the hall sensor would be a good way to measure the RPM. I'm using it myself to measure the RPMs of an anemometer.
The only problem I see in your situation could be the placement of the magnet that has to trigger the hall sensor.
(quiet large weight displacement, off-center, can result in vibrations etc.) But once u can detect a changing flank on the interrupt pin that's connected to your hall sensor, you will be able to measure the period between two pulses, and thus the RPM.
RPM = 60* frequency = 60* 1/period(in seconds) = 60.0/period and /1000 if you measure it in millis or /1000.000 if you measure it in micros.

This is what I use to determine the period of the pulses generated by my hall sensor:

long int t1,t2;
long int periode = 0;

void setup(){
attachInterrupt(0, interrupt, FALLING);
}

void interrupt() {
  noInterrupts();
  t2 = millis();
  periode = (t2 - t1);
  t1 = millis();
  //Serial.println(i);
  interrupts();
}

Are you using the ir sensor as an reflective sensor or do you let the fan blade interrupt the beam? I believe the latter is safer and also easier to test.

Here is some code that counts rmp without using interrups. Instead I uses my statemachine libray as a timer/sheduler
the library can be found here: Arduino Playground - SMlib
The example outputs to serial, you have to change that to LCD

#include <SM.h>

const int Samples = 32;
SM Fan(FanReset, FanCount);
int FanPulseCount;
int FanRpm;
int FanEncState;
const int NoBlades = 3;


SM EachSec(ES, ESwait);

void setup(){
  Serial.begin(115200);
  Serial.println("ready..");
}//setup()

void loop(){
  EXEC(Fan);
  EXEC(EachSec);
  //your code goes here, must be non-blocking
}//loop()

State FanReset(){
  FanPulseCount=0;
}//FanReset()

State FanCount(){
  if(RE(digitalRead(2), FanEncState)) FanPulseCount++;
  if(FanPulseCount == Samples){
    FanRpm = 60000*Samples/NoBlades/Fan.Statetime();
    Fan.Set(FanReset, FanCount);
  }//if(FanPulseCount)
}//FanCount()

State ES(){
  Serial.print("Fan rpm: ");
  Serial.println(FanRpm);
}//ES()

State ESwait(){
  if(EachSec.Timeout(1000)) EachSec.Set(ES, ESwait);
}//ESwait()

nilton61:
Are you using the ir sensor as an reflective sensor or do you let the fan blade interrupt the beam? I believe the latter is safer and also easier to test.

Here is some code that counts rmp without using interrups. Instead I uses my statemachine libray as a timer/sheduler
the library can be found here: Arduino Playground - HomePage
The example outputs to serial, you have to change that to LCD

#include <SM.h>

const int Samples = 32;
SM Fan(FanReset, FanCount);
int FanPulseCount;
int FanRpm;
int FanEncState;
const int NoBlades = 3;

SM EachSec(ES, ESwait);

void setup(){
  Serial.begin(115200);
  Serial.println("ready..");
}//setup()

void loop(){
  EXEC(Fan);
  EXEC(EachSec);
  //your code goes here, must be non-blocking
}//loop()

State FanReset(){
  FanPulseCount=0;
}//FanReset()

State FanCount(){
  if(RE(digitalRead(2), FanEncState)) FanPulseCount++;
  if(FanPulseCount == Samples){
    FanRpm = 60000*Samples/NoBlades/Fan.Statetime();
    Fan.Set(FanReset, FanCount);
  }//if(FanPulseCount)
}//FanCount()

State ES(){
  Serial.print("Fan rpm: ");
  Serial.println(FanRpm);
}//ES()

State ESwait(){
  if(EachSec.Timeout(1000)) EachSec.Set(ES, ESwait);
}//ESwait()

I am using the IR as interrupt but gives wrong reading. It even reads values if i turned on the motor at low voltage using
arduino since i put them all in one breadboard.
BTW the motor is a brushed 12v motor

If you are trying to power the motor from the Arduino, DON'T!
Doing so will create several different problems.

Also, don't expect even a brand new 9V PP3 battery like that illustrated in your diagram to run a motor for any significant length of time. For a small motor, and for learning purposes, you can try a 4xAA battery pack.

I am using an external power source of 12v to power the motor. Can the Hall Effect sensor be used on a brushed motor?
And what do you think is the problem with the infrared sensors? The infrared sensor can detect if the fan blade had passed the sensor but it seems like calling the interrupt function more than once than it should be. I am displaying the result to my computer using Serial connection.

I noticed once when i was building an rpm counter that the IR beam went straight trough white plastic. Gluing some paper on fixed that.

There is a possibility that the magnetic field from the motor can interfere with the hall sensor id it is too close. You have to try

nilton61:
I noticed once when i was building an rpm counter that the IR beam went straight trough white plastic. Gluing some paper on fixed that.

There is a possibility that the magnetic field from the motor can interfere with the hall sensor id it is too close. You have to try

But my fan blades are black. It seems like the infrared lights flicker that is why the receiver reads many values?