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));
}