Bike tachometer coding?

Ok well I found this code :

int val;
long last=0;
int stat=LOW;
int stat2;
int contar=0;

int sens=160;  // this value indicates the limit reading between dark and light,
              // it has to be tested as it may change acording on the 
              // distance the leds are placed.
int nPalas=2; // the number of blades of the propeller

int milisegundos=500; // the time it takes each reading
void setup()
{
  Serial.begin(9600);
  pinMode(13,OUTPUT);
  
}

void loop()
{
  val=analogRead(0);
  if(val<sens)
    stat=LOW;
   else
    stat=HIGH;
   digitalWrite(13,stat); //as iR light is invisible for us, the led on pin 13 
                          //indicate the state of the circuit.

   if(stat2!=stat){  //counts when the state change, thats from (dark to light) or 
                     //from (light to dark), remmember that IR light is invisible for us.
     contar++;
     stat2=stat;
   }
   if(millis()-last>=milisegundos){
     double rps=((double)contar/nPalas)/2.0*1000.0/milisegundos;
     double rpm=((double)contar/nPalas)/2.0*60000.0/(milisegundos);
     Serial.print((contar/2.0));Serial.print("  RPS ");Serial.print(rps);
     Serial.print(" RPM");Serial.print(rpm);Serial.print("  VAL ");Serial.println(val);
     contar=0;
     last=millis();
   }
}

it basically shows on the serial monitor the RPM depending on how much times an IR receiver gets blocked by a blade in my case I have a drill stuck through my own little paper blade. Now it works great with the RPM and such but heres what I need help on:

I want to incorporate this RPM counter onto my bike. All I need to know right now it how would I change the code around so it can tell me my speed and maybe even my distance on a LCD?

I just need the equations and things to consider and such to get this going.

More specifically, How can I change RPM to KPH ? I know the math behind it I find out the circumference of my wheel and then instead of minutes I make it into hours but how would I add that into the code? And for the distance measure, I know I need the arduino to actually count every second and calculate how far I have gone depending on the KPH data. So how would I do THAT?

To calculate distance, it is probably better to count rotations of the wheel and multiply by circumference of the wheel.

If you start to calculate how many seconds you have been driving at different speeds you are going to get many sources of error into the equation.

Another way would be to use a GPS module :slight_smile:

I don't know if KPH is the same as km/h, but let try simply way.

You count pulses, and compare it to time delta. That gives you the average speed of RPM. Then you need to know how many pulses there are for one turn, and what is the lenght of the circle.

It's good for you to think this yourself clear, we can help in the idea.

Where would you start? What information you have at the first place? Totatal count of pulses and time between them, time delta?

Cheers,
Kari

Okay I think I have this figured out but I need help coding it here's exactly what i need to do,

I have RPM so I have to multiply that number by my circumference to get my tire distance per minute
Then I multiply the whole number by 3600 to get per hour. So now I have meters per hour and lastly I divide the whole number by
1000 to get kilometers per hour.

For the distance I make the arduino add the tire circumference every time the IR is tripped and log the sum on the LCD

So now I need to know what codes I can utilize because I frankly don't know how to multiply and divide with the arduino programming. I also need to know how to add a number to a total every time the beam is tripped.

So now I need to know what codes I can utilize because I frankly don't know how to multiply and divide with the arduino programming. I also need to know how to add a number to a total every time the beam is tripped.

The Arduino programming language comes with these really neat operators, + (for addition), - (for subtraction), * (for multiplication), and / (for division). You are free to use them, instead of trying to invent your own.

polishdude20,
Is this place familiar to you? Arduino - Home

You better start to use that information, people love to help people who help themselves at first.

All mathematical syntaxes are there for you, just like PaulS said.
:slight_smile:

Cheers,
Kari

GaryP:
polishdude20,
Is this place familiar to you? Arduino - Home

You better start to use that information, people love to help people who help themselves at first.

All mathematical syntaxes are there for you, just like PaulS said.
:slight_smile:

Cheers,
Kari

ok thanks

polishdude20:

GaryP:
polishdude20,
Is this place familiar to you? Arduino - Home

You better start to use that information, people love to help people who help themselves at first.

All mathematical syntaxes are there for you, just like PaulS said.
:slight_smile:

