GPS mit dem Arduino oder mit dem Raspberry Pi

Vor einem Jahrzehnt noch undenkbar in der Zwischenzeit für um die 10€ Euro erhältlich. Ein komplettes GPS Modul  das sogar in Räumen funktioniert und mit dem der Standort bis auf wenige Meter genau ermittelt werden kann.

GPS klingt zunächst unheimlich kompliziert. Die Mathematik dahinter ist es auch, nachzulesen unter https://de.wikipedia.org/wiki/Global_Positioning_System.

In der Zwischenzeit gibt es aber GPS-Module die die Komplexität komplett kapseln.

Die GPS-Module die in der Bauteileliste stehen kommunizieren alle über eine einfache Serielle Schnittstelle, daher ist es recht einfach an die GPS-Daten zu kommen. Man muss nur einen Code schreiben, der eine Serielle Schnittstelle mit 9600 Baud öffnet und kontinuierlich ausliest. Und das ist in jeder Programmiersprache und auf jedem Rechner egal ob Embedded, Microcomputer, Arduino, Raspberry Pi oder PC  oder kein Hexenwerk, weil es Bibliotheken für Serielle Schnittstellen überall gibt.

Das GPS Modul holt man sich am Besten von ebay. Im Prinzip geht jedes Modul, das VCC, GND, RX , TX bietet. Tipp zum Suchen: Nach “NEO-6M” “GPS Modul Arduino” “GY-GPS6MV2” “NEO-6M Flight Controller”, “SkyNav SKM53”  immer in Verbindung mit “Arduino” suchen

Also legen wir auf dem Arduino mal los:

Bauteile:

  • Arduino (Uno, Nano …) oder Raspberry Pi (1,2,3)
  • GPS Modul von ebay
  • Steckbrett
  • Kabel
  • Lego

Schaltplan

Der Arduino Code:

Im Prinzip ist es der Sketch-Code des SoftwareSerial Beispiels.

#include 

SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
 // Open serial communications and wait for port to open:
 Serial.begin(9600);
 while (!Serial) {
 ; // wait for serial port to connect. Needed for native USB port only
 }


 Serial.println("Goodnight moon!");

// set the data rate for the SoftwareSerial port
 mySerial.begin(9600);
// mySerial.println("Hello, world?");
}

void loop() { // run over and over
 if (mySerial.available()) {
 Serial.write(mySerial.read());
 }
 if (Serial.available()) {
 mySerial.write(Serial.read());
 }
}

Der Raspberry Pi / Linux Code:

in Perl, aber wie gesagt es geht mit jeder Programmiersprache.

#!/usr/bin/perl

use strict;
use Device::SerialPort;

my $seriel = Device::SerialPort->new('/dev/ttyS0') || die "Kann /dev/ttyS0 nicht öffnen! ($!)n";
# halt prüfen an welcher tty das GPS-Modul hängt

$seriel->baudrate(9600);
$seriel->parity("none");
$seriel->databits(8);
$seriel->stopbits(1);

$|=1;
my $exit=0;
while($exit < 100000) {  my ($cin, $sin) = $seriel->read(1);
 if($cin)
 {
  print $sin;
  $exit=0;
 }
 else
 {$exit++}
}
print "n";

exit(0);

Steckplatine

Der NMEA 0183 Standard

Die Ausgabe, die man dann angezeigt bekommt sieht im ersten Moment ziemlich verwirrend um mich zu sagen kaputt aus. Es handelt sich dabei aber um die Ausgabe der Koordinaten nach dem NMEA 0183 Standard, nachzulesen in der Wikipedia: “NMEA 0183 ist ein Standard…, der von der National Marine Electronics Association (NMEA) definiert wurde und auch für die Kommunikation zwischen GPS-Empfänger und PCs sowie mobilen Endgeräten genutzt wird. Er besteht aus einer RS422-Schnittstelle und einer Definition von Datensätzen.” Aha, und jetzt?

Syntax des NMEA 0183 Datenformats:

  • Bei den NMEA-Daten handelt es sich um ASCII-basierte Datensätze.
  • Jeder Datensatz beginnt mit einem “$”
  • Jeder Datensatz wird durch ein  () abgeschlossen.
  • Jedes Datum in einem Datensatz wird durch ein “,” getrennt.
  • Dezimaltrennzeichen ist der Punkt (“.”)
  • Uhrzeiten werden in UTC angegeben

Der fertige Aufbau

Dekodieren der GPS-Daten:

Daten meines Empfängers:$GPGGA,223758.00,4848.02931,N,00859.93258,E,1,03,3.14,426.4,M,47.6,M,,*59
Format:$GPGGA,HHMMSS.ss,BBBB.BBBB,b,LLLLL.LLLL,l,Q,NN,D.D,H.H,h,G.G,g,A.A,RRRR*PP

Dekodieren des GPGGA-Datensatzes:

Global Positioning System Fix Data (GPGGA)
Dieses Format enthält die wichtigsten Angaben zur Position und deren Genauigkeit, Anzahl der Satelliten, Höhe über Meeresoberfläche und andere Informationen.

Meine DatenFormatBedeutung
223758.00HHMMSS.ssaktuelle Uhrzeit (UTC)
484802931BBBB.BBBBBreitengrad in Grad und Minuten (ddmm.mmmmmm)
NbAusrichtung des Breitengrades (Nord oder Süd)
85993258LLLLL.LLLLLängengrad in Grad und Minuten (dddmm.mmmmmm)
ElAusrichtung des Längengrades (East oder West)
1QGPS-Qualität:  0 für ungültig
1 für GPS fix
2 für DGPS fix
6 für geschätzt
3NNAnzahl der benutzten Satelliten (00 − 12)
41699D.Dhorizontale Abweichung (dilution of precision)
426.4H.HHöhe der Antenne über der Meeresoberfläche
MhEinheit der Antennenhöhe (Meter)
47.6G.Ggeoidal separation
MgEinheit der geoidal separation (Meter)
A.AAlter des DGPS-Datensatzes
RRRRDGPS-Referenzstation (0000 bis 1023)
*59PPPrüfsumme

Die Ausgabe des GPS-Moduls nach dem NMEA 0183-Standard:

Direkt nach dem Start sehen die Daten so aus. Das ist normal!

$GPGSV,1,1,00*79
$GPGLL,,,,,,V,N*64
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,1,1,00*79
$GPGLL,,,,,,V,N*64
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30

Die serielle Ausgabe