Difference between revisions of "Electric Longboard"

From ESE205 Wiki
Jump to navigation Jump to search
Line 53: Line 53:
 
#When we printed the data that we read from the serial port it came out line by line starting with either $GPGGA, $GPGLL, $GPGSA, $GPGSV, GPRMC or $GPVTG, followed by a string of numbers separated by commas. At first we didn't understand what these values were. The GPS chip that we bought came with a data sheet that explained what these values were. The values at the beginning of the lines are called message IDs. So to find velocity, for example, we had to look for the lines that started with $GPVTG which spits out values that correspond to course over ground speed. Lines with this message ID had 8 comma separated values that followed it. The value that corresponded to kilometers per hour was the value 7 down from $GPVTG. A similar process was used to find Longitude and Latitude.
 
#When we printed the data that we read from the serial port it came out line by line starting with either $GPGGA, $GPGLL, $GPGSA, $GPGSV, GPRMC or $GPVTG, followed by a string of numbers separated by commas. At first we didn't understand what these values were. The GPS chip that we bought came with a data sheet that explained what these values were. The values at the beginning of the lines are called message IDs. So to find velocity, for example, we had to look for the lines that started with $GPVTG which spits out values that correspond to course over ground speed. Lines with this message ID had 8 comma separated values that followed it. The value that corresponded to kilometers per hour was the value 7 down from $GPVTG. A similar process was used to find Longitude and Latitude.
 
#Now we had to display the data. We wanted to display the riders current velocity during the ride and at the end of the ride display their max speed, average speed and distance traveled and map where they went. To display the data the rider's velocity, we had to use pythons split() method for strings. The split method takes in a string as a parameter:let's call this string parameter the separator. When you call the split method on a string it separates the string by the separator you input as its parameter and the method returns an array with every element between the separators in the string stored in a different index in the array.So, In our program, we read a line from the serial port and stored it in a string x. Then we called x.split(",") which stored each line we read as an array with each value that was separated by a comma in a different index in the array. To find velocity we created an if stated that checked for the condition array[0]=="$GPVTG". Array[0] is what each line would start with--the message ID. Once this condition was met we knew that the 7th index in the array stored the rider's velocity in kilometers per hour.
 
#Now we had to display the data. We wanted to display the riders current velocity during the ride and at the end of the ride display their max speed, average speed and distance traveled and map where they went. To display the data the rider's velocity, we had to use pythons split() method for strings. The split method takes in a string as a parameter:let's call this string parameter the separator. When you call the split method on a string it separates the string by the separator you input as its parameter and the method returns an array with every element between the separators in the string stored in a different index in the array.So, In our program, we read a line from the serial port and stored it in a string x. Then we called x.split(",") which stored each line we read as an array with each value that was separated by a comma in a different index in the array. To find velocity we created an if stated that checked for the condition array[0]=="$GPVTG". Array[0] is what each line would start with--the message ID. Once this condition was met we knew that the 7th index in the array stored the rider's velocity in kilometers per hour.
 +
#For the encoder first we started with a six slit disk for the wheel and simple block for the LED and photocell mounts that would have been glued to the truck. It quickly became apparent the simple box was not going to be sufficiently secure. To solve this we added a ring to go around the truck with a box on top to house the LED and photocell respectively. Once on the truck we wanted to secure the spacing so we created specific mm spacers to go in between the wheel, photocell mount, and LED mount. After we started getting readings from the ADC we realized we only needed to measure single rotations as opposed to fractions of rotations and so we printed another ring with one larger hole to go around the wheel. We were still not getting peaks with enough definition across surfaces and in different lighting conditions so we tried a number of filters that calculated standard deviations and means of data and tried to locate values that would cross a constantly updated filter, but none of these worked so we 3D printed another piece to act as a shield for the LED. This shield was lined with aluminum foil to reflect the LED light and once secured we finally got defined peaks over surfaces and in different lighting conditions.
 +
#Hooking up the mcp3002 ADC required finding data sheets for the raspberry pi and the ADC in order to match the SPI pins and correctly wire the channel, voltage and ground. Once we had everything wired we could manipulate the circuit connected to channel 0. Initially we just had the photocell connected in series with a resistor to a voltage source, but our values we not highly responsive and made little sense. After a number of trials we discovered that we needed a voltage divider and connected one lead of the resistor to the ground. This way the photocell had a resistor pull-up that increases the saturation rate of the cell and gave us much more defined data from the ADC. Once this was all hooked up we could experiment with different resistor values based on the average ambient light we were experiencing and the subsequent average photocell resistance.
 +