Cheers,
Kari

ok thanks

wait a second NO no thanks. I am asking for help and sure enough I gave all I could but this is what a forum is for. I need help with writing the code from actual people not some tutorial with an obscure idea of what I'm trying to do. If you can't help me then don't tell me to go research it myself, writing on this forum IS research.

For those of you who CAN help,

I have gotten the code to write out my Km/h just fine but now I am stumped getting the IR sensor to "debounce" so to speak.

I need the IR sensor to count only ONCE whenever the beam is broken like a button debounce. Because the values I get just keep increasing when the light gets blocked.

So this is what I need to do specifically:
Get the arduino to wait for the IR sensor to tell it that it's dark. Then once it says that it increments by 1 and it cannot increment by another 1 until it gets bright again and then the cycle repeats.

Anyone know how to do this?

here's the code I have so far

#include <LiquidCrystal.h>
// LiquidCrystal display with:
// rs on pin 12
// rw on pin 11
// enable on pin 10
// d4, d5, d6, d7 on pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);



int val;



long last=0;
int stat=LOW;
int stat2;
int contar=0;
int rpm3;
int rpm4;
int rpm5;
int total;
int total2;
int total3;
int contar2=0;
int rpm2;
int sens=160;  // this value indicates the limit reading between dark and light,
              // it has to be tested as it may change acording on the 
              // distance the leds are placed.
int nPalas=1; // the number of blades of the propeller

int milisegundos=500; // the time it takes each reading
void setup()
{
  Serial.begin(9600);
  pinMode(13,OUTPUT);
  lcd.begin(16, 4);
}

void loop()
{
  val=analogRead(0);
  if(val<sens)
    stat=LOW;
   else
    stat=HIGH;
   digitalWrite(13,stat); //as iR light is invisible for us, the led on pin 13 
                          //indicate the state of the circuit.

   if(stat2!=stat){  //counts when the state change, thats from (dark to light) or 
                     //from (light to dark), remmember that IR light is invisible for us.
     contar++;
     stat2=stat;
     ++total;
     
   }
   if(millis()-last>=milisegundos){
     
     double rpm=((double)contar/nPalas)/2.0*60000.0/(milisegundos);
     
     rpm2 = rpm * .75 ;    // the number multiplied here is the example circumference of the bike tire in meters
     rpm3 = rpm2 / 100;  // here I divide by 1000 to give the number in kilometers
     rpm4 = rpm3 * 60 ;  // lastly here I multiply by 60 to give me kilometers per hour.

     Serial.print(" RPM  ");Serial.print(rpm4);Serial.print("  VAL ");Serial.println(val);
     contar=0;
     last=millis();
   }
   
   total2=total * .75;
   
     lcd.setCursor(5,0);
  lcd.print("KPH");
  lcd.setCursor(5,1);
  lcd.print(rpm4);
  
  lcd.setCursor(5,3);
  lcd.print(total2);
 
  
  
 
   
   
}

writing on this forum IS research.

Depends on what you write. "Please write some code for me!" is NOT research.

     rpm3 = rpm2 / 100;  // here I divide by 1000 to give the number in kilometers

Really? When the comments and the code are not in agreement, the code is right. Always.

You have some code that unconditionally increments when the sensor reading is above a threshold. You need to ignore readings from the sensor, after incrementing, until the reading drops below sens again. Create a boolean variable, set to true when the sensor reads high, after incrementing the counter(s), then set it to false once the reading drops below sens. Only increment the counter(s) when the variable is false.

Sorry but I still don't get it.

Don't I already have a boolean when it says :

 if(stat2!=stat){  //counts when the state change, thats from (dark to light) or 
                     //from (light to dark), remmember that IR light is invisible for us.
     contar++;
     stat2=stat;
     ++total;
     
   }

How would I write this as true or false?

because I can see the code says if stat2 does not equal stat 1 then increment contar and total by 1. then toggle stat2 to equal stat 1. I don't get what this stat 2 is doing here anyways.

You are funny, but I didn't realized that it is spoonfeeding time.

