Instructables

Arduino Bike Speedometer

Picture of Arduino Bike Speedometer
IMG_9279 copy.jpg
Monitor your road speed using the Arduino. This project uses a magnetic switch (also called a reed switch) to measure the speed of one of the bike's wheels.  The Arduino calculates the mph, and send this information out to the LCD screen on the handlebars as you ride.  It is compatible with any kind of bike/wheel, simply enter the radius of the wheel in the firmware to calibrate the device for your setup.



Parts List:

(1x) Arduino Uno REV 3 Radioshack 276-128
(1x) Switch-Magnetic Reed Radioshack 55050593
(1x) 10K Ohm 1/4-Watt Carbon Film Resistor Radioshack #271-1335
(1x) 9V Alkaline Battery Radioshack #23-866
(1x) Heavy-Duty 9V Snap Connectors Radioshack #270-324
(1x) PC Board with Copper Radioshack #276-147
(1x) Parallax 27977-RT Serial Backlit LCD Radioshack 276-120
(x2) SPST PC-Mountable Submini Toggle Switch Radioshack #275-645
(2x) Male Header Pins Jameco 103393
(1x) Female Pin Sockets Jameco 308567

Additional Materials:
22 Gauge Wire Radioshack #278-1224
Solder Radioshack #64-013
sand paper
plywood
wood glue
hot glue
screws
zip ties
sugru

Download Arduino IDE

 
Remove these adsRemove these ads by Signing Up

Step 1: Schematic

Picture of Schematic
The schematic for this project is shown above.

It consists of three switches:
-one to connect to a 9V power supply
-one to switch the backlight of the LCD on and off
-a magnetic switch (called a reed switch) which closes each time the wheel completes one full rotation.

The Parallex LCD is designed to connect to the arduino using only three pins (ignore the labels and the other pins int his schematic).  One to 5V, one to ground, and a third to serial out (TX)- on the arduino, serial out is digital pin 1.

10kOhm resistors are connected to the reed and backlight switches to prevent excess current between 5V and ground (you should never directly connect 5V and ground on the arduino!)

Step 2: Protoboard

Picture of Protoboard
IMG_5508 copy.jpg
Solder three rows of header pins on the protoboard so that the arduino will snap to it as shown in the images above.
1-40 of 101Next »
cool
biinJC2 months ago

Hi. Can I still use the code for reed if I change the reed switch to hall effect sensor? Because my reed switch can't get accurate mph(double / triple of the actual speed) when the speed is slow

amandaghassaei (author)  biinJC2 months ago
but it does work when it's fast?

When it get faster, the reed switch works fine when the speed increase even the result i get doesn't show a linear increment when i increase the voltage by 0.5 each time (I am using a DVD player motor with disc taped on it to act as the bike tyre) and it break down after 47mph.

Murphy403 months ago

How would you change the final speed code to also display the distance travelled along with the speed?

b3nz13 months ago

I've tried using this code to measure windspeed on an anemometer for a project of mine. it's a rotating magnet and a reed switch so it's the same principle. The reed test works fine. i've changed the radius (0.87 inches) to fit with my windspeed sensor. However when i upload the code, the serial port view just gives me 0's for MPH for the first reading then a steady steam of 28.21 MPH. Any ideas?

achand83 months ago

I thought of the same thing. But I would have used a hall effect sensor and a standalone Atmega 8. Not everyone has an arduino for every project

M.Hawse4 months ago

Thank you so much for posting this project. I'm building something similar to this and I came across this project of yours while looking for some additional ideas. It provided a lot of much needed inspiration. Best wishes to you...

jeneral7 months ago
hello..

im using this LCD
http://www.engineersgarage.com/electronic-components/16x2-lcd-module-datasheet

is there anything i have to modify?
amandaghassaei (author)  jeneral6 months ago

this lcd does not support serial communication, you can get it to work, but you will have to read the datasheet and make some changes to the code.

Could you please help me with the code for this LCD display??? Please (Serial communication 16x2 display) Thank You

satrio5 months ago

Amazing! sorry I curious, may I get a picture of proteus simulation
project? I really want to know how it does work very nice. Thanks in
advance.

BrianRico5 months ago

