Hey folks.
I'm struggling to figure out how to display an accurate RPM reading with a hall effect sensor, for a project I've got going.
All of the examples I've seen, show the concept works, but readings tend to be all over the place (+/- 100 RPM) which is unusable to me.
I started by trying to modify this example code, which appears to be for RPM's up to 10,000, using one magnet.
/*
RPM meter code (tested on device rotating at 10,000 rpm)
rev.001
* using a hall effect sensor
http://www.adafruit.com/index.php?main_page=product_info&cPath=35&products_id=158
* using a parallel LCD with
LiquidCrystal Library
http://www.ladyada.net/learn/lcd/charlcd.html
http://www.arduino.cc/en/Tutorial/LiquidCrystal
with pins 7,6,5,4,3,2
*/
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7,6,5,4,3,2);
// read the hall effect sensor on pin 2
const int hallPin=8;
const unsigned long sampleTime=1000;
const int maxRPM = 10200;
void setup()
{
pinMode(hallPin,INPUT);
Serial.begin(9600);
// set up the LCD's number of rows and columns:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("initializing");
delay(1000);
lcd.clear();
}
void loop()
{
int rpm=getRPM();
lcd.clear();
displayRPM(rpm);
displayBar(rpm);
}
int getRPM()
{
// sample for sampleTime in millisecs
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;
}
void displayRPM(int rpm)
{
lcd.clear();
// set the cursor to column 0, line 1
lcd.setCursor(0, 0);
// print the number of seconds since reset:
lcd.print(rpm,DEC);
lcd.setCursor(7,0);
lcd.print("RPM");
}
void displayBar(int rpm)
{
int numOfBars=map(rpm,0,maxRPM,0,15);
lcd.setCursor(0,1);
if (rpm!=0)
{
for (int i=0; i<=numOfBars; i++)
{
lcd.setCursor(i,1);
lcd.write(1023);
}
}
}
I've added 50 magnets, to a larger surface area (for a little more time between interrupts) and am trying to get accurate readings starting from around 400 RPM, to calculate the time it takes for a flywheel to free-spin down to around 50 RPM.
Am I on the right track with more interrupts per revolution?
Is float math the right way to go about this?
Would an optical sensor, with alternating white/black lines on the axle, be more accurate?
I haven't made much progress on this in the last couple weeks, and it's a little frustrating.
Could anyone point me in the right direction?
.