If your in the UK, I noticed that they had them on amazon and pimoroni.
I used the raspberry pi's on board UART to connect to the GPS module, Adafruit advocate using a USB to serial device but that didn't suit my needs (I need the USB for other things).
I also create a GPSController class in python to allow me to communicate with the module easily.
Connecting the GPS module
Wiring it up is pretty simple:
- Raspberry Pi - 5v -> GPS Module - VIN
- Raspberry Pi - GND -> GPS Module - GND
- Raspberry Pi - Tx -> GPS Module - Rx
- Raspberry Pi - Rx -> GPS Module - Tx
Enable the UART
By default the UART is enabled to allow you to connect a terminal window and login, I needed to disable this to free it up for the GPS Module.
sudo nano /boot/cmdline.txt
The contents looks like this (yours might be slightly different depending on your distribution):
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
remove the following config from the file and save it.
console=ttyAMA0,115200
kgdboc=ttyAMA0,115200
Change inittab so it doesnt spawn a login to the serial connection:
sudo nano /etc/inittab
Change:
#Spawn a getty on Raspberry Pi serial line
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
to:
#Spawn a getty on Raspberry Pi serial line
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
Reboot
sudo shutdown -r now
Install GPSD
GPSD is an open source project which provides a daemon which streams GPS data via a TCP socket, allowing you to communicate with a whole host of different GPS devices (not just this one):
sudo apt-get install gpsd gpsd-clients python-gps
Run gpsd
GPSD needs to be started up, using the following command:
sudo gpsd /dev/ttyAMA0 -F /var/run/gpsd.sock
Test gpsd
There is a simple GPS client which you can run to test everything is working:
cgps -s
It may take a few seconds for data to come through, but you should see a screen like this:
Python code
In order to control and capture the GPS data in python I started looking round for some code, this took me to http://www.danmandle.com/blog/getting-gpsd-to-work-with-python which I used as a starting point for creating this python GPSController class. It uses threading to continuously read the stream of data from GPSD and present it as properties of the class.
There is a more in depth example of how to use the class in the code below, but in simple terms you use it like this:
#create controller
gpsc = GpsController()
#start controller
gpsc.start()
#read latitude and longitude
print gpsc.fix.latitude
print gpsc.fix.longitude
#stop controller
gpsc.stopController()
gpsc = GpsController()
#start controller
gpsc.start()
#read latitude and longitude
print gpsc.fix.latitude
print gpsc.fix.longitude
#stop controller
gpsc.stopController()
Note - you may have to wait a few seconds for the data to start streaming
GPSController.py
from gps import *
import time
import threading
import math
class GpsController(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info
self.running = False
def run(self):
self.running = True
while self.running:
# grab EACH set of gpsd info to clear the buffer
self.gpsd.next()
def stopController(self):
self.running = False
@property
def fix(self):
return self.gpsd.fix
@property
def utc(self):
return self.gpsd.utc
@property
def satellites(self):
return self.gpsd.satellites
if __name__ == '__main__':
# create the controller
gpsc = GpsController()
try:
# start controller
gpsc.start()
while True:
print "latitude ", gpsc.fix.latitude
print "longitude ", gpsc.fix.longitude
print "time utc ", gpsc.utc, " + ", gpsc.fix.time
print "altitude (m)", gpsc.fix.altitude
print "eps ", gpsc.fix.eps
print "epx ", gpsc.fix.epx
print "epv ", gpsc.fix.epv
print "ept ", gpsc.gpsd.fix.ept
print "speed (m/s) ", gpsc.fix.speed
print "climb ", gpsc.fix.climb
print "track ", gpsc.fix.track
print "mode ", gpsc.fix.mode
print "sats ", gpsc.satellites
time.sleep(0.5)
#Error
except:
print "Unexpected error:", sys.exc_info()[0]
raise
#Ctrl C
except KeyboardInterrupt:
print "User cancelled"
finally:
print "Stopping gps controller"
gpsc.stopController()
#wait for the tread to finish
gpsc.join()
print "Done"
import time
import threading
import math
class GpsController(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info
self.running = False
def run(self):
self.running = True
while self.running:
# grab EACH set of gpsd info to clear the buffer
self.gpsd.next()
def stopController(self):
self.running = False
@property
def fix(self):
return self.gpsd.fix
@property
def utc(self):
return self.gpsd.utc
@property
def satellites(self):
return self.gpsd.satellites
if __name__ == '__main__':
# create the controller
gpsc = GpsController()
try:
# start controller
gpsc.start()
while True:
print "latitude ", gpsc.fix.latitude
print "longitude ", gpsc.fix.longitude
print "time utc ", gpsc.utc, " + ", gpsc.fix.time
print "altitude (m)", gpsc.fix.altitude
print "eps ", gpsc.fix.eps
print "epx ", gpsc.fix.epx
print "epv ", gpsc.fix.epv
print "ept ", gpsc.gpsd.fix.ept
print "speed (m/s) ", gpsc.fix.speed
print "climb ", gpsc.fix.climb
print "track ", gpsc.fix.track
print "mode ", gpsc.fix.mode
print "sats ", gpsc.satellites
time.sleep(0.5)
#Error
except:
print "Unexpected error:", sys.exc_info()[0]
raise
#Ctrl C
except KeyboardInterrupt:
print "User cancelled"
finally:
print "Stopping gps controller"
gpsc.stopController()
#wait for the tread to finish
gpsc.join()
print "Done"
how can you give 5v to raspberry pi.....???
ReplyDeleteIm not sure I understand your question. But, if your talking about how do I wire the GPS unit up. I take the 5v line from the raspberry pi gpio and connect it to the VIN on the gps module.
DeleteI dont give the raspberry pi 5v!
What is the correct way to test if:
ReplyDelete1) the GPS unit is present, ie: is there an error code genberated when gpsc.start() is run and even though gpsd is running, there is no GPS unit attached?
2) test to see if the data read is good? At the moment, I just loop until lat/log are both no longer 0.0.
thanks.
I dont know a better way to be honest, ive not looked into it, if you find out let me know though
DeleteWhich gps module are you use?
ReplyDeleteadafruit gps ultimate breakout board (see link at the top of the page)
Deletehi martin.where should i go to create the python GPSController class
ReplyDeleteIs there a kit that would allow the GPS to automatically download via wifi when the vehicle returns home? Thx
ReplyDeleteI dont know of a 'kit' but it doesnt sound like a particularly difficult problem to code. A script which runs every x minutes, if it can find a connection, it copies the file of gps data to a share.
Deletewhen i reboot my raspberry doesnt turn on again ... looks like a broke boot particion, i had to reinstall 3 times ._. some idea why ?
ReplyDeleteKnackered SD Card? Have you tried using a different one?
DeleteI get the same problem I'm afraid. After reboot I get a kernel issue and have to reload. Tried another SD and the same thing happens. I don't think all packages were 100% up to date, so im going to give it another shot.
DeleteDid you have any luck? I have never experienced this problem before?
DeleteAny one else had luck with this. Im getting the same problem
DeleteRight I have managed to re-produce the error. Its because the raspbian / noobs setup has changed. Where I originally said:
DeleteChange:
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
to:
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
You need to just remove the:
console=ttyAMA0,115200 kgdboc=ttyAMA0,115200
parts.
If you cut and paste my code directly it would have resulted in raspbian being unable to find the root and the kernal error. Ive updated the post.
Hello,
DeleteI had a problem with this part of the code:
#Spawn a getty on Raspberry Pi serial line
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
to:
#Spawn a getty on Raspberry Pi serial line
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
When I would try to reboot..nothing would happen! It's like I had to re-install everything on the sd-card. I rebooted my pc with a debian live cd and change the above code back. My PI booted back like normal.
In order not to run into this problem again:
on console I entered :
sudo raspi-config In the software configuration tool select option 8 then select option A7 Serial and select NO.
Select OK and close app.
In console enter:
sudo gpsd /dev/ttyAMA0 -F /var/run/gpsd.sock
cgps -s
wait for gps data
That was my work around for serial (none USB method)
The last two steps have to be re-entered everytime you reboot. Just for testing reasons I did not automatically had it run on boot time.
I can't run GPScontroll.py
ReplyDeleteWhy occured this error?
pi@raspberrypi ~ $ python GPSController.py
File "GPSController.py", line 53
time.sleep(0.5)
SyntaxError: default 'except:' must be last
It sounds like a code indentation problem. Did you cut and paste the code from the page? Did it cut and paste properly?
DeleteI got the same error, but managed to fix it. The lines
Deleteexcept:
print "Unexpected error:", sys.exc_info()[0]
raise
must be moved so they come _after_
except KeyboardInterrupt:
print "User cancelled"
Thanks for the excellent write-up Martin!
Cheers, Lars
Hi,
ReplyDeletedo you know how to send the data you get from GPSController.py to a html page on webiopi?
Cheers.
I have never looked at webiopi. I doubt it would be too difficult though.
DeleteI am trying to run this on a RPi in idle3 with the adafruit ultimate gps but I keep getting a syntax error on the quotation Mark after latitude. Help!
ReplyDeleteAh Python 3. I wrote this in Python 2. Its probably because Python 3 expects While(True): and print("hello") - note the brackets. I cant guarantee there wont be other python 2 - 3 issues.
DeleteThis is really useful, great!
ReplyDeletebut by the way, how to send the output data (longitude and latitude) from py code to website (html)? Is it need other library or package? or if I start the gpsd I can be able to call the longitude and latitude in html without python code like this example http://www.w3schools.com/html/html5_geolocation.asp? thank you
Did you use GPS library module in Python 3? How did you do that?
ReplyDeleteDo you mean the GPS modue I wrote (i.e. the one in the blog post)? If so the code I wrote is python 2 but I dont think it would be that difficult to migrate it to Python 3.
DeleteThis comment has been removed by the author.
ReplyDeleteHi,
ReplyDeleteThank you very much for posting this tutorial
I want to ask a question
if I want to use the USB instead of uart pins
Do I have to configure something in order to use the python class that you have created
thank you again and I hope my question is not that stupid :)
The python code remains the same, but when you startup gpsd, you need to give it a different device:
Deletesudo gpsd /dev/ttyAMA0 -F /var/run/gpsd.sock
change the ttyAMA0 to the usb serial device, sorry I dont know what it is. Im sure google will help though.
I get a really bad freeze (I can only kill it with -9) at the .join() line. has anyone else seen this issue?
ReplyDeleteThe command gpsc.join() is waiting for the GPS controller to finish. I dont know why it wouldnt stop though. Other than that does it work?
DeleteIt seems to. I have not tested it with a gps receiver, but my program gets nan from it with no problem. I will have to work to test it more thoroughly. I am just not sure why the thread would hang when it works fine if I don't put it in a thread. (but that won't work for my main application.)
ReplyDeleteI dont know, but it could be that its not erroring correctly as its expecting a GPS receiver to be returning data.
Deletehow to store gps data in database
ReplyDeleteSim908 interfacing with raspberry pi...coding and interfacing
ReplyDeleteSim908 interfacing with raspberry pi...coding and interfacing
ReplyDeleteSim908 interfacing with raspberry pi...coding and interfacing
ReplyDeleteSim908 interfacing with raspberry pi...coding and interfacing
ReplyDelete