Bereits vor einiger Zeit hatte ich mit GPS Modulen für den Raspberry Pi experimentiert, heute wollte ich die verschiedenen Projekte mal zusammenbringen und einen echten Raspberry Pi GPS-Tracker mit Akku Betrieb bauen. Als kleines Addon soll alle paar Minuten ein Bild erzeugt werden welches mit den jeweils aktuellen GPS Daten versehen wird. Dieses Raspberry Pi GPS Projekt kann entweder im Auto als GPS-Tracker mit Bild Funktion oder auch auf Wanderungen oder Fahrradtouren zur Dokumentation der Tour mit einem Akku verwendet werden.
Material
Folgendes Material habe ich verwendet
- Raspberry Pi Modell 2B
- Das NEO6M GPS Modul gy-neo6mv2
- MicoSD Karte mit 32GB Class 10
- Ein 5V Smartphone Akkupack mit ausreichend Kapazität
- Ein Flachbandkabel 40 Polig und/oder Kabel zum Verbinden
- Einige Kabel zum Verbinden
- Kleines ABS Gehäuse für den GPS Sensor ~50×50
- Kabelbinder
- Doppelseitiges Klebeband
- Für den Einsatz im Auto USB Adapter für den Zigarettenanzünder + MicroUSB Kabel
Verkabelung des GPS Modul
Die Pin Nummern und Bezeichnungen der GPIO-Leiste des Raspberry Pi 2 findet ihr in der GPIO PIN Übersicht.
Verkabelung des Moduls
|
PPS verkabeln
Das PPS-Signal müsst ihr am PIN3 des GPS-Chip oder am markierten Widerstand durch anlöten eines kleinen Kabels abholen |
Meine Verkabelung / Aufbau
Einrichtung GPS Tracker auf dem Raspberry Pi
Uhrzeit via GPS beziehen
Da wir beim mobilen Einsatz unsers RasPi keine Internetverbindung zum beziehen der aktuellen Uhrzeit haben und ich in diesem Fall auch keine RTC-Modul für den Bezug der Zeit via Funk habe setzen wir die Uhrzeit via GPS. Dafür ist es notwendig das PPS Signal eures Moduls an den GPIO Pin Nr. 12 (GPIO18) weiterzureichen.
Sobald das PPS Signal anliegt können wir den PPS Treiber, welcher das Signal verarbeiten kann, aktivieren. Das erledigen wir via Device Tree Overlay in der Datei config.txt mit dem Editor Nano.
1 |
sudo nano /boot/config.txt |
Fügt ans Ende folgende Zeile an und speichert mit STRG+X, Y und Enter.
1 |
dtoverlay=pps-gpio,gpiopin=18 |
Zum Testen des PPS Signals (euer PI braucht dafür eine Sichtverbindung zu mindestens zwei GPS Satelliten) installieren wir noch die PPS Tools.
1 2 |
sudo apt-get -y install pps-tools sudo reboot |
Nach einem Reboot solltet ihr nach folgendem Befehl eine Ausgabe erhalten
1 |
sudo ppstest /dev/pps0 |
Das ist das PPS Signal welches der Pi vom GPS Modul bekommt.
1 2 3 4 5 6 7 |
trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1437308973.404467560, sequence: 454 - clear 0.000000000, sequence: 0 source 0 - assert 1437308974.404486750, sequence: 455 - clear 0.000000000, sequence: 0 source 0 - assert 1437308975.404505732, sequence: 456 - clear 0.000000000, sequence: 0 |
Beendet die Ausgabe mit STRG+C.
Da wir nun die Zeit vom GPS via PPS Signal am Raspberry Pi haben müssen wir noch eine Angepasste Version des Zeitdienstes NTP installieren. Falls ihr eure Zeitzone noch nicht eingestellt habt erledigt das über folgenden Befehl (vermutlich befindet ihr euch wie ich in UTC +1 Europe/Berlin).
1 |
sudo dpkg-reconfigure tzdata |
Um an die Sourcen des NTP Dienstes zu kommen fügen wir das passende Repository zu unserer sources.list hinzu und aktualisieren die Paket Liste. Das ist notwendig da das normale NTP Paket keine PPS Zeitquellen unterstützt.
1 2 |
sudo sh -c 'echo "deb-src http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi" >> /etc/apt/sources.list' sudo apt-get update |
Dann holen wir uns die Build Dependencies und den Quellcode des NTP Dienstes
1 2 3 |
cd ~ sudo apt-get -y build-dep ntp ntpdate sudo apt-get -y source ntp |
Der Source Code wurde in das Home des Benutzers pi abgelegt, bei mir ist das momentan ntp-4.2.6.p5+dfsg. Ich wechsle in das erstellte Quellcode Verzeichnis nach debian.
1 |
cd ntp-4.2.6.p5+dfsg/debian/ |
Hier finden wir eine Datei rules welche wir bearbeiten um die fehlende Funktion für PPS zu aktivieren
1 |
sudo nano rules |
Wir müssen in der Datei den configure Aufruf mit –enable-ATOM ergänzen, sucht am Besten mit STRG+W nach configure und fügt am Ende des Aufrufs –enable-ATOM hinzu, die Zeile davor müsst ihr noch mit einem “ \“ergänzen. Bei mir sieht das Ergebnis wie folgt aus. Speichern mit STRG+X, Y und Enter.
1 2 3 4 5 6 7 8 9 10 11 12 |
./configure CFLAGS='$(CFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' \ --prefix=/usr \ --enable-all-clocks --enable-parse-clocks --enable-SHM \ --disable-debugging --sysconfdir=/var/lib/ntp \ --with-sntp=no \ --with-lineeditlibs=edit \ --without-ntpsnmpd \ --disable-local-libopts \ --enable-ntp-signd \ --disable-dependency-tracking \ --with-openssl-libdir=/usr/lib/$(DEB_HOST_MULTIARCH) \ --enable-ATOM |
Um kompilieren zu können müssen wir in der Datei changelog noch die Version von NTP um eine Nummer erhöhen. Wir verwenden wieder nano
1 2 |
sudo nano changelog |
und ändern in der Ersten Zeile 4.2.6.p5+dfsg-2
zu 4.2.6.p5+dfsg-3
und speichern mit STRG+X, Y und Enter.
Jetzt kompilieren wir den NTP Dienst mit, das dauert eine Weile (ca. 30 Minuten), nach Abschluss des Vorgangs müssen wir nur noch das neu erstellte NTP-Paket installieren
1 2 3 4 5 |
cd .. sudo dpkg-buildpackage -b cd /home/pi sudo dpkg -i ntp_4.2.6.p5+dfsg-3+deb7u4_armhf.deb |
Nun haben wir auf unserem System den NTP Dienst mit aktivierter ATOM Funktion um via PPS gelieferte Daten verarbeiten zu können.
Die Konfiguration von NTP folgt als nächstes, diese wird in einer zentralen Konfigurationsdatei vorgenommen. Ihr findet die Datei in /etc/ntp.conf, ich verwende zum Bearbeiten der Datei wieder den Editor Nano.
1 |
sudo nano /etc/ntp.conf |
Wir möchten nun dem NTP Dienst sagen das zwei zusätzliche Zeitquellen vorhanden sind, zum einen die via PPS angebundene und zum anderen die Ausgabe des GPSD. Hierzu fügen wir der Konfiguration folgende Zeilen hinzu.
1 2 3 4 5 6 7 8 9 |
# pps-gpio /dev/pps0 server 127.127.22.0 minpoll 3 maxpoll 3 prefer fudge 127.127.22.0 refid PPS fudge 127.127.22.0 flag3 1 # enable kernel PLL/FLL clock # gpsd clock server 127.127.28.0 minpoll 3 maxpoll 3 prefer fudge 127.127.28.0 refid GPS fudge 127.127.28.0 time1 +0.130 |
Die anderen eingetragen NTP Server habe ich durch voranstellen einer Raute (#) entfernt da ich im offline Betrieb GPS als Zeitquelle verwenden will und für den online betrieb die UK Pool Server
1 2 3 4 5 6 7 |
#server 0.debian.pool.ntp.org iburst #server 1.debian.pool.ntp.org iburst #server 2.debian.pool.ntp.org iburst #server 3.debian.pool.ntp.org iburst pool uk.pool.ntp.org minpoll 5 maxpoll 5 iburst |
Speichert wieder mit STRG+X, Y und Enter.
Zum testen ob alles geklappt hat müsst ihr einmal den Dienst, folgender Befehl gibt uns dann die konfigurierten Zeitquellen aus.
1 2 |
sudo service ntp restart ntpq -p |
Falls euer Raspberry Pi eine IP-Adresse via DHCP erhält und euer DHCP Server zusätzlich auch ein NTP-Server ist (wie meine FritzBox) müsst ihr die automatische Konfiguration via DHCP abschalten.
1 |
sudo nano /etc/dhcp/dhclient.conf |
Innerhalb der Datei entfernt ihr hinter request folgenden Inhalt: ntp-servers
Zusätzlich lösche ich noch die folgenden Dateien um zu verhindern das noch eine alte Konfiguration angezogen wird und starte meinen Pi neu.
1 2 3 |
sudo rm -rf /etc/dhcp/dhclient-exit-hooks.d/ntp sudo rm -f /var/lib/ntp/ntp.conf.dhcp sudo reboot |
GPS Einrichten
Wichtig ist das wir als erstes die Serial Funktion aktivieren, öffnet hierzu raspi-config
1 |
sudo raspi-config |
Navigiert in die „Advanced Options“ auf „Serial“ und beantwortet die Frage „Would you like a login shell to be accessible over serial? “ mit No. Nun können wir den GPS Dienst, welcher für uns die Kommunikation mit dem Modul übernimmt, installieren
1 2 |
sudo apt-get -y install gpsd gpsd-clients python-gps gpsbabel sudo reboot |
Wir konfigurieren den Dienst nun direkt, hierzu rufen wir den Konfigurationsdialog auf
1 |
sudo dpkg-reconfigure gpsd |
- Die erste Frage nach dem Automatischen Start bestätigen wir mit NO
- Die zweite Frage ob USB-Geräte verwenden werden soll beantworten wir wieder mit NO
- Die Frage nach dem GPS Device beantworten wir durch Eingabe des Geräts /dev/ttyAMA0
- Die Rückfrage nach den Parametern tragen wir folgendes ein -n
- Den gpsd control socket belassen wir so wie er vorgeschlagen wird
Zum aufzeichnen der Daten verwende ich ein Python Script welches via gpspipe die GPS Daten jede Sekunde speichert. Das ist notwendig um den GPS-Dienst und das Tracking nach start des Raspberry Pi jeweils verzögert zu starten, das vermeidet Probleme.
1 |
sudo nano /home/pi/gps-tracker.py |
Die Datei bekommt folgenden Inhalt (das Script ist einfach gestaltet und hat noch keine Fehlerbehandlung).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#!/usr/bin/env python import subprocess import time from datetime import datetime as dt # Terminate existing gpsd instances, start gpsd and sleep a few seconds subprocess.call('sudo killall gpsd', shell=True) subprocess.call('sudo /usr/sbin/gpsd /dev/ttyAMA0 -F /var/run/gpsd.sock', shell=True) time.sleep(30) # Refresh the local time subprocess.call('sudo service ntp restart', shell=True) time.sleep(3) #output file name with actual date filename = "/home/pi/gpstrack-" + dt.now().strftime("%Y%m%d-%H%M%S") + ".txt" # start gpspipe and output the GPS Data as NMEA to file subprocess.call('gpspipe -d -l -r -o '+ filename +' ', shell=True) |
Nach dem Speichern wird diese ausführbar gemacht.
1 |
sudo chmod +x /home/pi/gps-tracker.py |
Dann fügen wir einen Autostart für das Script hinzu.
1 |
sudo nano /etc/rc.local |
Am Ender der Datei, vor exit 0 tragen wir folgenden Befehl ein
1 |
/bin/sleep 15 && /home/pi/gps-tracker.py & |
Nach einem Reboot wird nun mit etwas Verzögerung unter /home/pi/ eine Datei mit dem Namen gpstrack-<zeitstempel>.txt geschrieben.
GPS Daten in Google Maps anzeigen
Wir haben nun fleißig Daten gesammelt, diese liegen uns im im Roh-Format als NMEA Daten vor. Um diese zb. in Google Maps importieren und anzuzeigen müssen wir diese in das KML Format umwandeln. Das erledigt das Tool gpsbabel für uns.
1 |
gpsbabel -i nmea -f /home/pi/ |
Die Datei könnt ihr dann z.B. via WinSCP von eurem Raspberry Pi holen, geht eure IP-Adresse und die Logindaten ein und klickt auf Login
Kopiert die Datei durch Drag and Drop auf euren Rechner. Die KML Dateien könnt ihr dann zum Beispiel mit Google Earth oder in My Google Maps importieren, bearbeiten und abspeichern.
Für den KML Import für Google Maps
- Öffnet hierzu https://www.google.com/mymaps
- Ihr müsst euch ggf Anmelden, sagt dann „Neue Karte erstellen„
- Ihr erhaltet eine Leere Karte mit einer leeren Ebene, bennent die Ebene nach euren Wünschen um
- Klickt dann für die Ebene auf Import und wählt die KML File von eurem Rechner
- Die Karte könnt ihr dann mit euren Freunden und bekannten teilen
Für den KML Import für Google Earth
- Die Datei kann einfach via Drag&Drop hinzugefügt werden
Bilder
Die Bilder via Raspberry Pi CAM erstellen wir wie üblich via „raspistill“, vorab müsst ihr eure Kamera allerdings via „sudo raspi-config“ mit „5 Enable Camera“ aktivieren. Zusätzlich installiere ich die Software Imagemagick welche es mir erlaubt in das aufgenommene Bild die aktuellen GPS Daten als Text zu integrieren.
1 |
sudo apt-get install imagemagick |
Zusätzlich installieren wir das Tool „exiftool“, anhand dessen fügen wir dem aufgenommenen Bild Meta-Informationen im JPEG Header hinzu, das ganze nennt sich auch Geotagging und macht es uns später einfacher die Bilder in einem Map Anwendung dem Aufnahmeort zuzuordnen.
1 2 3 4 5 6 7 8 |
wget http://www.sno.phy.queensu.ca/~phil/exiftool/Image-ExifTool-9.99.tar.gz gzip -dc Image-ExifTool-9.99.tar.gz | tar -xf - cd Image-ExifTool-9.99/ perl Makefile.PL make -j4 test sudo make -j4 install |
Ein kleine Script nimmt nun alle paar Minuten ein Bild auf, dabei werden vorher kurz die aktuellen Koordinaten, die Höhe und die Geschwindigkeit abgefragt und dann via convert als Text ins Bild geschrieben. Zusätzlich erhält das aktuelle Bild den Aufnahmeort und weitere Informationen via EXIF in den JPEG Header.
1 |
nano /home/pi/Bild.sh |
Das Script erhält folgenden Inhalt (hat noch Experimentier-Status, das werde ich bei Gelegenheit noch verbessern).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#!/bin/bash while true; do sleep 1m tpv=$(gpspipe -w -n 10 | grep -m 1 TPV) latitude=$(echo $tpv | python -c 'import sys, json; print json.load(sys.stdin)["lat"]') longitude=$(echo $tpv | python -c 'import sys, json; print json.load(sys.stdin)["lon"]') altitude=$(echo $tpv | python -c 'import sys, json; print json.load(sys.stdin)["alt"]') speed=$(echo $tpv | python -c 'import sys, json; print json.load(sys.stdin)["speed"]') time=$(echo $tpv | python -c 'import sys, json; print json.load(sys.stdin)["time"]') FILE="/home/pi/bild_$(date +%Y%m%d_%H%M%S).jpg" sudo rm -f /var/tmp/bild.jpg sudo raspistill -o /var/tmp/bild.jpg -w 1280 -h 720 -q 7 -ex auto cmd="sudo convert /var/tmp/bild.jpg -gravity SouthEast -stroke '#000C' -pointsize 24 -strokewidth 2 -annotate 0 'Lat: $latitude Lon: $longitude Alt: $altitude Speed: $speed' -stroke none -fill white -annotate 0 'Lat: $latitude Lon: $longitude Alt: $altitude Speed: $speed' $FILE" eval $cmd sudo exiftool -overwrite_original_in_place '-gpstimestamp<${DateTimeOriginal}+1:00' '-gpsdatestamp<${DateTimeOriginal}+1:00' -GPSLongitudeRef="E" -GPSLongitude="$longitude" -GPSLatitudeRef="S" -GPSLatitude="$latitude" -gps:GPSAltitudeRef=0 -GPSAltitude="$altitude" "$FILE" done |
Speichert mit STRG+X, Y und Enter. Jetzt machen wir das Script noch ausführbar.
1 |
sudo chmod +x Bild.sh |
Ans Ende eurer GPS Start-Datei für den GPS Dienst könnt ihr nun noch folgenden Befehl anhängen, dieser sorgt dafür das die Bild-Aufnahme mit gestartet wird (sudo nano /home/pi/gps-tracker.py)
1 2 |
#start shell script for create pictures every 2 min subprocess.call('sh Bild.sh', shell=True) |
Bei mir wurden auf einer Testfahrt folgende Bilder aufgezeichnet, diese müsstet ihr natürlich wieder mit WinSCP auf euren Rechner holen (wundert euch nicht das die Schrift auf dem Kopf steht, ich hatte einen Parameter der Cam falsch gesetzt).