Ok, do me a favor, and I'll play with you;
Change those variable names that don't mean anything (language problem), like "nPalas", "milliSegundos", "contar" and "val" to something readable, with more meanings. Val is probably value for IR sensor, and milliSegundos is obviously milliseconds, but measured for what purpose; is time between two measurements, or current internal timer value? I want you to consentrate a bit, and look the code for yourself.

Trust me, when you make the breaktrough yourself, it pays back the pain you felt while learning. There's no way back then. But if you have this, easiest possible code WRITTEN TO YOU, you don't have a sh...!

I am a beginner with C-language, but I enjoy learning the structure and syntax, it is so much different from what I used to do, and so much pitfalls to make my life miserable.

But this easy task I can help you. When you help yourself first.

By the way, you have commented some lines in you code, good. Why don't you add information to all variables as well, like this;

int nPalas=1; // the number of blades of the propeller

Cheers,
Kari

Additional question for polishdude20;

What is your main problem, the logic or the syntax?

Kari

GaryP:
Additional question for polishdude20;

What is your main problem, the logic or the syntax?

Kari

it's the syntax! :smiley: I mean I looked up on the reference about booleans and such but I don't get how to implement it into my code.

And about me being "spoonfed", I haven't gotten any useful information from you at all yet other than giving me the link to the reference of programming. I actually DID help myself because I found how to change RPM to Km/h. I also tried doing the increment functions to add distance all by myself.

IF you aren't going to help me then this is not the topic for you, if you WILL help me I would gladly accept any advice on how to implement booleans and true and false into my code.

I know the logic behind it. For example: When sensor is "bright" A is True, when sensor is "dark" A is false. When a is True , wait for it to turn false, when it turns false increment by 1 until A is true again and then it repeats the cycle.

But I don't get how to make it wait for A to be "bright" again.

Okay I cleaned up the code a wee bit and I have added a boolean variable called state which is true when above sens value and false when below sens value.

Now how can I use "state" to increment only by one when state changes from true to false?

heres the new code

#include <LiquidCrystal.h>
// LiquidCrystal display with:
// rs on pin 12
// rw on pin 11
// enable on pin 10
// d4, d5, d6, d7 on pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);


int val;  //the value of the sensor
long last=0;
int stat=LOW;
int stat2;
int contar=0; //the variable that increments by 1 when sens is low
int rpm3;
int rpm4;
int total;
int total2;
int rpm2;
int sens=160;  // this value indicates the limit reading between dark and light,
              // it has to be tested as it may change acording on the 
              // distance the leds are placed.
int blades=1; // the number of blades of the propeller

boolean state= true;  //the boolean variable that checks to see if true or false

int milliseconds=500; // the time it takes each reading
void setup()
{
  Serial.begin(9600);
  pinMode(13,OUTPUT);
  lcd.begin(16, 4);
}

void loop()
{
  val=analogRead(0);
  if(val<sens){
    stat=LOW;
    state=false;} //if dark boolean false
   else{
    stat=HIGH;
    state=true;  //if light boolean true
   digitalWrite(13,stat); }//as iR light is invisible for us, the led on pin 13 
                          //indicate the state of the circuit.

   if(stat2!=stat){  //counts when the state change, thats from (dark to light) or 
                     //from (light to dark), remmember that IR light is invisible for us.
     contar++;
     stat2=stat;
     ++total;
     
   }
   if(millis()-last>=milliseconds){
     
     double rpm=((double)contar/blades)/2.0*60000.0/(milliseconds);
     
     rpm2 = rpm * .75 ;    // the number multiplied here is the example circumference of the bike tire in meters
     rpm3 = rpm2 / 100;  // here I divide by 100 to give the number in kilometers plus an extra decimal place
     rpm4 = rpm3 * 60 ;  // lastly here I multiply by 60 to give me kilometers per hour.

     Serial.print(" RPM  ");Serial.print(rpm4);Serial.print("  VAL ");Serial.println(val);
     contar=0;
     last=millis();
   }
   
   total2=total * .75;
   
     lcd.setCursor(5,0);
  lcd.print("KPH");
  lcd.setCursor(5,1);
  lcd.print(rpm4);
  
  lcd.setCursor(5,3);
  lcd.print(total2);
 
  
  
 
   
   
}