Your design will help out tremendously. Our design includes controls for a flywheel that will help stabilize a bicycle at slow velocities, and it is extremely important to get a very accurate forward velocity of the bike at slow velocities. Instead of using one magnet, my idea is to use multiple magnets equally spaced around the tire to get a more accurate angular velocity of the wheel. I would like to first ask for your help on modifying your code to include reading multiple magnets with one switch. Help modifying your code at all will be greatly appreciated. Love the instructable.

amandaghassaei (author)  BrianRico5 months ago
if your magnates are spaced evenly around the wheel then you'll just need to divide the speed calculation by the number of magnets to get the right speed for your setup. Sounds cool, post a pic when you're done!
pzedzik6 months ago

Hello,

I was just wondering about the code for radius. Would it not be better to put in the radius on the wheel of where the reed switch is, vs. just the radius of the wheel? That way the speed is much more accurate?

pzedzik pzedzik6 months ago

***like where the magnet on the wheel is? (I'm using a hall effect sensor for my project)***

amandaghassaei (author)  pzedzik6 months ago

the reed switch is used to measure rpm, so it doesn't matter where it is on the wheel when we measure it. The radius of the wheel is used to calculate the distance the bike travels per rotation.

mblanco rios7 months ago
Good!
Miss I have a problem with your project when I compile I get the first line goes to zero in the other 47.68 without placing the magnet I can failicar the correct scheme reed switch assembly
amandaghassaei (author)  mblanco rios6 months ago

does it work after you spin the wheel?

AgnostosTimos10 months ago
Awesome instructable. I am working on a similar speedometer for my motorcycle. I was wondering, which would be better to use, a magnetic reed switch like you did or a hall effect sensor. I have a feeling that the reed switch might not be fast enough to sense the front wheel spinning at 60 - 70 MPH. Any suggestions?
amandaghassaei (author)  AgnostosTimos8 months ago
I think the hall effect sensor will be better, the reed switch is mechanical and will eventually break down.
yoopee9 months ago
I have the same problem. It also shows 56.84 when bike goes very slow.
Anyone can help with code? Amanda? :-)
Hello! Nice job you made. I tried to make this at home. i used the code without the lcd, and the values i sent to the serial monitor. It worked but i had a problem... When the reed is right in front of the magnet, the same number (56.84) appears at the monitor, while the reed is in front. Do you know what is happening?
One more thing. In this code, how can I make and send to the monitor an avarege speed of the bike? Can you help me?

Thanks

jcservek1 year ago
I'm attempting to run this project without the display, only utilizing the reed switch which I harvested from an old bike computer to begin with. Unfortunately, when I check the serial monitor after uploading the sketch that is supposed to output mph, I get one or two 0.0mph readings, and then a continuous string of 45.91. If I put the magnet to the switch, it will drop back to 0.0, but only stay there so long as the magnet is continuously activating the switch. Does anyone have any ideas as to what might be causing this behavior?
amandaghassaei (author)  jcservek1 year ago
cool, I think some of the lcd specific commands were getting in the way, try this:

//outputs speed of bicycle to LCD

//calculations
//tire radius ~ 13.5 inches
//circumference = pi*2*r =~85 inches
//max speed of 35mph =~ 616inches/second
//max rps =~7.25

#define reed A0//pin connected to read switch

//storage variables
float radius = 13.5;// tire radius (in inches)- CHANGE THIS FOR YOUR OWN BIKE

int reedVal;
long timer = 0;// time between one full rotation (in ms)
float mph = 0.00;
float circumference;
boolean backlight;

int maxReedCounter = 100;//min time (in ms) of one rotation (for debouncing)
int reedCounter;


void setup(){

reedCounter = maxReedCounter;
circumference = 2*3.14*radius;
pinMode(1,OUTPUT);//tx
pinMode(2,OUTPUT);//backlight switch
pinMode(reed, INPUT);

// TIMER SETUP- the timer interrupt allows preceise timed measurements of the reed switch
//for mor info about configuration of arduino timers see http://arduino.cc/playground/Code/Timer1
cli();//stop interrupts

//set timer1 interrupt at 1kHz
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;
// set timer count for 1khz increments
OCR1A = 1999;// = (1/1000) / ((1/(16*10^6))*8) - 1
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS11 bit for 8 prescaler
TCCR1B |= (1 << CS11);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);

sei();//allow interrupts
//END TIMER SETUP

Serial.begin(9600);
}

