Key goals summary:
- Have a project that will tell my my location by different colours via GPS coordinates
- Make it look like Tony Stark’s Arc Reactor
I’ve always loved the Iron Man films and have been especially inspired by the Arc Reactor, what I wouldn’t give to have one of those myself I pondered…
I wanted something that looked cool, but didn’t just look cool; it needed to do something cool too.
So why not make it out of a Raspberry Pi?
I thought why not have it be able to use GPS to tell me where I am? A different colour for each location perhaps? It seemed so impossible to me at the time I had to attempt it.
So in February 2015 I began work on the Arc Raspberry project:
It was constructed with the following components:
- Old 80mm PC fan (under a shirt the illuminated fan resembles the film reactor, mostly.)
- Adafruit PowerBoost 500
- LiPoly Battery (one used here I can’t find any more)
- Raspberry Pi A+
- Adafruit GPS USB
- Raspberry Pi A+ Zebra Case
- Various other small components and cables, heatsinks, SD Card etc…
Thanks to NOOBS its easy enough to set up Raspbian as the operating system for the Pi, giving me a good base to set up the hardware. In terms of the GPS module set up, Adafruit is the place to go. Last but not least with a guide for using the PiGlow module I was well on the way to getting this working.
It took hours of work using Python. I mean hours. Thanks to countless tutorials and some nifty algorithms I found online, I was able to convert the Latitude and Longitude data from the GPS module into a Grid Reference which I could then compare against stored strings related to a certain location, such as a town or city.
After many hours of testing and debugging, involving way to much time wandering around in the cold with the device around my neck – peeking down my shirt frequently to see if it was changing colour; there was finally success. The device was blue in a location it had stored and white in unknown grid references, red in the adjacent town where my friend lives.
Here’s the annotated code, it runs under rc.local on boot:
#!/usr/bin/python #import modules import re, sys, string, os, gps from time import sleep from PyGlow import PyGlow #setup pyglow pyglow = PyGlow() #store alphabet for grid reference calculations upper = 'ABCDEFGHIJKLMNOPQRSTUVWX' #lists of grid squares for locations Bury = ["JO02IG", "JO02IF", "JO02JG", "JO02JF"] Thetford = ["JO02IK", "JO02JK", "JO02IJ", "JO02JJ"] Cambridge = ["JO02AF", "JO02AE", "JO02BE", "JO02BF", "JO02CE", "JO02CF"] #initialise gps session = gps.gps("localhost", "2947") session.stream(gps.WATCH_ENABLE | gps.WATCH_NEWSTYLE) #main loop try: while True: #gather statistics from tpv (latitude + longitude) then write both to respective variables report = session.next() if report['class'] == 'TPV': if hasattr(report, 'lat'): dec_lat=`report.lat` if report['class'] == 'TPV': if hasattr(report, 'lon'): dec_lon=`report.lon` #/below code source: http://ham.stackexchange.com/questions/221/how-can-one-convert-from-lat-long-to-grid-square adj_lat = float(dec_lat) + 90.0 adj_lon = float(dec_lon) + 180.0 mhloc="" grid_lat_sq = upper[int(adj_lat/10)]; grid_lon_sq = upper[int(adj_lon/20)]; grid_lat_field = str(int(adj_lat%10)) grid_lon_field = str(int((adj_lon/2)%10)) adj_lat_remainder = (adj_lat - int(adj_lat)) * 60 adj_lon_remainder = ((adj_lon) - int(adj_lon/2)*2) * 60 grid_lat_subsq = upper[int(adj_lat_remainder/2.5)] grid_lon_subsq = upper[int(adj_lon_remainder/5)] mhloc = grid_lon_sq + grid_lat_sq + grid_lon_field + grid_lat_field + grid_lon_subsq + grid_lat_subsq #/end #print grid square for logging/testing print mhloc #compare grid square against stored lists and set colours if mhloc in Bury: pyglow.color("white", 0) pyglow.color("blue", 255) pyglow.color("green", 0) pyglow.color("yellow", 0) pyglow.color("orange", 0) pyglow.color("red", 0) elif mhloc in Thetford: pyglow.color("white", 0) pyglow.color("blue", 0) pyglow.color("green", 0) pyglow.color("yellow", 0) pyglow.color("orange", 0) pyglow.color("red", 255) elif mhloc in Cambridge: pyglow.color("white", 0) pyglow.color("blue", 0) pyglow.color("green", 255) pyglow.color("yellow", 0) pyglow.color("orange", 0) pyglow.color("red", 0) else: pyglow.color("white", 255) pyglow.color("blue", 0) pyglow.color("green", 0) pyglow.color("yellow", 0) pyglow.color("orange", 0) pyglow.color("red", 0) #sleep(1) #error handling and sh script for restarting gps code in event of fatal exception except KeyError: pass except KeyboardInterrupt: session = None pyglow.all(0) quit() except StopIteration: session = None pyglow.all(0) os.system('bash ./home/pi/pyglow/restartgps.sh') quit() except: session = None pyglow.all(0) os.system('bash ./home/pi/pyglow/restartgps.sh') quit()
The script that runs in rc.local:
sudo sleep 15 sudo killall gpsd sudo sleep 15 sudo gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock sudo sleep 15 sudo python /home/pi/pyglow/arcraspberrymkI.py &
The & symbol after the script makes it run silently, so you can still log on and use Raspbian while its running (mainly for when I had it plugged into my monitor for debugging).
Here’s the restartgps.sh script for restarting the gps protocol if something goes wrong:
#!/bin/sh sudo sleep 15 sudo killall gpsd sudo sleep 15 sudo gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock sudo sleep 15 sudo python /home/pi/pyglow/arcraspberrymkI.py &
The final device:
Worn around my neck:
The next phase.
High on my own success I realised I could do more, building up from what I’d done and adding more to it; wouldn’t it just be awesome if it could respond to voice commands and speak back my location?
Oh, Hi, Jasper.