Let's clear the variables a bit more. You have val for sensor, then you have sensor for the preset value for comparing? Change the "val" to "sensorValue" for analog reads, and "sensor" to "sensorTreshold". It will be easier to follow the logic.

What does the "contar" means in english, or in finnish? Just kidding... with the finnish...

You did't add the meaning for all variables, if there is unnessessary variables, you should remove them.

I'm not the best person to teach you, but if you let me try, I will help myself too.

And get rid of the attitude. You are beeing this-skinned (best translation I could find for this). :wink:

Cheers,
Kari

A week or so ago, I wrote some code for a unicycle computer. If it helps, here is my code:

#include <LiquidCrystal (2).h>  //This shows for some reason when I import the LCD library
#include <LiquidCrystal.h>  //This adds the liquidCrystal capabilities to the arduino
//If you try the code and it does not work, delete these two lines above and go tools -> import library -> liquidCrystal

float rotationTime;  //used to hold the time of one rotation in milliseconds
float distanceTravelledPerSecond;  //this is going to be used for calculating the speed
float wheelCircumference = 159.592907;  //the unicycle wheel has a circumference of this many cm.
float RPM;  //this variable will be used to store the wheels RPM.
float speeds;  //this holds the speed of the unicycle.
float maximumSpeed; //this holds the fastest speed attained.
unsigned int distanceTravelled;  //this holds the trip distance. 
unsigned int averageSpeed;  //This will hold the average speed
unsigned char revoloutions = 0;  //this holds the ammount of wheel turns. It is an unsigned char so it can hold a very big number.
unsigned char startRotation = 0;  //used to hold the millis() of the end of the last rotation
unsigned char endRotation = 0;  //used to hold the millis() of the end of the current rotation
unsigned char timeInSeconds;  //This will hold how long the program has been running for, in seconds
boolean reedSwitchState;  //used to hold the state of the reed switch
boolean lastReedSwitchState; //used to hold the previous state of the reed switch

const int reedSwitchPin = 5;  //The sensor is attatched to pin 5
const int switchToShowRPM = A0;  //The LCD will display RPM if this is pressed
const int switchToShowSpeeds = A1;  //the LCD will show the speed if this is pressed
const int switchToShowMaximumSpeed = A2;  //the LCD will show the maximum speed if this is pressed
const int switchtoShowDistanceTravelled = A3;  //The distance travelled will be shown if this is pressed
const int switchToShowAverageSpeed = A4;  //The average speed will be shown if this is pressed

boolean RPMstate;
boolean speedsState;
boolean maximumSpeedState;
boolean averageSpeedState;
boolean distanceTravelledState;  //These five variables will be used when reading the switches above, and will decide the variables below:

boolean showRPM = 0;  //The LCD will show the RPM if this is true
boolean showSpeeds = 0;  //The LCD will show speed if this is true
boolean showMaximumSpeeds = 0;  //the LCD will show the maximum speed if this is true
boolean showDistanceTravelled = 0;  //the LCD will show the distance travelled if this is true
boolean showAverageSpeed = 0; //The LCD will show the average speed if this is true

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 2, 3, 4, 6, 7, 8, 9, 10);
//This uses all 8 of the input pins (8 bit mode) to write to the LCD faster

void setup(){
  pinMode(reedSwitchPin, INPUT);  //declare the pin with the reed switch as an input
}

