Pages: [1] 2 3   Go Down
Author Topic: RPM calclater  (Read 3113 times)
0 Members and 1 Guest are viewing this topic.
Delhi, India
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
~
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How to make a RPM calculater with arduino>..??
I wanna calculate rpms of some of my motors . I am planning to do it using a IR sensor(easiest to make)
I have attached a wheel to the motor and pasted a black circle over the wheel with only one stripe of white(see the pic, u'll understand)
so whenever the ir rays are reflected by the white strip, arduino reads it ad calculate how many times the rays are received i.e. RPM of the motor.
I do not noe how to make a stopwatch such that the arduino stop reading the rays after a minute. smiley-zipper smiley-cry
Reagrds,
Shubham Garg


* Untitled.jpg (21.45 KB, 405x525 - viewed 25 times.)
Logged

Regards
Shubham Garg

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 27419
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Use the millis() function.
Something like this:
Code:
void loop(){

//read the current time

current_time = millis();
//then count until 1 minute (= 60*1000 ms, 60000mS) has elapsed
while (millis()<=(current_time+60000)){
count=count+1; // every time a black/white transition is detected, will leave that to you
}
Serial.print(count);
}
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 75
Posts: 7303
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

How fast will the motor run? Will it run outdoor with the IR from sun mixed with your sensor? Maybe a Hall Effect Switch with a magnet is better.
Logged


Montreal
Offline Offline
Faraday Member
**
Karma: 30
Posts: 2609
Per aspera ad astra.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Look in:
http://arduino.cc/en/Reference/PulseIn
Return value would be in reverse proportion to RPM.
Logged

Delhi, India
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
~
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thx every1 fr the reply...smiley
@crossroads, your sol works great except that whenever the wheel rotates single time, instead of showing 1 count it shows multiple of them.
how to fix this?
Logged

Regards
Shubham Garg

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 227
Posts: 14024
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Please post your current code so we can have a look
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Delhi, India
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
~
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

here is the code:
Code:
int count ;
int ir = 5 ;
int current_time ;

void setup(){
Serial.begin(9600) ;
Serial.print("start")  ;
}

void loop(){   //read the current time

current_time = millis();
//then count until 1 minute (= 60*1000 ms, 60000mS) has elapsed
if (millis()<=(current_time+60000)){
  if(digitalRead(ir) == LOW)
  {
count=count+1; // every time a black/white transition is detected, will leave that to you
Serial.println(count);
  }
}
else
{
 
}
}

here is the result:(on a single transition)
Code:
start1
2
3
4
5
6
7
8
9
10
11
12
Logged

Regards
Shubham Garg

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 227
Posts: 14024
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
 if(digitalRead(ir) == LOW)
  {
count=count+1; // every time a black/white transition is detected, will leave that to you
Serial.println(count);
  }

This is incorrect logic, what you do is check the state of the sensor, not if there is a transition. A transition is a change. To measure a change you need a current value and a previous value. See code below.

(code not tested or compiled ...
Code:
#define IRPIN 5

unsigned int count;  // can only be positive
unsigned long current_time;
int prevState;  //  LOW = BLACK, HIGH = WHITE
int newState;

void setup()
{
  Serial.begin(115200) ;
  Serial.println("Start RPM 0.1") ;
  pinMode (IRPIN, INPUT);
}

void loop()
{
  count = 0;  
  prevState = digitalRead(IRPIN );   // read the reference state
  current_time = millis();

  //count until 1 minute (= 60*1000 ms, 60000mS) has elapsed
  while (millis() - 60000L <= current_time )  // use L for LONG math !!!
  {
    newState = digitalRead(IRPIN);
    if (prevState == LOW && newState == HIGH)  // this is a transition from LOW to HIGH
    {
      count++
    }
    prevState = newState;
  }
  Serial.println();
  Serial.print("RPM: ")
  Serial.println(count);
}

Succes,
Rob
« Last Edit: July 18, 2011, 05:56:14 am by robtillaart » Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Delhi, India
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
~
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@robtillaart
here is the code(compiles)
Code:
#define IRPIN 5

unsigned int count;  // can only be positive
unsigned long current_time;
int prevState;  //  LOW = BLACK, HIGH = WHITE
int newState;

void setup()
{
  Serial.begin(115200) ;
  Serial.println("Start RPM 0.1") ;
}

void loop()
{
  count = 0; 
  prevState = digitalRead(IRPIN );   // read the reference state
  current_time = millis();

  //count until 1 minute (= 60*1000 ms, 60000mS) has elapsed
  while (millis() - 60000L <= current_time )  // use L for LONG math !!!
  {
    newState = digitalRead(IRPIN);
    if (prevState == LOW && newState == HIGH)  // this is a transition from LOW to HIGH
    {
      count++ ;
    }
    prevState = newState;
  }
  Serial.println();
  Serial.print("RPM: ") ;
  Serial.println(count);
}

here is he result
Code:
2 ƄJ$!6
„€€

what's wrong with this?
Logged

Regards
Shubham Garg

Greenville, IL
Offline Offline
Edison Member
*
Karma: 15
Posts: 1330
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


  Serial.begin is set 115200. You probably have your serial monitor set to 9600.


Mark
Logged


Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 27419
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Check your baud rates - your original code was at 9600, the latest is at 115200 - what is your serial monitor set at?

@robtillart,

while (millis() - 60000L <= current_time )  // use L for LONG math !!!

Should this be UL for unsigned long, to agree with millis() and current_time?
« Last Edit: July 17, 2011, 10:41:50 am by CrossRoads » Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 227
Posts: 14024
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Should this be UL for unsigned long, to agree with millis() and current_time?
point is that 60000 is not in the int range so should be declared as a datatype larger than int.
Long is OK, Unsigned long is probably better as it keeps the whole math in unsigned long. 

Thanx for this addition.

BaudRate (why 115200)
I changed the baudrate as it takes 12x less time at 115200  than 9600 to transmit a character. It gives the inner loop While (millis() - 60000L <= current_time) ... the change to stop after 60000 millis (almost) exactly. Recall there was a print of count in this while loop earlier. This print would take a few millis @9600 but @115200 it prints in less (or about) than 1 millis. Reading the code over before posting made me decide to remove the print statement altogether to optimize the timing to the max.

Rob
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Toronto, Canada
Offline Offline
Edison Member
*
Karma: 2
Posts: 1234
"Keep it R.E.I.L. - "Research, Experiment, Investigate and Learn"
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi guys. I just read at the discussion here, and the RPM counter program do sample every minute. Just like : Turn / minute. OK But What if it can be reprogram to take sample every second. Like  : Sample -->Numbers of Turn / second re-calculate into Turns / min and display the result via serial ?  I assume the motor is a high speed type ( electric motor )    So  the data sample will be for example :  15 count in 1 second---> Take 15 * 60 = 900 rpm.  Heh, I just don't like to wait every minute.  Just an idea.   
 
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 227
Posts: 14024
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good idea but (there is allways a but)  you get the granularity. 900 RPM jumps to 960 RPM or 840 RPM

You should count per second, but keep a sum of the last 60 seconds or so.

something like this: not ideal but
Code:


#define IRPIN 5

unsigned int count;  // can only be positive
unsigned long current_time;
int prevState;  //  LOW = BLACK, HIGH = WHITE
int newState;

void setup()
{
  Serial.begin(115200) ;
  Serial.println("Start RPM 0.1") ;
  pinMode (IRPIN, INPUT);
  prevState = digitalRead(IRPIN );   // read the reference state
}

int idx;
int count[60];
int sum;

void loop()
{
  current_time = millis();

  idx = (current_time/1000) % 60;
  sum = sum - count[idx];           // remove current second of prev minute

  // COLLECT
  count[idx] = 0;
  while (millis() - 1000L <= current_time )  // use L for LONG math !!!
  {
    newState = digitalRead(IRPIN);
    if (prevState == LOW && newState == HIGH)  // this is a transition from LOW to HIGH
    {
      count[idx]++ ;
    }
    prevState = newState;
  }
  sum = sum + count[idx];       // add current second of this minute

  // DISPLAY
  Serial.println();
  Serial.print("RPM: ") ;
  Serial.println(sum);
}
drawback is that it has a delay, the running average of the last 5 seconds iso 60 will follow the RPM faster.
« Last Edit: July 18, 2011, 05:56:41 am by robtillaart » Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Delhi, India
Offline Offline
Jr. Member
**
Karma: 0
Posts: 80
~
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I like the discussion going on, smiley-grin smiley-grin..
 
@CrossRoads,
I did changed the baudrate to 9600 and
Quote
Serial.println("Start RPM 0.1") ;
to "start RPM 1"
the result was like this

RPM = 0
RPM = 0
RPM = 0

"0" val was not changing..smiley-sad...
« Last Edit: July 18, 2011, 04:59:19 am by gshubham96 » Logged

Regards
Shubham Garg

Pages: [1] 2 3   Go Up
Jump to: