cpe 329 final project report

17
Final Project: Cycle Computer Bench #3: Chris Polis, Grant Frame CPE 329 SPR 2012, Harris Overview For our final project we built a cycle computer that tracks the can be mounted on a bicycle to track speed and temperature as well as control LED’s. We chose this project because it is something practical and was a challenge to build. Hardware The hardware we used for the project were: Arduino Uno (ATMega328P) 16 x 2 LCD Module with HD44780 controller 4 LED’s and 330Ω pull down resistors 2 switches Hall Effect (Magnetic field) sensor, mounted to bicycle fork, with 10kΩ resistor Magnet attached to bike rim Temperature sensor(TMP36) 9V battery and snap connector to barrel plug

Upload: chris-polis

Post on 27-Oct-2014

76 views

Category:

Documents


6 download

DESCRIPTION

Lab Report for my CPE 329 final project - an Arduino based cycle computer. Includes hardware diagrams, source code and operation instructions.

TRANSCRIPT

Page 1: CPE 329 Final Project Report

Final Project: Cycle ComputerBench #3: Chris Polis, Grant FrameCPE 329 SPR 2012, Harris

OverviewFor our final project we built a cycle computer that tracks the can be mounted on a bicycle to track speed and temperature as well as control LED’s. We chose this project because it is something practical and was a challenge to build.

HardwareThe hardware we used for the project were:

● Arduino Uno (ATMega328P)● 16 x 2 LCD Module with HD44780 controller● 4 LED’s and 330Ω pull down resistors● 2 switches● Hall Effect (Magnetic field) sensor, mounted to bicycle fork, with 10kΩ resistor● Magnet attached to bike rim● Temperature sensor(TMP36)● 9V battery and snap connector to barrel plug

Fig. 1: System Block Diagram

Page 2: CPE 329 Final Project Report

Fig. 2: Individual Component Schematics

Software

Page 3: CPE 329 Final Project Report

TestingWe first used the temperature sensor from project 3 and made sure it was functional and giving correct values on the oscilloscope. We then hooked up the LCD and made sure we were able to print to it. Next, we tested the hall effect sensor with the oscilloscope to test its range and sensitivity with the magnet we were using. This sensor gave us the most trouble - it operated differently when hooked up to the Arduino than it did when hooked up straight to the scope. Once we were able to get expected input, we hooked up switches, LEDs and wrote our program. Lastly, we connected the Arduino to 9V and attached the device to a bike. We realized that the hall effect sensor had to be connected in precisely the right position to capture the effect of the magnet moving past it. I rode my bike with a commercial cycle computer to check for accuracy, and our device ended up being really accurate - it always had <1mph difference in speed.

ConclusionsChris Polis:I enjoyed this project because we were able to create something that is practical and uses different hardware from what we learned in class, although using similar interfaces and code. Our project satisfied the guidelines in our proposal for an ‘A’ grade. One of the major obstacles we had with this project was making our device so that it could actually be used on a bike, ie

Page 4: CPE 329 Final Project Report

getting the Arduino to run off a 9v battery, where/how to setup the hall effect sensor and magnet to get consistent readings, and keeping everything secure. If I were to do this project again, I would have used the 4-bit mode on the LCD to free up ports on the Arduino and the ability to add sensors and different LED configurations. It would also have been neat if we had a memory chip or some way to keep a running total of distance traveled - that persisted when the device turned off. Grant and I worked about the same amount of time on the project - I did more of the hardware implementation, whereas he covered more of the software. We spent roughly five class periods on the project and another ten hours out of class working on the project, not counting proposal, report or presentation work time.Grant Frame:

Figuring out that the hall effect sensor worked when its pin was not set to be an input, but didn’t work when it was set as in input took some time. We actually got lucky, thinking it was the pin we hooked it to another and forgot to set that as an input. After it then started working we noticed what we had done and tested to see if setting the new port as an input would stop the hall sensor from working, which it did. So we went back to not setting it as an input. The timing was a large obstacle in the project. The sensor needed to read constantly but we didn’t want it to print constantly. The switches needed to be read in as well and so some time needed to be devoted to that. If we were to do this project again we would have looked into writing to the LCD in half bytes at a time. This would have freed up more pins for other things that we wanted to do. We both spent 5 class periods working on the project. I spent a lot more hours outside of lab working on the code, probably 8 or so and Chris spent a lot of time, around 8 hours, getting the hardware hooked up and testing the accuracy of the sensor. We reached the ‘A’ requirements as outlined in our proposal.