#To decide on the filter size for the data we had to calculate how fast our max speed would require we read values. ....To detect a peak, we intialized an array to hold three values. We took a filtered reading and stored it in array[0] then another filtered reading and stored it in array[1] and a third reading that we stored in array[2]. We then checked if(array[1]>array[0] and array[1]>array[2]) we incremented a rotations variable by one.  After this we shifted our readings over (array[0]=array[1], array[1]=array[2] and then we took a new filtered reading and stored it in array[2] and checked the if statement again. We then checked every second the size of the counter. and multiple this by .95. We multiplied this by .95 because the diameter of the wheel was 84 millimeters so multiplied by pi is the circumference then multiplied by 360 and divided by 1,000,000 converts rotations per second to kilometers per hour. 
 +
#Concrete clouds and other environmental factors can block the GPS signal. When this happened we would not get any velocity values. We wanted to record the rider's velocity throughout the whole trip so when the gps chip was unable to receive reliable data we started storing the velocity values recorded by our encoder. The code we wrote searched for the $GPVTG message Id and then we said if array[7]==0 run our encoder method.
 +
#Mounting all of the components meant 3D printing a plate to hold the raspberry pi and an enclosure for the breadboard and wires. In addition holes for the GPS wires and a mount of the GPS on the outside of the cover were added. After the pi was secure we were able to solder the wires to the encoder on the wheel and attach them to the breadboard.
 
==Budget==
 
==Budget==
  

Revision as of 00:13, 3 May 2016

Project Overview

Our goal in this project was to modify the Longboard riding experience. In particular, when riding a Longboard for commuting or exercise there is no way to certainly know how far or fast one has ridden. Using a GPS chip and an encoder on the wheel we programmed a Raspberry Pi 2 Model B to collect data from the board. We could then display the data on a map of the area tracing the route taken. This design enhances the Longboard riding experience by making it interactive and goal driven, while also yielding tangible results.

Team Members

  • Max Cetta
  • Jacob Frank
  • Alden Welsch (TA)

Objectives

  1. Use GPS data to track distance and location of rides
    1. Use the serial port to connect to the GPS.
    2. Read data and write it into a text file.
    3. Display data
  2. Have an encoder on the wheel to measure top ground speed and average speed over a ride
    1. Designing and printing the encoder
    2. Wiring the ADC and using SPI pins to communicate with the Raspberry Pi
    3. Writing code to filter and interpret the data to locate peaks

Challenges

  1. Receiving data from the GPS chip
  2. Interpreting the data
    • Isolating desired data from the GPS data stream which provided other information that was not useful for our project
  3. Displaying the data
    • How to get the data off the Raspberry Pi
    • Displaying the riders position on a map
    • Displaying the riders velocity on computer screen
  4. Designing Encoder
    • Ensuring mount would attach to the truck of the Longboard
    • Making sure the mounts were able to house the LED and photocell reliably and safely
    • Stabilizing results across all lighting conditions and riding surfaces
  5. Hooking up the Analog to Digital Converter
    • Locating the SPI pins and correctly wiring them to the ADC
    • Building the voltage divider
    • Choosing the resistance to use for more rapid photocell saturation
  6. Writing code to read the ADC values, filter, and interpret them
    • Creating a properly sized filter to stabilize noise in data
    • Locating a peak in the data and ensuring that only 1 peak was counted
  7. Environmental effects on GPS accuracy
    • Concrete, heavy clouds and other structures will obscure view to satellites
    • Locating and eliminating unreliable data
    • Substituting encoder data for these instances
  8. Mounting
    • Taking all of our components and putting them in a compact container which can be secured to the longboard
    • Maintaining as light a design as possible considering the board is being manually powered
    • Keeping all the components safe and dry