ISR(TIMER1_COMPA_vect) {//Interrupt at freq of 1kHz to measure reed switch
reedVal = digitalRead(reed);//get val of A0
if (reedVal){//if reed switch is closed
if (reedCounter == 0){//min time between pulses has passed
mph = (56.8*float(circumference))/float(timer);//calculate miles per hour
timer = 0;//reset timer
reedCounter = maxReedCounter;//reset reedCounter
}
else{
if (reedCounter > 0){//don't let reedCounter go negative
reedCounter -= 1;//decrement reedCounter
}
}
}
else{//if reed switch is open
if (reedCounter > 0){//don't let reedCounter go negative
reedCounter -= 1;//decrement reedCounter
}
}
if (timer > 2000){
mph = 0;//if no new pulses from reed switch- tire is still, set mph to 0
}
else{
timer += 1;//increment timer
}
}

void displayMPH(){
Serial.print("Speed = ");
Serial.print(mph);
Serial.println(" MPH ");
}

void loop(){
//print mph once a second
displayMPH();
delay(1000);
}


Hey, nice project, but isn't it a little big?! :)
I know it's not so easy to keep things small, but i would suggest using an Arduino Nano or similar, and a smaller 3D Printed box...
And regarding the electronics of it, maybe use a dynamo and a rechargeable battery?
The older dynamo were pretty annoying, but i think the newer ones are pretty awesome, since they're so silent and have a bearly noticeable resistance (mechanical resistance) since they're in the center of the wheel.
Anyhow, nice project, i like these kinds of projects, because they're relatively easy to build and you can always improve them with fairly small efforts (eg. add average speed, driven distance, automatic standby when the wheel didn't turn for a certain amount of time, etc.), there are thousands of possibilities! :)
So far I have everything working the way it should, but i can't get my lcd display to display anything at all but the backlight works fine. Any advice?
amandaghassaei (author)  allenkevan241 year ago
it's the same lcd? you might try some of these sketches just to make sure it's working.
http://learn.parallax.com/KickStart/27977
12niraj121 year ago
what is the total power lost in the ARDUINO developed speedometer.
col0n1 year ago
Would this be possible to make with an arduino micro?
amandaghassaei (author)  col0n1 year ago
Yes
shad0w881 year ago
Nice!...Would this work for a motorcycle? With more added functionality like temp, battery or Fuel?

How about RPM can that be calculated?
amandaghassaei (author)  shad0w881 year ago
probably, I think the limiting factor would be the speed of the reed switch- there is a mechanical piece in the switch that moves back and forth to complete the circuit. At 60mph, ~1ft radius tires rotate at 25-30 rotations per second. As long as the reed switch can switch back and forth that quickly you would be able to measure speed/rpm on a motorcycle

If you want the lcd to output rpm:
add:
float rpm = 0.00; //variable rpm
and insert the line:
rpm = float(6000)/float(timer);//calculate rotations per minute
after:
mph = (56.8*float(circumference))/float(timer);
and:
rpm=0;
after:
mph=0;

and create the function:
void displayRPM(){
Serial.write(12);//clear
Serial.write("RPM=");
Serial.write(13);//start a new line
Serial.print(rpm);
Serial.write(" RPM ");
//Serial.write("0.00 RPM ");
}

and call this function in the main loop when you would like to display the RPM

and yes you could definitely expand to include temp, battery, etc, there are plenty of available pinson the arduino.
amandaghassaei (author)  amandaghassaei1 year ago
I realized that the line should say:
rpm = float(60000)/float(timer);//calculate rotations per minute
Why not use a Hall Effect sensor? There are no moving parts and it works off the disruption of a magnetic field. They are used in many high speed applications because of this. Those POV devices you see for bike wheels use a hall effect sensor to know when to flash the LEDs for the POV illusion.
amandaghassaei (author)  soshimo1 year ago
hall effect sensor would work too
would you be able to post the whole rpm code please, i just cant get it to work.

Thanks.
amandaghassaei (author)  tesladude1231 year ago


Thankyou. It works perfectly.
motto201 year ago
I am trying to understand your code (which works great by the way) and am wondering about your RPM and MPH calculations. Where do the values 56.8 and 6000 come from in each calculation? Thank you.
1-40 of 101Next »
Pro

Get More Out of Instructables

Already have an Account?

close

PDF Downloads
As a Pro member, you will gain access to download any Instructable in the PDF format. You also have the ability to customize your PDF download.

Upgrade to Pro today!