User ManualSetup

○ The hall effect sensor must be attached to your bicycle’s fork and oriented such that the long side is perpendicular to the bike wheel..

○ There must be a magnet on the rim of your front wheel.○ Make sure that the magnet is attached such that it passes within a half inch of

the sensor when the wheel is spinning.

Power ON / OFFTo turn on the device, simply connect a 9v battery attached to a barrel plug into the Arduino board.

Normal ModeBy default, the LCD will display temperature on the top line and speed on the bottom line and the LEDs will be on. Temperature will be in Fahrenheit, speed in MPH and the LEDs are set to on.

Settings Mode (to toggle LEDs, change temperature or speed format)To get into settings mode, toggle the settings switch - the rightmost switch.Once in settings mode, ‘Speed’, ‘LED’, ‘Temperature’ will cycle through on the LCD - once it is displaying the one you want to modify which is indicated with an arrow, toggle the select(left) switch.Toggle the select(left) switch again to make changes.Toggle the settings(right) switch to return to normal mode.

Proposal

Page 5: CPE 329 Final Project Report

1. Grant Frame, Chris Polis CPE 329, SPR 12, Bench #3 Project 4 Sensor Used: Hall Effect Sensor

2. The sensor will be used to measure the rpm of a tire wheel. The sensor will measure the speed at which the wheel spins when a magnet is placed on the wheel. The sensor spikes when near a magnet so when the magnet on the tire gets close it will spike, over time letting us know the speed at which one is traveling. This measure will be used to calculate the current speed that is being traveled at to be displayed on the LCD.

3.

4. Milestones[DONE] 5/11 - Order and receive hardware (Chris)[DONE] 5/14 - Connect hardware (Both)5/16 - Configure sensor, ensure accurate reading (Both)5/18 - Write basic software functionality (Grant)5/21 - Test, improve software (Chris)5/25 - Add more complex functionality to project (Both)

Page 6: CPE 329 Final Project Report

6/1 - Demo, finish lab report (Both)

5. The physical rotations of the wheel affect the outcome shown. So the environment plays a role in the overall performance of the device. The sensor itself should behave as promised by the spec sheet. The speed shown should be that which one is currently traveling at.

6. Testing will be done as the code is written. The sensor will be hooked up first and tested to see if and what the sensor is outputting. Then the LCD will be attached and checked for accuracy. Then the code switching between the types of measurement will be written and tested. Each will be tested to make sure that it can work properly on its own. Then a button will be added to switch between the two. Next the LEDs will be connected to and made to light up. Then they will be lit up based on the speed that is being travelled.

7. A ‘B’ for this project will be to just have the sensor read the speed that is being traveled and printed to the screen in different scales. An ‘A’ grade will include the LEDs, and the board hooked up to a bike.

8. This project will be completed purely to provide fun to the user. It is being designed to bring enjoyment, and as a result is not going to be designed to be harmful in any way.

Source CodeLines of code: 386 (incl. whitespace, comments)Download size: 6022 bytes/* * Project 4 Code * CPE 329 Spring 2012 * * Written By: Chris Polis and Grant Frame */

#define F_CPU 16000000UL#include <avr/io.h>#include <util/delay.h>

Page 7: CPE 329 Final Project Report

#include <string.h> // Used to convert integers to string#include <stdlib.h>

// Values for data bus to LCD#define FUNCSET 0x3C#define DISPLAY 0x0C#define CLEAR 0x01#define ENTRY 0x06

// Different formats for temperature#define FARENHEIT_MODE 0#define CELSIUS_MODE 1#define KELVIN_MODE 2

// Different formats for speed#define MPH_MODE 1#define KMPH_MODE 0

#define LED_ON 1#define LED_OFF 0

#define ON 0#define OFF 1

void writeTo(char *string);void write(int RS, int value);void setupCycle(int value);void clearScreen();void skipLine();void init();void Initialize_ADC0();void getTemp();void getSpeed();void optionChoices(int loc);