void loop(){
  RPMstate = digitalRead(switchToShowRPM);  //RPMstate will be high if the switch to show RPM is high
  speedsState = digitalRead(switchToShowSpeeds);  //speedsState will be high if the switch to show speed is high
  maximumSpeedState = digitalRead(switchToShowMaximumSpeed);  //maximumSpeedState will be high if the switch to show the maximum speed is high
  distanceTravelledState = digitalRead(switchtoShowDistanceTravelled);  //distanceTravelledState will be high if the switch to show the distance travelled is high
  
  if(RPMstate){  //if the RPM switch was pressed...
   showRPM = 1;  //turn showRPM to high, so the RPM will be displayed...
   showSpeeds = showMaximumSpeeds = showDistanceTravelled = showAverageSpeed = 0;  // ...and then set the rest to 0, so they will not show
  }
  
  if(speedsState){  //if the speedsStates Switch was pressed...
    showSpeeds = 1;  //set the showSpeeds to high so it will display...
    showRPM = showMaximumSpeeds = showDistanceTravelled = showAverageSpeed = 0;  //...and turn the rest to low so they will not.
  }
  
  if(maximumSpeedState){  //if the switch to show maximumSpeed was high...
    showMaximumSpeeds = 1;  //turn maximumSpeed to high so it will display...
    showSpeeds = showRPM = showDistanceTravelled = showAverageSpeed = 0;  //...and turn the others to low so they will not.
  }
  
  if(distanceTravelled){  //if the switch to show the distance travelled has been pressed...
    showDistanceTravelled = 1;  //turn distance travelled to high so it will display...
    showSpeeds = showRPM = showMaximumSpeeds = showAverageSpeed = 0;  //..and turn the rest to 0 so they will not.
  } 
      
  if(averageSpeed){  //if the switch to show the distance travelled has been pressed...
    showAverageSpeed = 1;  //turn distance travelled to high so it will display...
    showSpeeds = showRPM = showMaximumSpeeds = showDistanceTravelled = 0;  //..and turn the rest to 0 so they will not.
  } 
  
  lastReedSwitchState = reedSwitchState;  //pass the value of reed Switch State to previous Reed Switch State
  reedSwitchState = digitalRead(reedSwitchPin);  //take a reading of the reed switch state

  if((lastReedSwitchState == LOW) && (reedSwitchState == HIGH)){  //if the reed switch is high and was previously low...
    revoloutions ++;  //add one to revoloutions - the wheel has turned round one more time
    endRotation = millis();  //keep track of the time that the rotation completed
    rotationTime = endRotation - startRotation;  //work out the time of the full rotation
    startRotation = endRotation;  //the next rotation starts when the previous one finished, so make them have both the same values
    RPM = (60000 / rotationTime);  //find out how many times you can get the rotation time inot one minute - hence working out the RPM
    distanceTravelled = revoloutions * wheelCircumference;  //the distance travelled will be the ammount of rotations * the distance travelled per rotation
    distanceTravelledPerSecond = RPM * wheelCircumference;  //speed = distance / time. The time for this is 1 second, the distance is worked out here
    distanceTravelledPerSecond = distanceTravelledPerSecond / 100;  //This gives the distance travelled per second in meters, not centimeters
    speeds = distanceTravelledPerSecond;  //The speed will be in m/s, and this is the ammount of meters travelled per second, or m/s, so it is the speed!
    if(speeds > maximumSpeed) maximumSpeed = speeds;  //if the new speed is faster than the maximum speed, make the current speed the new maximum speed
    timeInSeconds = millis();  //This will give the ammount of milliseconds that the program has been running for
    timeInSeconds = timeInSeconds / 1000;  //This will turn the time in milliseconds into the time in seconds
    averageSpeed = (distanceTravelled / timeInSeconds);  //This will give the average speed
    lcd.clear();  //Clear the LCD to show the new results
    
    if(showRPM) lcd.print(RPM);  //show the RPM on the LCD
    else if(showSpeeds) lcd.print(speeds);  //show the speed on the LCD
    else if(showMaximumSpeeds) lcd.print(maximumSpeed);  //Show the maximum speed on the LCD
    else if(showDistanceTravelled) lcd.print(distanceTravelled);  //Show the distance travelled on the LCD
    else if(showAverageSpeed) lcd.print(averageSpeed);  //Show the average speed on the LCD

  }    
}

It uses several switches to show different sets of data on an LCD display. The sensor input is a reed switch, although there is nothing stopping you from modifying it to use the IR sensors.
I have not built the hardware for this, so I have no idea whether it will work or not. The code might work, but it should show the maths needed. Simply change the variable 'wheelCircumference' to [pi X the bike wheel diameter], and the maths should do the rest for you. If you need anything explaining that the comments do not make clear, just ask! :smiley:

Onions.

GaryP:
Let's clear the variables a bit more. You have val for sensor, then you have sensor for the preset value for comparing? Change the "val" to "sensorValue" for analog reads, and "sensor" to "sensorTreshold". It will be easier to follow the logic.

What does the "contar" means in english, or in finnish? Just kidding... with the finnish...

