Implementing debounce, driving me insane X(

Okay well I have this code that tells me the rpm of my bike and various other functions.

It operates with the use of a reed switch which closes when a magnet is placed over it.

My problem with the code is that there is no debounce! The readings are erratic because the slight changes in HIGH to LOW when flipping a switch change the rpm dramatically.

Now I have seen solutions in doing this with hardware and with coding. I can't really get my hands on a schmidtt trigger unless I buy it online and the coding I tried doesn't seem to work very well or at all.

I need someone to show me how I can debounce this in software or even hardware (without a schmidtt trigger).

If I MUST use a schmidtt trigger then can anyone recommend any common ones I could find? In any old electronics I can take apart?

heres the code :

#include <LiquidCrystal440.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

int changeoverTime = 1000;  //Used to determine when to change the display data

int displayCount = 0;  //Used to change between the display output
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
unsigned char timeInMilliseconds;  //This will hold how long the program has been running in milliseconds
unsigned char lastMillis;  //This will hold the last time the display data was changed
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
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
int test2;
int test = 4;
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7,8,9,10,11,12);
//This uses all 8 of the input pins (8 bit mode) to write to the LCD faster


void DoTimeAndDistanceCalcs()
{
    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 = timeInMilliseconds / 1000;  //This will turn the time in milliseconds into the time in seconds
    averageSpeed = (distanceTravelled / timeInSeconds);  //This will give the average speed
}





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

void loop(){
  test2 = digitalRead(test);
  //timeInMilliseconds = millis();
  displayCount = 0;
  //if((timeInMilliseconds - lastMillis) > changeoverTime){
   // displayCount ++;
   // lastMillis = millis();
   // if(displayCount == 5) displayCount = 0;
  //}
  
  if(displayCount == 0){  //if display Count = 0...
   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(displayCount == 1){  //if display Count = 1...
    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(displayCount == 2){  //if display Count = 2...
    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(displayCount == 3){  //if display Count = 3...
    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(displayCount == 4){  //if display Count = 4...
    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...
    DoTimeAndDistanceCalcs();
    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

  }    
  
  Serial.println(digitalRead(reedSwitchPin));
 
  
}

KE7GKP:
I am not sure I understand your question. You quoted a very large and opaque mass of code (hint: white space and indenting makes things more readable and understanable). And you asked about debounce. But there is no evidence of anything in your code that is supposed to be doing debounce? There is a tutorial on debounce. Did you try it? Do you understand how it works?

http://www.arduino.cc/en/Tutorial/Debounce

yes I tried it and understand it but I don't think I implemented it properly into my code. I'm not sure how to actually implement it into my specific application.

oh and to make it more easier , here is the section where the code looks for the sensor state:

 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...
    DoTimeAndDistanceCalcs();
    lcd.clear();  //Clear the LCD to show the new results

Really hard to read ... Instead of using a bunch of IF ... THEN, try switching it:

switch (displayCount) {
  case 0:
    showRPM = 1;
    showSpeeds = showMaximumSpeeds = showDistanceTravelled = showAverageSpeed = 0;
    break;
  case 1:
    showSpeeds = 1;
    showRPM = showMaximumSpeeds = showDistanceTravelled = showAverageSpeed = 0;
    break;
  case 2:
    showMaximumSpeeds = 1;
    showSpeeds = showRPM = showDistanceTravelled = showAverageSpeed = 0;
    break;
  case 3:
    etc., etc.
    break;
  default:
    // Do whatever needs to be done in a default state, for example cycle back to initial state, or turn off
    break;
}

This might make it easier to read.

As far as the debouncing goes, consider taking the sample code, as is, and where the LED in the code is being turned on/off, insert your code. Or, stick your whole routine into a function, and call the function from within the debounce loop. Might be easier that way.

Your code is way too dense to be readable - there are just too many obvious comments, e.g.

 revoloutions ++;  //add one to revoloutions - the wheel has turned round one more time
if(displayCount == 1){  //if display Count = 1...
averageSpeed = (distanceTravelled / timeInSeconds);  //This will give the average speed

Let the code tell the story - your variable names are mostly good and suited for what they do.

I'm also guessing you have too many variables with global scope when they don't need it.
Re-factor your code and dump the junk or it'll grow into an unmanageable mess.

And it doesn't help you to divide the same problem in to three different topics. Same people are reading them, same people are going to answer, pretty much.

When you read your sensor, and you can see that it is pressed, simply add delay(50) at first, change it if it doens't help. And what kind of a switch you actually have that is bouncing like a superball?

My recommendation is to read both changes from the sensor, you get better resolution if the speed is slow.

Cheers,
Kari