int voltageDigital, lastVoltageDigital;int time, changes, last, current, rpm, speedCount, noValue = 1;float speed;int button, mode, lastButton, cycleCount;int ledMode; int settings, loc, first = 1;int option, switchOp, preSwitch;float voltage, temp;int speedMode;const double KM_CONST = 12.678;const double MPH_CONST = 7.877;const double CONVERT_TO_KMPH = 1.60934;const double CONVERT_TO_MPH = 0.62137;char buffer[10];char buffer2[10];char hallBuff[10];char tempBuff[8];

int main(void){

init(); // Initialize LCD, input and output ports

Page 8: CPE 329 Final Project Report

Initialize_ADC0(); // Initialize ADC0

speedMode = MPH_MODE; //set the speed modeledMode = LED_ON; //set the led mode

while(1){

//delay for 500ms between each print, check the speed every ms.//If 10s have elapsed with no speed reading then signify that no//value has been read. for(int i = 0; i < 500; i++) {

_delay_ms(1);speedCount++;if(speedCount == 10000)

noValue = 1;getSpeed();

}

first = 1;loc = 0;//If setting is on then print settings to LCDwhile(settings == ON) {

if(first) {first = 0;clearScreen();

}

//loop and print the different settings that can be changed. for(int i = 0; i < 2; i++) {

if(loc == 0)writeTo("Temperature ");

else if(loc == 1)writeTo("Speed ");

else if(loc == 2)writeTo("LED ");

if(i == 0) {writeTo("<-");skipLine();loc++;

} else {setupCycle(0x80);

}

if(loc == 3)loc = 0;

}

//read settings switchsettings = !(PINB & 0x20);

//delay 1s bewteen each print and check to see if the option switch has been

//flipped every ms. for(int i = 0; i < 1000; i++) {

option = (PINB & 0x08);_delay_ms(1);

Page 9: CPE 329 Final Project Report

if(option) {optionChoices(loc - 1);i = 1000;

}}

}

//write the main screen informationclearScreen();writeTo("TEMP: ");getTemp();writeTo(tempBuff);

if(mode == CELSIUS_MODE) {write(1, 223);writeTo("C");

} else if(mode == FARENHEIT_MODE) {write(1, 223);writeTo("F");

} else if(mode == KELVIN_MODE) {writeTo("K");

}

skipLine();

if(speedMode == KMPH_MODE) {writeTo("KM/H: ");

} else if(speedMode == MPH_MODE) {writeTo("MP/H: ");

}

if(noValue)writeTo("0.0");

else {writeTo(buffer2);writeTo(".");writeTo(buffer);

}

//turn leds on and offif(ledMode == LED_ON)

PORTB |= 0x10;else

PORTB &= 0x00; //PORTB = 0x00;

// Check settings mode switchsettings = !(PINB & 0x20);

}

return 0;}

// Option choices are listed based on which option was selected. void optionChoices(int loc){

Page 10: CPE 329 Final Project Report

loc++;preSwitch = 1;while(settings == ON) {

clearScreen();if(loc == 1) {

if(mode == CELSIUS_MODE) {write(1, 223);writeTo("C");

} else if(mode == FARENHEIT_MODE) {write(1, 223);writeTo("F");

} else if(mode == KELVIN_MODE) {writeTo("K");

}

if(switchOp != preSwitch) {if(mode == 2)

mode =0;else

mode++;}

}

else if(loc == 2) {if(speedMode == MPH_MODE)

writeTo("MPH");else if(speedMode == KMPH_MODE)

writeTo("KMPH");

if(switchOp != preSwitch) {if(speedMode) {

speedMode = 0;speed = speed * CONVERT_TO_KMPH;

}else {

speedMode = 1;speed = speed * CONVERT_TO_MPH;

}

itoa((speed / 100), buffer2, 10);itoa(((int)speed % 100), buffer, 10);

}}

else if(loc == 0) {if(ledMode == LED_ON)

writeTo("ON");else if(ledMode == LED_OFF)

writeTo("OFF");

if(switchOp != preSwitch) {if(ledMode)

ledMode = 0;else

ledMode = 1;

Page 11: CPE 329 Final Project Report

}}

//read in values from switchessettings = !(PINB & 0x20);preSwitch = switchOp;switchOp = (PINB & 0x08);

}}

