Go Down

Topic: Revolutions Per Minute Calculating Error (Read 2 times) previous topic - next topic

mykiscool

Jun 19, 2012, 01:59 am Last Edit: Jun 19, 2012, 02:01 am by mykiscool Reason: 1
Can someone please help me with this code. It is supposed to detect the revolutions per second on a bicycle wheel and then convert it to revolutions per minute. The magnetic sensor code works fine, the timer resets itself when it passes by, but no matter what speed or increment of time i wait to pass the magnet by again, it only comes up with 2 readings 5,000 and 6,000, which are not goods revolution per second readings. I expect to get some number like 230.14 or something random like that. My code is below. Any help is appreciated.


Code: [Select]

//these are just some references for it to work properly
#include <StopWatch.h>
#include <LiquidCrystal.h>
//these are the microcontroller ports that an lcd screen is connected to, a status led, and the switch.
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);
#define LED 13 //pin for the LED indicator (green)
#define Reed 3 //pin for the switch

//create a timer
StopWatch MySW;
//state of sensor 1 or 0
byte reedState=0;
//time between pass of magnet
float timeSincePass=0;
//revolutions per second
float RPS=0;
//revolutions per minute
float RPM=0;

//just some setup stuff
void setup()
{
 pinMode(LED,OUTPUT);
 pinMode(Reed,INPUT);
 Serial.begin(9600);
 lcd.begin(16, 4);
 lcd.print("Your Revs/Sec");
}


void loop()
{
 //get the state of the sensor
 reedState=digitalRead(Reed);
 //time since pass of magnet
 timeSincePass= MySW.elapsed();
 //set the lcd cursor to write on the second line
 lcd.setCursor(0, 1);

//if the magnet engages the switch
 if (reedState==HIGH)
 {
   //turn on status led for visual purposes
   digitalWrite(LED, HIGH);
   //convert milliseconds to seconds
   RPS=(float)timeSincePass*1000;
   //reset the timer storage int    
   timeSincePass=0;
   //reset the timer and start it again
   MySW.reset();
   MySW.start();
 }

 else
 {
   //turn off led otherwise
   digitalWrite(LED, LOW);
 }
 //convert seconds to minutes
 RPM=(float)RPS*60;
 
 //print the results to a screen
 lcd.print(RPS);
 lcd.print("  ");
 lcd.print(timeSincePass);
}
Proud Member of the Nighthawk Robotics Club Team 569 B

marco_c

It is possible that you are counting multiple times each time the sensor is triggered, as the code will execute very fast.

You need to include some form of trigger detection. This is done by remembering if the digital input was low or high the last time you checked and only counting the low to high (or high to low) transitions.

A relatively straightforward way to do this is to use an interrupt that will be triggered on the transition only - there is lots of stuff on hte board on how this can be done.
Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

mykiscool

Ok thanks that's a good idea. Ill look into it and get back to you if it doesn't work.
Proud Member of the Nighthawk Robotics Club Team 569 B

jraskell

Code: [Select]

//convert milliseconds to seconds
RPS=(float)timeSincePass*1000;


You convert milliseconds to seconds by dividing by 1000, not multiplying by 1000.

Then RPS is 1 / time for 1 revolution (I assume that's your timeSincePass value).

James C4S


Code: [Select]

//convert milliseconds to seconds
RPS=(float)timeSincePass*1000;

You convert milliseconds to seconds by dividing by 1000, not multiplying by 1000.


It is also a good practice to make your constants match the kind of math you are doing.  "1000" is an integer constant.  "1000.0" is a float constant.
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Go Up