Our goal in this step-by-step instructable is to build a device you can clip to your belt and wear throughout the day. This device will log data that, when downloaded to a back-end server system, will provide a report showing the location history of your day along with the breakdown of how much time you spent indoors and outdoors.
A quick rundown of how the system will operate is as follows:
The accelerometer constantly looks to see if the user is in motion. While the user is at rest, the unit takes a GPS and temperature reading every 15 minutes. When motion is detected the GPS unit is turned on. After 2-minutes passes the GPS unit and thermometer again take samples. If motion was detected during that two minute period the 2-minute wait and sample period repeats until the user is at rest again. This is done in order to conserve energy.
All the GPS and temperature data is stored on the SD card. Upon pushing the button on the front of the unit, all data is off-loaded (requires a USB connection to a laptop) and sent to a back end server system for analysis. The backend algorithm (coded in Java) extracts the useful features from the data (such as GPS error, # satellites and temperature) to build a decision tree that classifies the location as indoor or outdoor. The algorithm also utilizes the assistance of online public weather API's as well a GIS web service which tells if lat/long points are within a building or not, to produce a report for the user. The report shows the amount of time (discrete periods of the day) ,and location history along with whether the user was inside or outside.
The arduino code, backend algorithm code as well as the GIS server can be found at https://github.com/pretsb/838fproject
This requires the following equipment:
Arduino WiFi Shield
GPS Unit (LS20031)
2.2K Ohm resister
9V Battery pack
Adafruit Arduino Case
This instructable was made as part of the final project requirement in the
CS graduate course "Tangible Interactive Computing" at the University of
Maryland, College Park taught by Professor Jon Froehlich. The course
focused on exploring the materiality of interactive computing and, in the
words of Hiroshii Ishii, sought to "seamlessly couple the dual worlds of
bits and atoms." Please see http://cmsc838f-f12.wikispaces.com/ for more
A video tour of the project as well as a quick overview can be seen here:
We will use the following shell from Adafruit to encase the project http://www.adafruit.com/products/337 This shell can be used for many other projects and is designed to hold an Arduino and an Ethernet shield within the case. The WiFi shield must be a touch wider than the Ethernet shield as the shell barely screws together tight when you put it together with both devices in there. Once you place wiring into the female pins there is a small amount of pressure being applied to the Arduino itself, but I do not think this pressure will cause any damage to the shell or the Arduino.
The shell has a nice few screw hole designed to hold the Arduino. We'll screw the Uno itself to the shell using the enclosed screws and move on....
The WiFi shield slides nicely onto the Arduino Uno itself. If you are not building this exact project please be sure to read the following page as it outlines what pins are necessary for the WiFi shield and SD card http://arduino.cc/en/Guide/ArduinoWiFiShield
Failing to recognize these pin-outs will cause either the shield or your external peripheral to stop working.
We'll simply slip the shield onto the Uno and slip the SD micro card into the shield itself and continue....
I chose the BMP085 barometer/thermometer to gather the temperature. The barometer proved insufficient for our needs but the thermometer works nicely for our purposes. This device does require the Wire.h library and several functions to simply produce a temperature but this device is reliable. A good example of how to use this device can be found at: http://www.sparkfun.com/tutorial/Barometric/BMP085_Example_Code.pde
I chose to solder wire to the pin-outs, as shown, to allow more flexibility in the placement of the device. Leads would add to the inflexible size of the device as wires allow me to bend them as needed all the way down to the breakout board.
We will explore wiring later in the project, for now we simply just solder the 6 - 3" wires to the breakout board and trim them later as needed.
The GPS will sit on the side of the case along with the wiring for the button and the LED. The unit itself is also quite size-able so I will simply solder wires directly to the GPS unit. This will allow me to place the unit where I see fit and not have the additional constraints that leads might provide.
We will not use the TinyGPS library due to memory constraints and thus only read data off of the GPS unit through its serial connection. A good tutorial on how to use the GPS unit can be found here: http://store.makerbot.com/replicator.html
The colored wires (from left to right) are to be connected as follows:
Orange - 3.3V (the GPS can handle 5V as well if needed).
Green - Signal / Serial TX
Black - Grnd
We chose digital 8 to power the device as it gives us the ability to switch the unit on and off as it draws quite a bit of power. We will use the accelerometer to dictate when we need to gather a GPS signal. Thus simple 'digitalWrite(8, HIGH)' and 'digitalWrite(8, LOW)' commands will allow us to easily switch on and off the unit.
We tape the back of the GPS unit to prevent shorting from taking place in the event a bare wire makes contact with the Unit. This also protects the back of the unit as it will later be packed tight into the shell.
I chose to solder 90-degree leads to the accelerometer instead of directly soldering wires to the device. The layout within the case will be such that the accelerometer will have more free space around it. Leads also allow for easy integration with a breadboard if I decide to use the accelerometer in a future project. Thus I will essentially have a plug-and-play accelerometer with the help of a few wire with female connectors on one end.
Now that the accelerometer is plug-and-play ready we will prepare the wiring to allow such a connection. We will use pre-terminated wires that have female connections on one end and male leads on the other end. The male ends tend to break if bent too much so I'll cut off the male ends and strip the wires, leaving about 2" of free wire on each. We'll trim each as needed later as we connect to the Uno. On the female side, I'll wrap every other end in electrical tape to eliminate any shorts that may occur if the touch one another as I connect them to the leads.
We then plug each end into the leads of the accelerometer in an alternating pattern as show in the picture. We'll conclude the connection by wrapping the connections in electrical tape.
Our connection scheme will be as follows:
VCC - 3.3V ONLY! Don't fry the device :)
GND - common ground. We will place this in the ground pin just below the 5V (we will use the other ground for the barometer/thermometer later)
X - Analog 0
Y - Analog 1
Z - Analog 2
We will actually start connecting devices at this point. As noted earlier, the green wire (from RX pin connection on GPS unit) will go to the TX pin (digital 0) on the Uno. The power cable will go to Digital 8. The ground will stay out for now. We'll later attach the ground lines from other peripherals to this wire as many things need to share a common ground.
One thing to note about the GPS unit with this connection: The RX/TX connection pins replaces the serial communication of the USB serial cable once this unit is powered up and running. Thus, if the GPS unit were cabled up to the 3.3V or 5V connection vs. the digital pin you would not be able to upload code to the Uno as the GPS unit would be using the Serial. One should use a similar wiring approach when testing the GPS unit to allow for code uploading. Otherwise you will need to disconnect either the power or serial wire each time you need to upload code.
We will now connect the accelerometer to the Uno. As we only have one 3.3V connection we pull the power cable across the Uno to reduce the amount of soldering required. Digital 2 will power the accelerometer. The ground will go to the 2nd ground below the 5V pin. The X, Y and Z cables all go to Analog 0, 1, and 2 pins.
We then turn the accelerometer such that we can lay it along the Uno/Shield on the side of the analog pins. If the wires are too long, we can trim them down and re-strip as needed to prevent too much excess wiring within the case.
The only complaint I have with the Arduino case is that it does not offer an easy way to place a battery. We could simply place a battery in the back of the case itself but we would have to secure it to the case somehow. The plastic 9V case we have fits perfectly within the internal pins of the case, allowing us to simply place it into the bottom shell. We run the barrel connector and wiring up along the side with the accelerometer to allow us to plug the batter into the Arduino at a later time.
We now connect the thermometer to the Uno. This unit will utilize the i2C bus on the Arduino Uno (via analog 4 & 5 and the Wire.h library). Our connections will be as follows:
VCC to the 3.3V pin
Ground to the ground just below the 5V
SCA to Analog 4
SCL to Analog 5
We will not use the center two connections for this project.
Note we trim the wires to minimize excess wiring again but we need enough wire to place the thermometer atop and in the center of the shield.
The goal is to allow the thermometer to sit behind the square hole that is in the center of the shield. This hole is here to allow things to come into/go out of the shell. The shell has a door that you can use to close up the hole but we will leave it open to allow the thermometer to gauge the air outside of the shell, otherwise we might shield the thermometer from being able to accurately measure the ambient temperature. We want to ensure when we place the top half of the shell on this unit the thermometer sits within that open space.
With the use of a 2.2K Ohm resister and a simple button, we will add the ability to signal to the device that we are ready to off-load data. The button itself has 4 leads. We first lay out the wiring of this connection on a breadboard to validate the wiring scheme. This enables us to test the button and ensure we will get a good signal. We also do this so that one can clearly see how the wiring will work. The hot and ground are on the top side of this button. The ground also has a 2.2K Ohm resister coming off of it. The signal line is attached to the lead opposite the ground and runs to digital 6 on the Arduino WiFi Shield. The ground runs to the common ground. In an effort to reduce the number of wires we need to solder we will power the button through Digital 3. Thus in this picture the hot is being fed by digital 3.
Step 12: Prepare common ground for the button/GPS/LED
We now start tying together electrical components that will share the common ground on the side of the digital pins. We solder together the wire that has the ground for the GPS unit, the button (going through the 2.2K Ohm resister first) and another wire that will serve as the ground for an LED (described later) and tie all of them into the small green wire that will actually connect to the Arduino Uno. This allows the GPS unit, button and LED to share the only ground pin on that side of the Uno.
We now wire up the LED. We solder the LED to the ground we wired up in the last step, as well as to a wire that leads to digital 5. When the button on the shell is pushed, this LED will provide feedback to the user that that data is being off-loaded from the device. The LED will remain lit during the entire off-loading process and then turn off. Through a series of digital Writes we will enable and disable the LED.
Holding the button up on the front case, I marked 4 spots on the back side of the shell where I needed a hole for the button to sit in and pass wires through. Using a drill and 1/16" drill bit, I drilled four holes through those spots. I then dropped the button into place by placing the leads into the holes and, with a hot glue gun, glued the button to the case.
Using the same types of wires we used to connect the accelerometer we will connect the button to the Arduino. We again cut off the male ends and strip the cables to appropriate lengths. The female ends will connect to the button through the back of the shield as shown in the picture. We will connect three cables (as noted in the wiring example earlier) as necessary for use. The wires I used were too short to allow one to easily leave the shell open. Thus I extended the wires by soldering them to longer wires and wrapping the connections with electrical tape to again prevent any shorts. At this point I can open the shell with the wires for the buttons being too short.
Reiterating the connections we have:
A common ground
A connection coming from digital 5 (reading the signal)
A connection coming from digital 3 (powering the button. This is the power we will switch through the button)
We now close the case. This is probably the hardest part of this process as we have to lay the GPS unit along the side of the device, careful not to pinch any wires or leaving any wires underneath the GPS unit. Doing so will make closing the case hard as the GPS unit is as wide as the case itself; and a wire running under the unit will thicken the needs of the project. We carefully tuck the light just behind the end of the unit so that it does not protrude beyond the end of the case and risk getting bent or broken.
We use the 4 screws that accompanied the shell to close it up. All that is missing is a clip so we can clip the device to our belt....
The case we have is nice in that it holds the project together well and protects everything but it alone is not suited for wearing. We could simply place it in our pocket but the size is a bit large, so... We will print a clip that we can glue to the case to allow the unit to easily clip onto our belt. Using TinkerCad we draw up a clip. We then use ReplicatorG to create a .s3g file that we can easily load onto an SD card, place into a MakerBot 3D printer and print the clip. After printing we will glue the clip onto the back of the case using a hot glue gun.
Our final product is a wearable device we can carry around on our belt all day. The data is stored on the SD card, offloaded at night and where the back-end server system provides a report showing you how much time you spent indoors and outdoors throughout the day.
On the server side, we get a set of samples and each sample contains a unique identifier to identify the person whose data is being synced, GPS reading and temperature readings. The algorithm parses the GPS reading to determine whether its a valid GPS reading (fixQuality>0) or invalid GPS reading. For valid GPS data, we obtain the lat long and reverse geocode it. We also use meta data like # satellites, location Error and the temperature reading as features in a decision tree to classify the location as indoor/outdoor. For invalid GPS readings, we just use the last known lat/long values for reverse geocoding.
The server side code can be found here: https://github.com/pretsb/838fproject/tree/master/MACServer