void getTemp(){

ADCSRA = 0xC7; // ADC - start conversion

lastButton = button;if(button == ON && lastButton == OFF) // If button has been pressed

mode = (mode == 2) ? 0 : mode + 1; // Switch to next mode

voltageDigital = ADC & 0x3FF; // Get temperature value from ADC (0 -> 1024)

if(voltageDigital != lastVoltageDigital) { // If voltage has changed

voltage = 5.0 * voltageDigital / 1024.0; // Get float representation of voltage

voltage -= .5; // see equation below

temp = voltage * 100; // temp (in Celsius) = (voltage - .5) * 100

if(mode == CELSIUS_MODE) {itoa(temp, tempBuff, 10);

} else if(mode == FARENHEIT_MODE) {temp = (temp * 9 / 5) + 32; // Convert celsius to

farenheititoa(temp, tempBuff, 10); // Convert integer

to string

} else if(mode == KELVIN_MODE) {temp += 273; // Convert celsius

to kelvinitoa(temp, tempBuff, 10); // Convert integer

to string}

}

lastVoltageDigital = voltageDigital; // Update lastVoltage to check next cycle if it has changed}

void getSpeed(){

current = PINB & 0x04; //pin location of the hall effect sensorif(last != current) {

changes++;

Page 12: CPE 329 Final Project Report

speedCount = 0; //speed count is set to zero if a new value is read.

}last = current;time++;

// Sample for 10 passes, then calculate rpmif(changes == 9) {

rpm = 600000 / time;

// Write out mph or km/hif(speedMode == KMPH_MODE) {

speed = KM_CONST * rpm; itoa((speed / 100), buffer2, 10);itoa(((int)speed % 100), buffer, 10);

} else if(speedMode == MPH_MODE) {speed = MPH_CONST * rpm; itoa((speed / 100), buffer2, 10);itoa(((int)speed % 100), buffer, 10);

}

time = 0;changes = 0;noValue = 0;

}}// Initialize LCD module, Arduino input and output portsvoid init(){

UCSR0B = 0x00; // Turn off TX and RX DDRD |= 0xFF; // Outputs on PORTD

DDRB |= 0x7B; // Outputs on PORTB do not include Pin that has hall effect Sensor

_delay_ms(20);setupCycle(FUNCSET); // Settings for LCD_delay_ms(1);setupCycle(DISPLAY); // Enable LCD display_delay_ms(1);setupCycle(CLEAR); // Clear LCD screen_delay_ms(1);setupCycle(ENTRY); // Set LCD mode to entry_delay_ms(1);

}

// Used to send data to LCD module by setting enable and passing in valuevoid setupCycle(int value){

PORTB = ledMode == LED_ON ? 0x12 : 0x02;

_delay_ms(50);

PORTD = value;_delay_ms(50);

PORTB = ledMode == LED_ON ? 0x10 : 0x00;

Page 13: CPE 329 Final Project Report

}

// Write a single character to the LCDvoid write(int RS, int value){

PORTB = RS;_delay_us(20);

PORTB = 0x02 | RS;_delay_us(20);

PORTD = value;_delay_us(20);

PORTB = RS;_delay_ms(1);

}

// Write a string(multiple characters) to LCDvoid writeTo(char *string){

for(int i = 0; i<strlen(string); i++)write(1, (int)string[i]);

}

// Clears the LCD of all charactersvoid clearScreen(){

setupCycle(CLEAR);_delay_ms(1);setupCycle(ENTRY);

}

// Moves the cursor to the bottom linevoid skipLine() {

setupCycle(0xC0);_delay_ms(1);

}

// Initialize ADCvoid Initialize_ADC0(void){ ADCSRA = 0x87; //Turn On ADC and set prescaler (CLK/128--62 kHz) //MAX A/D conversion rate 5 kHz @ 62 kHz frequency

ADCSRB = 0x00; //turn off autotriggerADMUX = 0x00; //Set ADC channel ADC0 and AREF input (wire to 5V)

}