My Bicycle Computer

My first Physical Computing class assignment for this summer was to create a bicycle computer. This is a device that you stick on your bike and it tells you how fast you are going, what your speed is, etc. Following is how I made my own bicycle computer.

I used an Arduino (with a 9-volt batter pack) to power several features. Data from these features were then displayed on an LCD screen. These features included:

1) Speedometer

2) Temperature Sensor

3) Timer

The speedometer was the most complicated. To make this feature I attached a small rare earth magnet to one of my bike’s wheel spokes. I then attached a magnetic sensor that would read every time the magnet came around the wheel (figure 1).

IMG_1758 copy

Figure 1. Magnet and sensor

This data was then read by the Arduino and computer to miles per hour using the radius of my bike wheel. Finally, miles per hour was displayed by the LCD.

One problem I had with this was getting to zero miles per hour when stopped. Technically, the LCD only displayed the previous revolution’s average velocity. The program would see the magnet, count up milliseconds, see the magnet aging, and then find the elapsed time which would be displayed on the LCD. (Kind of like when you first learn about integrals with that annoying add-up-the-bars method.) This doesn’t matter when you are peddling along at a good speed, but when you stop, the LCD ends up displaying something like 4mph when you aren’t going anywhere. To fix this I would have had to implement some code, saying something like “if elapsed time is > x, set speeed = 0.”

The temperature sensor was pretty easy. All I had to do was follow the schematic for the circuit read the temperature sensor, and use some code snipits from my instructor for converting the feedback from the sensor to degrees F and C. Basically, Arduinos reads all analog input as ints from 0 to 1023, and you need some conversions to change that into temperatures. I also learned to b vary careful about attaching a temperature sensor to a circuit backwards. When this happens the sensor becomes VERY hot in a short amount of time. If you ever attached a temperature sensor backwards, you will know. Trust me.

IMG_1766 copy

Figure 2. The temperature sensor on my breadboard (the large thing further down the board is an Ethernet chord plug-in).

The timer was also fairly simple. I just used a simple Arduino function (millis()) to count up milliseconds since the device was reset, and converted the milliseconds into the format of mm:ss. I could have done hours too without changing much.

IMG_1767

Figure 3. My hardware set up

IMG_1769

Figure 4. The finished project (as if any project is ever really finished).

It was kind of fun when a fellow bicyclist asked me what my weird, duct-tape-covered box was for

And finally, here is my code:

/*

Rose Beede 7/16/13, with snippits from Andrew Davidson

Code for “Bicycle Computer”

Features:

– speedometer, in mph

– temperature sensing

– timer, counting minutes and seconds since start time

*/

//this code computes rate from magnet sensor

//———————————————————–

long bike_r = 13.5; // bike wheel radius in inches         |

//———————————————————–

// ———— for speed sensing w/ magnet —————–

const int hallPin = 2; //magnet

const int ledPin = 13;

const int magnetIn = LOW;

const int magnetOut = HIGH;

int magPrev = magnetOut;

long prevRevTime;

long rpm = 0;

long mph = 0;

// ————– for sensing temp ——————-

const int tempSensor = A1;

int tempValue;  // raw analog data

int tempMV;     // corresponding voltage

int prevTemp = 0;   //for only updating if temp has changed, right now just pays attention to F

float tempCent;   // degrees Fahrenheit

float tempFahr;   // degrees Centigrade

//  ——————— LCD ————————

#include “Wire.h”

#include “LiquidCrystal.h”

LiquidCrystal lcd(0);

// ———————– setup ———————

void setup () {

pinMode(ledPin, OUTPUT);

pinMode(hallPin, INPUT); //magnet pin

pinMode(tempSensor, INPUT); // temp sensor input

// set up the LCD’s number of rows and columns:

lcd.begin(16, 2);

//set up serial monitor

Serial.begin (9600);

Serial.println(“*** start”);

}

// ———————- loop ————————

void loop () {

// ————– calculate and print speed ———–

int mag = digitalRead(hallPin);

//Serial.println(mag);

if (mag == magnetIn) {

digitalWrite(ledPin, HIGH);

if (mag != magPrev) {

// here is where the magnet is seen first

//calculate revs per min

long curRevTime = millis();

long thisRevTime = curRevTime – prevRevTime;

rpm = 60000 / thisRevTime;

Serial.println(rpm);

//write to LCD

// (note: line 1 is the second row, since counting begins with 0):

lcd.setCursor(0, 0);

mph = (rpm * 376.8 * bike_r)/(63360.0);

lcd.print(mph);

lcd.print(“mph  “);

//reset prevRevTime

prevRevTime = curRevTime;

}

}

else {

digitalWrite(ledPin, LOW);

}

magPrev = mag;  //reset magPrev

// ————– update and print temp ————–

tempValue = analogRead(tempSensor);

// first, convert the sensor reading to the right voltage level (5000 mV, since the Arduino port is +5V)

// the map function is just an efficient shortcut for some ratio math

tempMV = map(tempValue, 0, 1023, 0, 4999);

tempCent = (tempMV – 500) / 10.0;

tempFahr = (tempCent * 9 / 5.0) + 32;

if (tempFahr != prevTemp) {

//write to LCD

lcd.setCursor(12, 0);

lcd.print(int(tempFahr));

lcd.print(“F “);

lcd.setCursor(12, 1);

lcd.print(int(tempCent));

lcd.print(“C “);

}

prevTemp = tempFahr;

// —————- time since start —————-

lcd.setCursor(0, 1);

lcd.print(millis() / 60000);

lcd.print(“:”);

lcd.print((millis() / 1000) % 60);

}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s