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 / Linix 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 <CR><LF> 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 Daten Format Bedeutung
223758.00 HHMMSS.ss aktuelle Uhrzeit (UTC)
484802931 BBBB.BBBB Breitengrad in Grad und Minuten (ddmm.mmmmmm)
N b Ausrichtung des Breitengrades (Nord oder Süd)
85993258 LLLLL.LLLL Längengrad in Grad und Minuten (dddmm.mmmmmm)
E l Ausrichtung des Längengrades (East oder West)
1 Q GPS-Qualität:  0 für ungültig
1 für GPS fix
2 für DGPS fix
6 für geschätzt
3 NN Anzahl der benutzten Satelliten (00 − 12)
41699 D.D horizontale Abweichung (dilution of precision)
426.4 H.H Höhe der Antenne über der Meeresoberfläche
M h Einheit der Antennenhöhe (Meter)
47.6 G.G geoidal separation
M g Einheit der geoidal separation (Meter)
A.A Alter des DGPS-Datensatzes
RRRR DGPS-Referenzstation (0000 bis 1023)
*59 PP Prü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