Rpm measurement using a unipolar hall effect sensor

i am using a unipolar hall effect sensor to measure the rpm of a wheel,but my values are always in multiple of 60,i.e 60,120,240,360 and so on . i am posting my code as well,i got it from a link on the internet .kindly help

const int hallpin=2;
const unsigned long sampleTime=1000;
const int maxRPM=10200;


void setup()
{
pinMode(hallpin,INPUT);
Serial.begin(9600);}

void loop() 
{
int rpm=getrpm();
Serial.println(rpm);}

int getrpm()
{
 int kount=0;
  boolean kflag=LOW;
  unsigned long currentTime=0;
  unsigned long startTime=millis();
  while (currentTime<=sampleTime)
  {
    if (digitalRead(hallpin)==HIGH)
    {
      kflag=HIGH;
    }
    if (digitalRead(hallpin)==LOW && kflag==HIGH)
    {
      kount++;
      kflag=LOW;
    }
    currentTime=millis()-startTime;
  }
  int kount2rpm = int(60000./float(sampleTime))*kount;
  return kount2rpm;
}
  int kount2rpm = int(60000./float(sampleTime))*kount;

sampleTime is a constant, with a value of 1000. Dividing 60000.0 by 1000 results in 60.0, or so my calculator says.

Casting 60.0 to an int results in a value of 60. You then multiply that by some value, and wonder why you get multiples of 60. I'm confused about why you are confused.

Thanks for the reply,i know that the code there is taking the sample time as 1000 but when i replace the sample time with the current time in the calculation part ,i am getting anonymous values that like 59,119,... and i don t know what else can be viable option.

i know that the code there is taking the sample time as 1000 but when i

change the code, it doesn't work. Well, we need to see the new code.

Thanks for the suggestion paul, ill try for a new code.

Your code is unusual because most people use interrupts for these tachometers.

I believe that you are running into rpm confusion because you are indeed limited to a integral number of pulses received during your measurement cycle. For more sensitivity on low rpm, you may need more magnets on what is revolving.

For developing and debugging your code, you should be able to set up another Arduino as a pulse source to replace your hall sensor input. If you don't have a second Arduino, you could try having the receiving Arudino pulse itself , but I haven't tried this.

I am considering Installing more no of magnets , probably one more directly opposite to where i have installed now. Now that i know my code is incorrect ,the issue is to find or write an accurate code that can measure low rpm values as well.

a method i found over the internet to measure the rpm is that i count pulses over an extended sampling interval (like several or more seconds), divide the count by the interval and multiply by 60. This approach is perhaps the only solution when very low RPM values with a single pulse per revolution are encountered. For example, assume a shaft turning at 113 RPM produces one pulse per revolution. If we count revolutions over a 15 second interval we’d accumulate a total of 28 pulses. Dividing by the sampling interval (15) and multiplying by 60 yields 112, very close to the actual RPM value.,but the problem with this method is that i will always get an average rpm ,not a real one i.e if my initial rpm @ t=0s is 60 and then it decreases to 0 over the span of next 14 seconds my rpm value will still be shown as an average and not 0 at t=15s.

There are three basic approaches to to this problem. 1) count the number of pulses in a fixed period of time; 2) measure the period of time for a fixed number of pulses; and 3) measure the interval between individual pulses. The best approach will be determined by the frequency of the pulses, the accuracy you require, and the programming requirements and the hardware capability. The subject of pulse counting and associated frequency or rpm measurement is easily researched with Mr. Google and there are some quite sophisticated variations on the basic themes.

I would also recommend that you do some research on coding for moving averages to help smooth out some of the jumpiness inherent in measurements which are limited to integer counts if you choose to follow approach #1.

Can you please provide me with an accurate code for measuring time between the pulses,if u see to the code that i have uploaded in my first post,i think there i am measuring the time between the pulses itself but when i am implementing it ,its not giving accurate values.

One method to measure intervals between pulses is to use PulseIn.

The hall pulses from the magnets should be short compared to the time for the rotation and you will measure the LOW time.

unsigned long duration;

void setup()
{
  Serial.begin(115200);
  pinMode(2, INPUT);
}

void loop()
{
  duration =  pulseIn(2, LOW);

  Serial.println((unsigned int)duration);
}

Whether or or not PulseIn gives you better results than measuring the time between interrupts, or by using the while loop is for your experimentation.

Thanks for the reply,i am looking forward to try out the method of averages first and see how much accuracy that method will provide me .The pulsein function will also be helpful in my case .