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!