You did't add the meaning for all variables, if there is unnessessary variables, you should remove them.

I'm not the best person to teach you, but if you let me try, I will help myself too.

And get rid of the attitude. You are beeing this-skinned (best translation I could find for this). :wink:

Cheers,
Kari

you mean "thick skinned"

Onions:
A week or so ago, I wrote some code for a unicycle computer. If it helps, here is my code:

#include <LiquidCrystal (2).h>  //This shows for some reason when I import the LCD library

#include <LiquidCrystal.h>  //This adds the liquidCrystal capabilities to the arduino
//If you try the code and it does not work, delete these two lines above and go tools -> import library -> liquidCrystal

float rotationTime;  //used to hold the time of one rotation in milliseconds
float distanceTravelledPerSecond;  //this is going to be used for calculating the speed
float wheelCircumference = 159.592907;  //the unicycle wheel has a circumference of this many cm.
float RPM;  //this variable will be used to store the wheels RPM.
float speeds;  //this holds the speed of the unicycle.
float maximumSpeed; //this holds the fastest speed attained.
unsigned int distanceTravelled;  //this holds the trip distance.
unsigned int averageSpeed;  //This will hold the average speed
unsigned char revoloutions = 0;  //this holds the ammount of wheel turns. It is an unsigned char so it can hold a very big number.
unsigned char startRotation = 0;  //used to hold the millis() of the end of the last rotation
unsigned char endRotation = 0;  //used to hold the millis() of the end of the current rotation
unsigned char timeInSeconds;  //This will hold how long the program has been running for, in seconds
boolean reedSwitchState;  //used to hold the state of the reed switch
boolean lastReedSwitchState; //used to hold the previous state of the reed switch

const int reedSwitchPin = 5;  //The sensor is attatched to pin 5
const int switchToShowRPM = A0;  //The LCD will display RPM if this is pressed
const int switchToShowSpeeds = A1;  //the LCD will show the speed if this is pressed
const int switchToShowMaximumSpeed = A2;  //the LCD will show the maximum speed if this is pressed
const int switchtoShowDistanceTravelled = A3;  //The distance travelled will be shown if this is pressed
const int switchToShowAverageSpeed = A4;  //The average speed will be shown if this is pressed

boolean RPMstate;
boolean speedsState;
boolean maximumSpeedState;
boolean averageSpeedState;
boolean distanceTravelledState;  //These five variables will be used when reading the switches above, and will decide the variables below:

boolean showRPM = 0;  //The LCD will show the RPM if this is true
boolean showSpeeds = 0;  //The LCD will show speed if this is true
boolean showMaximumSpeeds = 0;  //the LCD will show the maximum speed if this is true
boolean showDistanceTravelled = 0;  //the LCD will show the distance travelled if this is true
boolean showAverageSpeed = 0; //The LCD will show the average speed if this is true

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 2, 3, 4, 6, 7, 8, 9, 10);
//This uses all 8 of the input pins (8 bit mode) to write to the LCD faster

void setup(){
 pinMode(reedSwitchPin, INPUT);  //declare the pin with the reed switch as an input
}