Solutions

  1. To receive data from the gps chip we did...
  2. When we printed the data that we read from the serial port it came out line by line starting with either $GPGGA, $GPGLL, $GPGSA, $GPGSV, GPRMC or $GPVTG, followed by a string of numbers separated by commas. At first we didn't understand what these values were. The GPS chip that we bought came with a data sheet that explained what these values were. The values at the beginning of the lines are called message IDs. So to find velocity, for example, we had to look for the lines that started with $GPVTG which spits out values that correspond to course over ground speed. Lines with this message ID had 8 comma separated values that followed it. The value that corresponded to kilometers per hour was the value 7 down from $GPVTG. A similar process was used to find Longitude and Latitude.
  3. Now we had to display the data. We wanted to display the riders current velocity during the ride and at the end of the ride display their max speed, average speed and distance traveled and map where they went. To display the data the rider's velocity, we had to use pythons split() method for strings. The split method takes in a string as a parameter:let's call this string parameter the separator. When you call the split method on a string it separates the string by the separator you input as its parameter and the method returns an array with every element between the separators in the string stored in a different index in the array.So, In our program, we read a line from the serial port and stored it in a string x. Then we called x.split(",") which stored each line we read as an array with each value that was separated by a comma in a different index in the array. To find velocity we created an if stated that checked for the condition array[0]=="$GPVTG". Array[0] is what each line would start with--the message ID. Once this condition was met we knew that the 7th index in the array stored the rider's velocity in kilometers per hour.
  4. For the encoder first we started with a six slit disk for the wheel and simple block for the LED and photocell mounts that would have been glued to the truck. It quickly became apparent the simple box was not going to be sufficiently secure. To solve this we added a ring to go around the truck with a box on top to house the LED and photocell respectively. Once on the truck we wanted to secure the spacing so we created specific mm spacers to go in between the wheel, photocell mount, and LED mount. After we started getting readings from the ADC we realized we only needed to measure single rotations as opposed to fractions of rotations and so we printed another ring with one larger hole to go around the wheel. We were still not getting peaks with enough definition across surfaces and in different lighting conditions so we tried a number of filters that calculated standard deviations and means of data and tried to locate values that would cross a constantly updated filter, but none of these worked so we 3D printed another piece to act as a shield for the LED. This shield was lined with aluminum foil to reflect the LED light and once secured we finally got defined peaks over surfaces and in different lighting conditions.
  5. Hooking up the mcp3002 ADC required finding data sheets for the raspberry pi and the ADC in order to match the SPI pins and correctly wire the channel, voltage and ground. Once we had everything wired we could manipulate the circuit connected to channel 0. Initially we just had the photocell connected in series with a resistor to a voltage source, but our values we not highly responsive and made little sense. After a number of trials we discovered that we needed a voltage divider and connected one lead of the resistor to the ground. This way the photocell had a resistor pull-up that increases the saturation rate of the cell and gave us much more defined data from the ADC. Once this was all hooked up we could experiment with different resistor values based on the average ambient light we were experiencing and the subsequent average photocell resistance.
  6. To decide on the filter size for the data we had to calculate how fast our max speed would require we read values. ....To detect a peak, we intialized an array to hold three values. We took a filtered reading and stored it in array[0] then another filtered reading and stored it in array[1] and a third reading that we stored in array[2]. We then checked if(array[1]>array[0] and array[1]>array[2]) we incremented a rotations variable by one. After this we shifted our readings over (array[0]=array[1], array[1]=array[2] and then we took a new filtered reading and stored it in array[2] and checked the if statement again. We then checked every second the size of the counter. and multiple this by .95. We multiplied this by .95 because the diameter of the wheel was 84 millimeters so multiplied by pi is the circumference then multiplied by 360 and divided by 1,000,000 converts rotations per second to kilometers per hour.
  7. Concrete clouds and other environmental factors can block the GPS signal. When this happened we would not get any velocity values. We wanted to record the rider's velocity throughout the whole trip so when the gps chip was unable to receive reliable data we started storing the velocity values recorded by our encoder. The code we wrote searched for the $GPVTG message Id and then we said if array[7]==0 run our encoder method.
  8. Mounting all of the components meant 3D printing a plate to hold the raspberry pi and an enclosure for the breadboard and wires. In addition holes for the GPS wires and a mount of the GPS on the outside of the cover were added. After the pi was secure we were able to solder the wires to the encoder on the wheel and attach them to the breadboard.

Budget

Item Quantity Price Vendor Link
GPS Receiver - GP-20U7 (56 Channel) 1 $15.95 Sparkfun https://www.sparkfun.com/products/13740
Mini Photocell 2 $1.50 Sparkfun https://www.sparkfun.com/products/9088
Analog to Digital Converter - MCP3002 1 $2.30 Sparkfun https://www.sparkfun.com/products/8636
Raspberry Pi 2 - Model B (8GB Bundle) 1 $49.95 Sparkfun https://www.sparkfun.com/products/13724
Resistor Kit - 1/4W (500 total) 1 $7.95 Sparkfun https://www.sparkfun.com/products/10969
LED - Basic Green 5mm 2 $0.35 Sparkfun https://www.sparkfun.com/products/9592
Tontec® Raspberry Pi Case 1 $7.98 Amazon http://www.amazon.com/Tontec%AE-Raspberry-Black-Enclosure-Transparent/dp/B00NUN98UW?ie=UTF8&psc=1&redirect=true&ref_=od_aui_detailpages00
KMASHI 10000mAh Battery 1 $13.99 Amazon http://www.amazon.com/KMASHI-10000mAh-External-Battery-Portable/dp/B00JM59JPG?ie=UTF8&psc=1&redirect=true&ref_=oh_aui_detailpage_o04_s00
Total $101.82


Gantt Chart
Timeline