This is an all in one module which can provide location tracking and GSM services such as data, text and SMS to your project. It comes in the same form factor as a Raspberry Pi Zero, which makes it nice and compact when used with a Raspberry Pi Zero.
The two main components that make this board great are;
uBlox CAM-M8 GPS module (Same GPS found on BerryGPS-IMU)
uBlox SARA-U201 GSM for GSM connectivity, which has global coverage.
Both of these modules working together results in obtaining a GPS fix in secs, using Assisted GPS.
Along with other sponsors, we are happy to congratulate Plastic Monkeys team for placing 3rd (out of over 70 teams taking part) in the CanSats in Europe Polish Competition.
Here are three examples of how to use python to get GPS data from a GPS receiver attached to a Raspberry Pi.
Using GPSD client libraries
Manually parsing NMEA sentences
Using pynmea2 to parse NMEA sentences
GPSD client libraries
The gpsd client libraries are based on JSON. The JSON objects have a "class" attribute (E.g. TPV, SKY, DEVICE.etc...) which can be used to filter on different information.
This guide shows how to get gpsd up an running on a Raspberry Pi.
The example python script below filters on the TPV class, which is the Time Position Velocity report and then prints out the relevant information.
#! /usr/bin/python
from gps import *
import time
gpsd = gps(mode=WATCH_ENABLE|WATCH_NEWSTYLE)
print 'latitude\tlongitude\ttime utc\t\t\taltitude\tepv\tept\tspeed\tclimb' # '\t' = TAB to try and output the data in columns.
try:
while True:
report = gpsd.next() #
if report['class'] == 'TPV':
print getattr(report,'lat',0.0),"\t",
print getattr(report,'lon',0.0),"\t",
print getattr(report,'time',''),"\t",
print getattr(report,'alt','nan'),"\t\t",
print getattr(report,'epv','nan'),"\t",
print getattr(report,'ept','nan'),"\t",
print getattr(report,'speed','nan'),"\t",
print getattr(report,'climb','nan'),"\t"
time.sleep(1)
except (KeyboardInterrupt, SystemExit): #when you press ctrl+c
print "Done.\nExiting."
This python script filters on the SKY class and prints out satellite information.
#! /usr/bin/python
from gps import *
import time
import os
gpsd = gps(mode=WATCH_ENABLE|WATCH_NEWSTYLE)
try:
while True:
report = gpsd.next() #
if report['class'] == 'SKY':
os.system('clear')
print ' Satellites (total of', len(gpsd.satellites) , ' in view)'
for i in gpsd.satellites:
print 't', i
print '\n\n'
print 'PRN = PRN ID of the satellite. 1-63 are GNSS satellites, 64-96 are GLONASS satellites, 100-164 are SBAS satellites'
print 'E = Elevation in degrees'
print 'As = Azimuth, degrees from true north'
print 'ss = Signal stength in dB'
print 'used = Used in current solution?'
time.sleep(1)
except (KeyboardInterrupt, SystemExit): #when you press ctrl+c
print "Done.\nExiting."
Manually parsing NMEA sentences
The python script below shows how to access GPS data by connecting directly to the serial interface. It filters on $GPRMC NMEA sentences and then splits the well know attributes into different variables.
import serial
port = "/dev/serial0"
def parseGPS(data):
# print "raw:", data #prints raw data
if data[0:6] == "$GPRMC":
sdata = data.split(",")
if sdata[2] == 'V':
print "no satellite data available"
return
print "---Parsing GPRMC---",
time = sdata[1][0:2] + ":" + sdata[1][2:4] + ":" + sdata[1][4:6]
lat = decode(sdata[3]) #latitude
dirLat = sdata[4] #latitude direction N/S
lon = decode(sdata[5]) #longitute
dirLon = sdata[6] #longitude direction E/W
speed = sdata[7] #Speed in knots
trCourse = sdata[8] #True course
date = sdata[9][0:2] + "/" + sdata[9][2:4] + "/" + sdata[9][4:6]#date
print "time : %s, latitude : %s(%s), longitude : %s(%s), speed : %s, True Course : %s, Date : %s" % (time,lat,dirLat,lon,dirLon,speed,trCourse,date)
def decode(coord):
#Converts DDDMM.MMMMM > DD deg MM.MMMMM min
x = coord.split(".")
head = x[0]
tail = x[1]
deg = head[0:-2]
min = head[-2:]
return deg + " deg " + min + "." + tail + " min"
print "Receiving GPS data"
ser = serial.Serial(port, baudrate = 9600, timeout = 0.5)
while True:
data = ser.readline()
parseGPS(data)
Using pynmea2 to parse NMEA sentences
The python script below shows how to access GPS data by connecting directly to the serial interface. It filters on $GPGGA NMEA sentences and then uses pynmea2 to parse the data.
Have you ever wondered why it sometimes takes your GPS module 10-20 minutes to get a GPS fix? This post will explain why.
Each satellite sends a message every 30 seconds. This message consists of two main components;
Ephemeris data, used to calculate the position of each satellite in orbit
Almanac , which is information about the time and status of the entire satellite constellation.
Only a small portion of the Almanac is included in a GPS message. It takes 25 messages (12.5 minutes) to get the full Almanac. The full Almanac is needed before a GPS fix can be obtained. This is Time To First Fix (TTFF).
TTFF is a measure of the time required for a GPS receiver to acquire satellite signals and navigation data, and calculate a position solution (called a fix).
The above happens during a cold start, this is when the GPS module has been off for some time and has no data in its memory. A full Almanac download is required to get TTFF. If the GPS module has clear line of sight to all satellites, the shortest time for TTFF is 12.5 minutes.
In a warmstart scenario, the GPS module has valid Almanac data, is close to its last position (100km or so) and knows the time within about 20 seconds. This approximate information helps the receiver estimate the range to satellites. The TTFF for a warm start can be as short as 30 seconds, but is usually just a couple of minutes.
A receiver that has a current almanac, ephemeris data, time and position can have a hot start. A hot start can take from 0.5 to 20 seconds for TTFF.
Smarts phones use Assisted GPS (aGPS), this allows them to download the Ephemeris data and Almanac over the cell network which greatly reduces the TTFF.
In this post we will show you how to geotag and capture the "attitude" of photos taken with the Raspberry Pi camera and record these values within the photo itself using EXIF metadata
We used a modified (hacked?) cap to take the images in this post. The cap took photos, geo-tagged and recorded attitude as we walked around Sydney Harbour.
The BerryGPS-IMU was used to capture the GPS coordinates as well as "attitude". No external antenna was needed as the BerryGPS-IMU includes an internal antenna.
The "attitude" would include values such as pitch, roll, direction. Some of this data you can see annotate in the image below.
Other programs can use some of this data to plot the image on a map and even show the direction of the camera at the time the image was taken. A good example of this is seen in GeoSetter
The Cap
The cap has the BerryGPS-IMU sitting on top of the visor, with the Raspberry Pi sitting under the viso. Some holes where made in the visor to allow connectivity between the BerryGPS-IMU and Raspberry Pi. We also created a basic camera mount out of 3mm laser cut acrylic. M2.5 Nylon screws were used to hold everything in place.
Navit is an open source navigation system with GPS tracking. It works great with a Raspberry Pi, a GPS module and a small TFT with touch, jut like the official Raspberry Pi Display or PiScreen.
Navit can be installed without a GPS connected to your Raspberry Pi, but you will not be able to use the real-time turn by turn navigation. You will however be able to browse maps. If you are not going to use a GPS, you can skip to the next step.
As we are using the BerryGPS-IMU, we will be following the guide in the link below. As most GPS modules use serial to communication, this guide can be followed for other GPS modules.
The images below shows how we have connected the BerryGPS-IMU to the Raspberry Pi 3 whilst it is in the SmartPi Touch case.
If you plan on testing this out in your car, you need to be mindfully of where you place your BerryGPS. In my setup and I have placed it in the air vent as shown below, and BerryGPS gets a good strong signal.
If you are using an external antenna, then there is no need to worry about where your BerryGPS is placed.
BerryIMU also works great with Windows IoT Core on the Raspberry Pi.
Our Git repository contains the source files needed to get the BerryIMU up and running on Windows IoT.
The code will print out the following values to the screen;
Raw values from the gyroscope, accelerometer and magnetometer.
Accelerometer calculated angles.
Gyro tracked angles.
Fused X and Y angles.
Heading.
Tilt compensated heading.
Connecting BerryIMU to a Raspberry Pi
BrryIMU can connect via the jumper cables to the Raspberry Pi as shown below;
Or BerryIMU can sit right on top of the GPIO pins on a Raspberry Pi. The first 6 GPIOs are used as shown below.
Get the Code
Download the BerryIMU code for Windows IoT from our GIT repository. The files you need are under the WindowsIoT-BerryIMU folder.
You will need to download the entire git repository as GIT doesn't allow downloading individual folders.
Once downloaded, double-click the file WindowsIoT-BerryIMU.sln to open up the project in Visual Studio.
About the code
The project code outputs all of the needed values to the screen and a complementary filter is used to fuse the accelerometer and gyroscope angles.
We have a number of guides already documented on how to get the BerryIMU working with the Raspberry Pi. https://ozzmaker.com/berryimu/ These are based on Raspbian, however the principals and math are the same for Windows Iot.
The final values which should be used are the fused X &Y angles and the tilt compensated heading.
The sensor on the BerryIMU is the LSM9DS0 and all the I2C registers for this sensor can be found in LSM9DS0.cs
The main code can be found in MainPage.xaml.cs
Complementary Filter
A complementary filter is used to fuse the angles. Is summary, the complementary filter trusts the gyroscope for short periods and trusts the accelerometer for longer periods;
Changing how much trust is given for each of the sensors can be changed by modify the complementary filter constant at the start of the code.
const float AA = 0.03f; // Complementary filter constant
Loop Speed
The loop speed is important as we need to know how much time has past to calculate the rotational degrees per second on the gyroscope. A time delta is set at the start of the code.
const int DT = 100; //DT is the loop delta in milliseconds.
This is then used to specify a new timer method.
periodicTimer = new Timer(this.TimerCallback, null, 0,DT);
Here you can see where DT is used to keep track of the gyroscope angle. You can also see it in the above calculation for the complementary filter.
//Calculate the angles from the gyro
gyroXangle += rate_gyr_x * DT / 1000;
gyroYangle += rate_gyr_y * DT / 1000;
gyroZangle += rate_gyr_z * DT / 1000;
BerryIMU orientation
The calculations in the code are based on how the BerryIMU is orientated. If BerryIMU is upside down, then some of the angles need to be reversed. It is upside down when the skull logo is facing up(or to the sky). If it is upside down, set the below value to true. Otherwise, set it to false.
Our BerryIMU GIT repository has been updated with code for the Teensy, specifically Teensy 3.6. Now you can have access to an accelerometer, gyroscope, compass, temperature and pressure sensor on your Teensy.
Here you can see the angles displayed using the Serial Plotter in the Arduino IDE which is connected to a Teensy 3.6.
The latest version of Arduino IDE includes a Serial Plotter. This is great to show angles in a sliding graph.
The below image shows how to access the Serial Plotter.
The Serial Monitor will have to be closed as both cannot be opened at the same time.
The Serial Plotter expects the values to be separated with a space. To show the X and Y angles on the plotter, comment out the print statements in the existing code and insert the code below.
4 web pages are created: "/" - home page which is used to display the gauges. "/chart.html" - Is used to display chart. "/table.html" - Is used to display the data in a table. "/data.json"- Is used by the home page to update the the gauge values.
Hook Up
The below diagram shows how to connect a BerryIMU to an ESP8266 microcontroller, in this case it is the Adafruit Feather Huzzah .