void loop(){
 RPMstate = digitalRead(switchToShowRPM);  //RPMstate will be high if the switch to show RPM is high
 speedsState = digitalRead(switchToShowSpeeds);  //speedsState will be high if the switch to show speed is high
 maximumSpeedState = digitalRead(switchToShowMaximumSpeed);  //maximumSpeedState will be high if the switch to show the maximum speed is high
 distanceTravelledState = digitalRead(switchtoShowDistanceTravelled);  //distanceTravelledState will be high if the switch to show the distance travelled is high
 
 if(RPMstate){  //if the RPM switch was pressed...
  showRPM = 1;  //turn showRPM to high, so the RPM will be displayed...
  showSpeeds = showMaximumSpeeds = showDistanceTravelled = showAverageSpeed = 0;  // ...and then set the rest to 0, so they will not show
 }
 
 if(speedsState){  //if the speedsStates Switch was pressed...
   showSpeeds = 1;  //set the showSpeeds to high so it will display...
   showRPM = showMaximumSpeeds = showDistanceTravelled = showAverageSpeed = 0;  //...and turn the rest to low so they will not.
 }
 
 if(maximumSpeedState){  //if the switch to show maximumSpeed was high...
   showMaximumSpeeds = 1;  //turn maximumSpeed to high so it will display...
   showSpeeds = showRPM = showDistanceTravelled = showAverageSpeed = 0;  //...and turn the others to low so they will not.
 }
 
 if(distanceTravelled){  //if the switch to show the distance travelled has been pressed...
   showDistanceTravelled = 1;  //turn distance travelled to high so it will display...
   showSpeeds = showRPM = showMaximumSpeeds = showAverageSpeed = 0;  //..and turn the rest to 0 so they will not.
 }
     
 if(averageSpeed){  //if the switch to show the distance travelled has been pressed...
   showAverageSpeed = 1;  //turn distance travelled to high so it will display...
   showSpeeds = showRPM = showMaximumSpeeds = showDistanceTravelled = 0;  //..and turn the rest to 0 so they will not.
 }
 
 lastReedSwitchState = reedSwitchState;  //pass the value of reed Switch State to previous Reed Switch State
 reedSwitchState = digitalRead(reedSwitchPin);  //take a reading of the reed switch state

if((lastReedSwitchState == LOW) && (reedSwitchState == HIGH)){  //if the reed switch is high and was previously low...
   revoloutions ++;  //add one to revoloutions - the wheel has turned round one more time
   endRotation = millis();  //keep track of the time that the rotation completed
   rotationTime = endRotation - startRotation;  //work out the time of the full rotation
   startRotation = endRotation;  //the next rotation starts when the previous one finished, so make them have both the same values
   RPM = (60000 / rotationTime);  //find out how many times you can get the rotation time inot one minute - hence working out the RPM
   distanceTravelled = revoloutions * wheelCircumference;  //the distance travelled will be the ammount of rotations * the distance travelled per rotation
   distanceTravelledPerSecond = RPM * wheelCircumference;  //speed = distance / time. The time for this is 1 second, the distance is worked out here
   distanceTravelledPerSecond = distanceTravelledPerSecond / 100;  //This gives the distance travelled per second in meters, not centimeters
   speeds = distanceTravelledPerSecond;  //The speed will be in m/s, and this is the ammount of meters travelled per second, or m/s, so it is the speed!
   if(speeds > maximumSpeed) maximumSpeed = speeds;  //if the new speed is faster than the maximum speed, make the current speed the new maximum speed
   timeInSeconds = millis();  //This will give the ammount of milliseconds that the program has been running for
   timeInSeconds = timeInSeconds / 1000;  //This will turn the time in milliseconds into the time in seconds
   averageSpeed = (distanceTravelled / timeInSeconds);  //This will give the average speed
   lcd.clear();  //Clear the LCD to show the new results
   
   if(showRPM) lcd.print(RPM);  //show the RPM on the LCD
   else if(showSpeeds) lcd.print(speeds);  //show the speed on the LCD
   else if(showMaximumSpeeds) lcd.print(maximumSpeed);  //Show the maximum speed on the LCD
   else if(showDistanceTravelled) lcd.print(distanceTravelled);  //Show the distance travelled on the LCD
   else if(showAverageSpeed) lcd.print(averageSpeed);  //Show the average speed on the LCD

}    
}




It uses several switches to show different sets of data on an LCD display. The sensor input is a reed switch, although there is nothing stopping you from modifying it to use the IR sensors. 
I have not built the hardware for this, so I have no idea whether it will work or not. The code might work, but it should show the maths needed. Simply change the variable 'wheelCircumference' to [pi X the bike wheel diameter], and the maths should do the rest for you. If you need anything explaining that the comments do not make clear, just ask! :D

Onions.

wow thanks! Ill get right on it , ill see if I can understand and adapt this to my project!

polishdude20:
you mean "thick skinned"

If it means sensitive, then yes.

Well, it's sad if the time was wasted with arguing, we were almost getting to the point. But if ready code is what you need...
:slight_smile:

Cheers,
Kari

Thin skinned is the idiom you're looking for.

As to the rpm calc, you might want to consider increasing the time between calculating it a little - if you're sensing speed for a bicycle, you won't get many transitions per 500ms unless you're riding at speed.