In diesem Teil der Raspberry Pi Reihe zeige ich, wie ein GPS-Modul mit Raspberry Pi verbunden und ausgewertet werden kann. Bei dem verwendeten GPS-Modul handelt es sich um ein NEO-8M GPS Modul der Firma u-blox, welches direkt mit dem UART des Raspberry Pi verbunden werden kann.
Auslesen über die Konsole:
Sobald das Modul an die serielle Schnittstelle vom Raspberry Pi angeschlossen wurde, kann es über den Schnittstellentreiber /dev/serial0 verwendet werden:
Die Standardbaudrate für das Modul beträgt 9600 Baud. Über den Konsolenbefehl
stty
können die Einstellungen für die verschiedenen Terminals, wie z. B. die serielle Schnittstelle, geändert werden.
$ sudo stty 9600 -F /dev/serial0
Und anschließend kann die Maus über den Befehl
cat
ausgelesen werden:
$ cat /dev/serial0
Das Modul gibt die GPS-Informationen in verschiedenen Datensätzen aus. Diese Datensätze sind im NMEA 0183 Standard definiert und beginnen mit einem $-Zeichen.
- Track Made Good and Ground Speed (VTG)
- GPS DOP and Active Satellites (GSA)
- Geographic Position-Latitude/Longitude (GLL)
- Global Positioning System Fix Data (GGA)
- Text Transmission (PTXT)
- Recommended Minimum Specific GPS/Transit Data (RMC)
- GPS Satellites in View (GSV)
- Time and Date (ZDA)
Hinweis:
Der ursprüngliche Standard definiert eine Baudrate von 4800 Baud für die Datenübertragung. Seit der Version 3.01 werden aber auch Baudraten bis zu 38400 Baud unterstützt.
Schauen wir uns die einzelnen Datensätze mal genauer an…
Auslesen mit Python:
Zum Auslesen des GPS-Moduls muss als erstes die serielle Schnittstelle geöffnet werden:
try: if(not(UART.isOpen())): UART.open() except: print("[ERROR] Can not open serial port!") exit()
Anschließend werden die einzelnen Nachrichtenzeilen eingelesen und in einem
Dictionary
gespeichert:
while(True): Datasets = dict() Message = UART.readline().decode("ascii").strip().split(",") if("$" in Message[0]): Datasets[Message[0]] = Message[1:]
Nun können die einzelnen Informationen aus den Datensätzen extrahiert und ausgegeben werden. Der Aufbau der einzelnen Datensätze kann hier eingesehen werden.
So kann z. B. der GGA-Datensatz ausgewertet werden um genauere Details zur Positionsbestimmung zu erhalten.
for Key in Datasets.keys(): if("GGA" in Key): print("Use {} satellites".format(Datasets[Key][6])) if(Datasets[Key][5] == "1"): print("Time: {}".format(Datasets[Key][0])) print("Latitude: {} - {}".format(Datasets[Key][1], Datasets[Key][2])) print("Longitude: {} - {}".format(Datasets[Key][3], Datasets[Key][4])) else: print("GPS not fix!") print("GPS quality: {}".format(Datasets[Key][5]))
Wohingegen der GSV-Datensatz genutzt werden kann um Informationen über die verwendeten Satelliten zu erhalten.
elif("GSV" in Key): print("Number: {}".format(Datasets[Key][1])) print("ID: {}".format(Datasets[Key][3])) print("Visible satellites: {}".format(Datasets[Key][2])) print("Elevation: {} degree".format(Datasets[Key][4])) print("Azimuth: {} degree".format(Datasets[Key][5])) print("SNR: {} dB".format(Datasets[Key][6]))
Die Ausgabe sieht mit den beiden Punkten folgendermaßen aus:
ID: 21 Visible satellites: 12 Elevation: 14 degree Azimuth: 074 degree SNR: dB Number: 1 ID: 05 Visible satellites: 03 Elevation: degree Azimuth: degree SNR: 30 dB ID: 01 Visible satellites: 12 Elevation: 07 degree Azimuth: 252 degree SNR: 34 dB Number: 2 ID: 11 Visible satellites: 12 Elevation: 32 degree Azimuth: 275 degree SNR: 31 dB Number: 3 Use 09 satellites Time: 171103.000 Latitude: 5059.0659 - N Longitude: 00722.9327 - E
Falls es erforderlich ist, kann die Auswertung um zusätzliche Punkte erweitert werden. Das Vorgehen ist dabei analog zu dem bereits vorgestellten Ablauf. Die ausgelesenen Längen- und Breitengrade können anschließend in ein Kartenprogramm eingegeben werden, wodurch der genaue Standort angezeigt werden kann.
Das Python-Skript gibt es in meinem GitHub-Repository zum Download.
Hallo Daniel,
ich möchte mit einer USB-GPS-Maus einen NTP-Server betreiben, allerdings muss ich nach jedem Booten die virtuelle serielle Schnittstelle von 9600 auf 4800 Baud händisch einstellen (stty -F /dev/ttyUSB0 4800). Wie kann ich denn diesen Befehl automatisch beim Booten ausführen??
Gruß
Martin
Hey,
also der einfachste Weg wäre es diesen Befehl in die Datei /etc/rc.local zu packen. Dadurch wird der Befehl bei jedem Bootvorgang ausgeführt.
Gruß
Daniel
hat geklappt :-)
vielen Dank!
Hallo Daniel,
wie hat Du das mit dem NTP-Server gelöst?
Möchte auch einen betreiben um meine Geräte im Netzwerk damit auf gleichem Stand zu halten.
Viele Grüße Johannes
Hallo Johannes,
ich habe noch keinen NTP Server aufgesetzt.
Von daher weiß ich nicht was du meinst :(
Gruß
Daniel
Hallo,
ich habe Probleme dein GPS Script auszuführen. Ich habe das GPS Modul am ttyAMA0. Im Sript habe die Angaben angepasst.
Fehlermeldung:
Traceback (most recent call last):
File „gps.py“, line 1, in
import serial
ImportError: No module named serial
Ich habe dein Sript copy&paste, gps.py gespeichert, sudo chmod 777 gps.py, und starte es dann mit python gps.py.
Was mache ich falsch?
Vielen Dank.
Tim
Hey,
hast du das Modul „python-serial“ installiert?
Gruß
Daniel
Moin !
kann ich eigentlich jedes beliebige GPS Modul mit dem Raspberry auslesen oder gibt es auch Einschränkungen / Schwierigkeiten mit manchen Modulen. Ich möchte als Techniker Projekt GPS Signale auslesen und die Positionsdaten zur Standortbestimmung per SMS versenden.
be happy
boris
Hey,
die Protokolle sind Standardisiert, von daher sollte es keine Probleme mit anderen Modulen geben.
Falls doch schreib mir eine E-Mail, dann helfe ich dir :)
Gruß
Daniel
kannst du mir einen bestimmten Typ oder eine Marke empfehlen?
Hey,
ne kann ich nicht.
Habe bisher nicht mehr als das eine getestet.
Gruß
Daniel
Grüss Dich !
hast Erfahrung mit GPS Empfängern und GPIO. Ich finde nur GPS Empfänger im Gehäuse mit USB oder Bluetooth. Einerseits möchte ich den Empfänger auch etwas entfernt vom Rasp positionieren andererseits vielleicht über den GPIO. Macht ie Schnittstelle einen Unterschied -> USB oder GPIO?
alles gute
Boris
Hey Boris,
die Module haben meistens ein UART oder ein USB Modul.
USB kannst du halt direkt an den USB vom Raspberry Pi anschließen und das Modul verhält sich dann wie ein virtueller COM-Port. Wenn die einen UART haben, haben sie einen „richtigen“ COM-Port.
Das ist nur ein Schnittstellenunterschied.
Erfahrung habe ich, wie gesagt, mit keinem anderen GPS-Modul…sorry :(
Gruß
Daniel
alles klar.
vielen Dank
Grüss dich !
hast du mir einen Rat wie ich in C GPS Signale über /dev/ttyACM0 auslesen kann?
Wie binde ich die Schnittstelle ein?
alles Gute
Boris
Hey,
schau mal unter der Kategorie „Der USART“ nach.
Vielleicht wirst du da ja fündig :)
Gruß
Daniel
Hi!,
ich hab gerade ein Jahresprojekt am laufen und es sind paar Fragen aufgekommen.
1. Sobald die Maus an einen der USB Anschlüsse vom Raspberry Pi angeschlossen wurde, ist sie unter “/dev/ttyUSB0″ verfügbar:
Ich bekomme entweder den Fehler dass das Verzeichniss nicht existiert oder dass ich zu wenig rechte haben. Ich hab es auch schon mit root versucht und keinen Erfolg gehabt.
2. Ich hab die GPS Software NAVIT installiert. Bis zur installation hat mein Holux Rot geleuchtet aber zumindest die Koordinaten ausgegeben. Damit hats noch geklappt:
$ sudo stty 4800 -F /dev/ttyUSB0
Und anschließend kann die Maus über den Befehl
$ cat /dev/ttyUSB0
Nach der Installation von Navit und allen Einstellungen zeigt mir der Holux im Panel mit den exakt gleichen befehlen nur noch Fragezeichen und kryptische Zeichen. Was ist passiert?
3. Das GPS.py wird bei mir nicht ausgeführt bzw. es werden keine daten angezeigt. Muss man noch spezielle Einstellungen vornhemen? Muss der der Holux unbedingt unter freiem Himmel sein?
4.Falls du dich zufällig auch mit Nativ auskennst: Nach allen Einstellungen wird mir trotzdem keine Map angezeigt. Map wurde richtig heruntergeladen und in das programm eingefügt. Das Programm an sich läuft einwandfrei.
ich würde mich riesig freuen wenn du mir vielleicht einen Teil der Fragen beantworten würdest!
Schon mal vielen Dank und ein schönes Wochenende
Hey,
zu 1:
Du hast dich auch direkt als root angemeldet und konntest nicht auf die Maus zugreifen?! Wenn ja, schick mir mal bitte einen Screenshot mit den Konsoleneingaben etc.
zu 2:
Bitte auch am besten mal ein Bild schicken
zu 3:
Die Maus sollte auch was senden wenn sie nicht verbunden ist.
Hast du die Schnittstelle in dem Skript an dein System angepasst?
zu 4:
Damit kenne ich mich leider nicht aus :(
Schick mir mal die Informationen und dann kann ich mal schauen ob ich ein Problem finde :)
Gruß
Daniel
Hallo,
erstmal danke für Deine Informationen – sie haben mir sehr weitergeholfen! Ich habe jetzt ein Script geschrieben, das die Daten des GPS-Empfängers (irgendein alter Navilock-USB-GPSr) ausliest und auf einem 16×2 LC-Display darstellt (soll ins Cockpit eines Boots). Manuell per Konsole gestartet läuft auch alles super.
Wenn ich das Script allerdings in die rc.local eintrage, crasht es mangels ausreichender Rechte auf der /dev/ttyUSB0-Schnittstelle. Wie löse ich das?
Danke!
Hey,
mmh da sollte es eigentlich keine Rechteprobleme geben, da die rc.local als root ausgeführt wird.
Wie lautet den die komplette Zeile?
Gruß
Daniel
Hi,
das Problem war wohl ein anderes, läuft jetzt. Ich poste hier gern mal einen Link, wenn das Projekt komplett dokumentiert ist.
Hallo, genau das Vorhaben für das Boot mit LCD Display habe ich auch. Gibt es schon eine Doku zu dem Projekt? Gruß, Philip
Hey Philip,
was genau brauchst du? Eine Anleitung für ein LCD?
Gruß
Daniel
Voila:
http://youtu.be/J3g6a1yPk0Q
http://gpspi.gpsmonitor.de/
Das ist die erste Version, und es fehlt noch der Realitätscheck an Bord (folgt wohl diese Saison), aber ich bin schon ganz glücklich damit.
Grüss Dich !
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BAUDRATE B9600
/*struct gps
{
char GPVTG[40];
char GPGGA[80];
}nutzdaten;
*/
int main(void)
{
printf(„\n\n*****Techniker Abschlußarbeit 2014*****\n***********GPS-Daten auslesen**********\n\n“);
FILE *stream;
char daten[150];
int a,b = 0;
char GPVTG[40];
char GPGGA[80];
while(!NULL)
{
stream = fopen(„/dev/ttyACM0″,“r“); //Opening device file
fscanf(stream,“%80s\n“,daten);
if(daten[150]==“$GPVTG“)
{
for (a=0; a <= 40; a++)
{
scanf("%s",&GPVTG[a]);
}
}
if(daten[150]=="$GPGGA")
{
for (b=0; b <= 80; b++)
{
scanf("%s",&GPGGA[b]);
}
}
printf("%s\n%s\n",GPVTG,GPGGA);
fclose(stream);
}
printf("\n%s Schnittstelle lässt sich nicht öffnen", stream);
return 0;
}
ich versuche seit Stunden aus den Daten des GPS Empfängers die GPGGA und GPVTG Daten rauszufiltern. Hast du mir einen Rat?
Grüss DIch
könntest du mir folgenden Teil deines UART_Empfangen Programmes erklären?
memset(&newtio, 0, sizeof(newtio));
newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = 0;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 1;
tcflush(File, TCIFLUSH);
tcsetattr(File, TCSANOW, &newtio);
vielen Dank
Boris
Hey,
was die einzelnen Zeilen genau machen kann ich dir leider nicht wirklich erklären (müsste es selber erst mal raus suchen).
Sie dienen, einfach gesagt, einfach nur dazu um den UART zu initialisieren.
Gruß
Daniel
…und sind zum Auslesen der Schnittstelle /dev/ttyACM0 essentiell ?.
Ich habe mir an deinem Programm beispiel genommen. Warum vergleichst du Zeichen mit 13?
Wenn ich nur GPGGA und GPVTG nutze möchte, muss ich diese Strings erst in Integer wandeln bevor ich sie aus der Quelle ausfiltern kann oder?
Hey,
ja genau. Damit du die Schnittstelle benutzen kannst, musst du diese Zeilen haben.
Ich vergleiche mit dem Zeichen 13, da dieses Zeichen ein Zeilenende signalisiert.
Die Strings musst du nicht in einen Integer umwandeln. Du kannst direkt einen Stringvergleich machen.
Gruß
Daniel
Hallo,
ich probier jetzt schon eine Weile daran, aus dem GPS Stream die Protokolle GPGGA und GPVTG auszufiltern. Hast du mir nen Tip?
Ich habe strstr und strpbrk angewendet, aber ohne Erfolg.
…ich bin auf dem Gebiet noch nicht so fit…
warum kann ich das Programm nicht stoppen mit bsp. STRG+C, wenn ich dein Programm folgendermaßen ändere:
while(1)
{
zeichen = Empfangen();
Recieve[Laenge] = zeichen;
WriteFile();
}
das Terminal reagiert nicht auf STRG+C
Hey,
wie hast du das Programm den gestartet?
Ist da ein „&“ am Ende des Programmaufrufs gewesen? Weil dann läuft das Programm im Hintergrund.
Gruß
Daniel
grüss dich,
ich hab mir deinen Quellcode erstmal ausgedruckt und versucht ihn mit Hilfe von http://openbook.galileocomputing.de/c_von_a_bis_z
zu verstehen.
Mittlerweile hab ich den Quellcode soweit, dass der Compiler keine Warnungen und Fehler mehr findet.
alles Gute
Boris
Hey Boris,
klasse! Das hört sich gut an :)
Falls du Fragen haben solltest, kannst du dich natürlich immer melden :)
Gruß
Daniel
guten morgen
wie programmierst du einen Stringvergleich, wenn du nur eine Constante, sagen wir $GPGGA, hast und aus verschiedenen Zeichenketten, die alle mit $GPXXX beginnen, den $GPGGA string filtern möchtest?
Ich wende strncmp an. Der GCC gibt aber nur Ruhe wenn ich vor die Variablen ein & setze, damit aber die Adressen miteinander vergleich und nicht den Adressinhalt.
kannst du mir erklären was daran falsch ist?
#define E 80
…..
const char ref1[]={‚$‘,’G‘,’P‘,’G‘,’G‘,’A‘};
const char ref2[]=“$GPVTG“;
char Receiver[E]=““; //Empfangsdaten für Zwischenspeicherung
const char *ptrRes, *ptrRef1;
int main()
{
int a,b, zahl1, zahl2, ergebnis;
UART_Init();
while(1)
{
string = receive();
Receiver[Laenge] = string;
for(Laenge = 0; Laenge < 7; Laenge++)
{
ptrRes = &Receiver[Laenge];
ptrRef1 = &ref1[Laenge];
if(0 == strncmp(const char *ptrRes, const char *ptrRef1, int Laenge))
//if(ergebnis==0)
gpgga[Laenge]=Receiver[Laenge];
else
break;
}
der Compiler meldet:
projektTA.c:56:20: error: expected expression before ‘const’
projektTA.c:56:20: error: too few arguments to function ‘strncmp’
alles Gute
Boris
Hey,
schau mal hier, vielleicht hilft dir das weiter:
http://stackoverflow.com/questions/6892586/how-to-define-a-constant-array-in-c-c
Gruß
Daniel
Grüss dich,
warum ergibst du in deinen IF-Anweisung in der while-Schleife Recieve einen hex-Wert?
alles Gute
Hey Boris,
was genau meinst du?
Gruß
Daniel
…if(zeichen == 13)
Recieve[Laenge]=0x0D; //0x0D hex = 13 dez
…
Hey,
das muss ein anderes Programm sein ^.^
Aber den Wert 0x0D nehme ich wegen dem Carriage Return. Kannst aber auch den Wert 13 verwenden.
Gruß
Daniel
dieser Befehl steht in Zeile 12 ab der main gezaehlt, deines Programms UART_Empfangen. Dank Wikipedia weiss ich jetzt auch was ein Carriage Return ist.
Du erzeugst mit 0x0D, was die Zahl 13 als hex-Wert darstellt, ein CR? Da komm ich jetzt nicht ganz mit. hex-Werte in arrays werden als CR interpretiert?
Hey Boris,
ahh da hast du die Zeile her :)
Sorry nicht dran gedacht. Ich schaue einfach ob das aktuelle Zeichen ein CR ist und reagiere dann da drauf, sprich ich speichere in meinem Text ein CR, zähle den Counter hoch und springe dann in das Unterprogramm, welches den aktuellen Empfangsbuffer in eine Datei schreibt. So wird dann jede Zeile geschrieben :)
Gruß
Daniel
variieren die Zeichen nicht? Ich meine, je nach Position sind mehr oder weniger Informationen im Protokoll enthalten, was das Protokoll dann unterschiedlich lang werden lässt. Sodass das Ende nicht immer an Position 13 sitzt.
Hey Boris,
ja das stimmt. Aber ich vergleiche ja auch nur auf ein Zeichen, sprich ich warte bis ein bestimmtes Zeichen gesendet wird.
Die Länge beachte ich gar nicht. Der Zähler dient nur dazu um das Zeichen in die entsprechende Stelle des Empfangsstrings zu schreiben. Pro Zeichen wird der Zähler um eins erhöht und der Zähler markiert die Stelle an der ich mich gerade befinde (also z.B. 4. Buchstabe).
Gruß
Daniel
warum verwendest du nicht “ als Ende-Zeichen. Nach jedem Protokoll wird ein \n gesendet. Wenn du Zeichen == 13 vergleichst, liefert dir also das GGA Protokoll immer den Wert 13 als Ende-Zeichen, verstehe ich das so richtig?
Hey,
nein du verstehst das falsch. Jede Zeile von dem Modul wird mit 0x0D abgeschlossen.
Das heißt ich empfange solange die Zeichen (und speichere die in einem Buffer) bis ich ein 0x0D empfange. Dann weiß ich das die Zeile zu Ende übertragen wurde und speichere den aktuellen Bufferinhalt.
Dann geht alles von vorne los.
Gruß
Daniel
Moin Grüss Dich,
kennst du dich mit Structuren aus? Ich hab mein Programm soweit vorwärts bewegt, mit Zeigern und Strukturen, bis mir gerade aufgefallen ist, das die Uhrzeit, die ja eigentlch bei jedem Schleifendurchlauf aktualisiert wird, nur bei Programmaufruf (bei mir übers Terminal) die aktuelle Uhrzeit liefert und stehen bleibt. Vom String kann ich aber eine laufende Uhr beobachten.
Liegt das an der struct und den Zeigern => call by ref?
kennst du das Problem
alles Gute
Boris
Grüss Dich,
ich habe deinen Blog schon gut gefüllt, was :) Fast jedes Mal, wenn ich dich nach Rat gefragt habe, bin ich kurze Zeit danach selbst darauf gekommen – hat wohl gute Energien dein Block.
Ich wandle zur Zeit die empfangenen Grade in Dezimalwerte um. Habe dazu auch auf Wiki => NMEA die Formel //XXYY.ZZZZ ⇒ XX° + (YY.ZZZZ / 60)° gefunden. Du teilst einfach nur durch 100. Nach welchem System rechnest du?
alles Gute Boris
Hallo Boris,
das ist doch mal schön :)
So muss es sein!
Mmh das Teilen durch 100 habe ich, glaube ich, einfach nur gemacht, damit man direkt die erste Koordinatenstelle ablesen kann. Eine Umrechnung habe ich in dem Programm nicht mit berücksichtigt.
Gruß
Daniel
alles klar. Vielen Dank.
alles Gute
Boris
Hallo Kampi,
bei mir hat alles soweit geklappt, nur wenn die GPS Maus keinen Empfang hat , stürzt das Skript bei
Breitengrad = float(Datenliste[2])
ab. Das Kann man umgehen, indem man erst überprüft, ob die Qualität != 0 ist.
Viele Grüße
Sören
Hey,
ja, das kann passieren. Ich weiß jetzt nicht genau was dein Modul ausgibt, wenn kein Empfang da ist. Aber u.U. ist die Nachricht dann vom Format her nicht passend und das verursacht den Fehler.
Gruß
Daniel
Hallo Leute,
coole Tutorial. Ich habe nur ein Problem. Beim Auslesen des GPS Empfängers wird mein Standort nicht genau angezeigt. Ich bekomme zwar Längen- und Breitengrad nur ist die ermittelte Position ca 50km Luftlinie von meiner Tatsächlichen entfernt.
Hat einer von euch eine Lösung für das Problem.
Hey,
kann es ggf. sein, dass du die Koordinaten noch umrechnen musst?
Ansonsten kann das eigentlich nur am GPS Modul liegen, da dieses Modul ja die Daten ausgibt.
Hat es vielleicht nur Empfang zu einem Satelliten?
Gruß
Daniel
Ich gebe die Daten bei google maps ein und erhalte dann die Position die wie gesagt 50 km Luftlinie entfernt ist.
Satelliten habe ich laut Script 10 Stück. Also mehr als genug im Normalfall.
Wie meinst du das mit dem umrechnen? Ich habe schon bei verschiedenen Seiten die dezimal in Grad umrechnen lassen und komme immer auf die gleiche Position.
Bin langsam am verzweifeln. Zumal das ding ins Auto zum loggen der Position soll.
Wenn ich die Daten über cgps auslese bekomme ich den korrekten Standort. Nur über das Script werden die daten ungenau. Woran kann das liegen?
Hey,
schick mir mal bitte einen Datensatz aus meinem Skript, einen korrekten Datensatz, dein Programm und die Bezeichnung des GPS Moduls zu.
Dann schaue ich mal was ich machen kann (wird aber wahrscheinlich erst am Wochenende was werden).
Gruß
Daniel
Hallo,
das ist der Datensatz aus deinem Programm.
GPGGA,213938.000,4927.8941,N,01100.1035,E,1,08,1.1,321.8,M,47.8,M,,0000*5E
Laenge des Datensatzes: 74 Zeichen
Uhrzeit: 21:39:38
Breitengrad: 49.278941 N
Laengengrad: 11.001035 E
Hoehe ueber dem Meeresspiegel: 321.8 M
GPS-Qualitaet: 1
Anzahl der Satelliten: 8
Checksumme: 0000*5E
Den ist der Datensatz aus cgps kann ich leider nicht rauskopieren. bekomme nur die Daten angezeigt.
Was mir noch aufgefallen ist das wenn ich den Empfänger per cat /dev/ttyUSB0 anspreche, ich die gleichen werte wie aus deinem Programm bekommen.
Der Empfänger ist ein NaviLock NL-302U mit einem SiRFstarIII Chipsatz.
Ich hoffe die Infos helfen dir. Danke schon mal im voraus
Hallo Kampi,
das Problem mit den falschen Positionsdaten habe ich nun selbst gelöst. Die Berechnung der Nachkommastelle war irgendwie falsch (zumindestens für google maps).
Jetzt funktioniert alles so wie es soll.
Nun muss nur noch die Datenbank aufgesetzt werden und die Daten da rein und schon ist der GPS Logge fürs Auto komplett.
Hey Gerald,
ahh gut das du es hinbekommen hast :)
Dann brauch ich am Wochenende nicht drüber schauen ;)
Aber einen Rechenfehler hatte ich schon vermutet, da bei mir alles gestimmt hat.
Dann mal viel Erfolg und gutes gelingen :)
Gruß
Daniel
Das einzige was mich noch wundert ist, ist das die Uhr die per GPS übertragen wird um 2 Stunden nach geht.
Greenwich geht von uns aus gesehen nur eine Stunde nach. Ist das immer so oder hat sich evtl hier ein Fehler eingeschlichen?
Hallo,
das stimmt schon. Wenn du mal hier schaust:
http://www.uhrzeit.org/weltzeit.php
Die Differenz von Berlin zur UTC ist +2h. :)
Gruß
Daniel
Hallo Kampi,
weis nicht ob die Frage hier reinpasst.
Also ich habe eine DCF77- Empfangsplatine. Die mir das Zeitzeichen im Sekundentakt ausgibt. Habe mir ein Pythonprogramm geschrieben und alles funktioniert bestens. Jetzt mein Problem. Wie übergebe ich die Zeit bzw. den Zeitstring an die Funktion date?
Händisch kann ich die Zeit stellen zB. >> date -s ‚20141024 13:00‘ aber über das Python- Programm funktioniert das nicht.
Hilfe!?
Gruß Lush
Hey Lush,
einfach so machen:
import os
os.system(„date -s 20141024 13:00“)
Dann sollte es funktionieren.
Gruß
Daniel
Hallo Daniel,
erst mal vielen Dank für Deine Antwort. Leider kommt immer noch eine Fehlermeldung.
Teil meines Programmcodes:
# Jahr, Monat, Tag, Stunde, Minute als String
Datum = ‚date -s ‚ + Jahr + Monat + Tag + ‚ ‚ + Stunde + ‚:‘ + Minute
os.system(Datum)
Fehlermeldung: date: Dem Argument „“12:57″“ fehlt das führende „+“
mit
date –help bin ich nicht weiter gekommen
Gruß Lush
Hallo Lush,
lass dir mal den String „Datum“ ausgeben.
Er muss etwa diese Form haben:
date -s „Tag/Monat/Jahr“ Stunde:Minute:Sekunde“
Ich denke du musst das eher so machen:
Datum = „date -s \“ “ + Tag + „/“ + Monat + „/“ + Jahr + “ “ + Stunde + „:“ Minute + „:“ + Sekunde + „\““
Wichtig ist die Übergabe an den Befehl „date“ in Anführungszeichen zu setzen. Dafür einfach im String mit \“ ein Anführungszeichen einbauen.
Gruß
Daniel
Hallo Daniel
Danke für Deine Antwort. Irgend etwas stimmt mit der Formatierung nicht.
Ich habe mir jetzt folgendermaßen geholfen:
—————————————————————————
os.system(„date -s “ + Jahr + Monat + Tag)
os.system(„date -s “ + Stunde + ‚:‘ + Minute + ‚:‘ + str(0))
————————————————————————–
Damit setze ich das Datum und anschließend die Zeit. Es läuft bestens.
(Gesetzt wir das Datum und die Zeit immer nach Ablauf der 59. Minute, wenn das Übertragungsprotokoll des DCF77 Signals fertig übertragen ist)
Benutzt wird dieses Programm für die Zeiteinstellung nach dem Neustart des Raspi. Eine Anbindung ans Internet ist nicht gegeben weil in einer Gartenhütte abseits von jeder Ortschaft betrieben.
Nochmals vielen Dank für Deine Hilfe
Gruß Lush
Hallo Lush,
wenn es jetzt funktioniert ist es doch super ;)
Schau dir am besten noch mal den String komplett an (also den Befehlsaufruf).
Eventuell habe ich mich auch irgendwo verschrieben. Einfach den Befehl in einer Variable zwischenspeichern und dann mal in der Konsole ausgeben und schauen ob es das ist was der Befehl „date“ verlangt.
DCF77 kann ich bei mir leider nicht wirklich nutzen – irgendwie hat kein Modul Empfang :(. Sonst hätte ich da auch schon mal mehr mit gemacht. Aber so als Zeitsynchronisation für den Pi ist das wirklich klasse…da hast du recht :)
Gruß
Daniel
Hallo Daniel,
nochmals Danke für Deine Antwort. Du hattest Recht;
„date -s “ muss in Anführungszeichen übergeben werden. Sollen auch Stunde und Minte im gleichen Strng übergeben werden so muss vor der Stunde nochmals „date -s “ gesetzt werden.
——————
os.system(„date -s “ + Jahr + Monat + Tag + „date -s „+ Stunde + Minute)
——————
Gruß Lush
P.S. Dein Buch ist, für einen Anfänger wie mich, sehr verständlich geschrieben.
Hallo Lush,
schön das es jetzt funktioniert :)
Das freut mich (ebenso wie das dir das Buch gefällt :) )!
Falls du weitere Fragen hast, schreib mir ruhig.
Gruß
Daniel
Irgendeine Idee warum ich, im gegensatz zu anderen scripten, dieses nicht per PHP auf einer webseite anzeigen kann?
Eventuell fehlen dem Webserver einfach Zugriffsrechte auf die serielle Schnittstelle oder die Datei liegt außerhalb des Verzeichnisses /var/www.
Gruß
Daniel
Hallo,
danke für das tolle Tutorial, hab es auf Anhieb ans laufen bekommen. Super, dass Du auch die Scripte bereitgestellt hast.
Habe jetzt, genau wie Gerald das Problem der Genauigkeit.
$ sudo cgps -s
gibt mir den bis auf 5m genauen Längen und Breitengrad an.
Aus dem Script hier bin ich gute 25km Luftlinie daneben.
Woran kann das liegen?
Hey Frank,
klasse das es läuft.
Eventuell habe ich bei der Berechnung was falsch gemacht, sodass deswegen falsche Werte rauskommen (gehe ich fast von aus, da sich die Rohdaten der Maus ja nicht ändern, wenn man zwei unterschiedliche Programme verwendet ;) ).
Ich muss mich da mal genauer einlesen und dann korrigiere ich das mal.
Gruß
Daniel
Hey Frank,
so ich habe das Programm mal überarbeitet.
Teste es mal bitte erneut und sag mir ob es jetzt stimmt.
Ich habe es eben getestet und bei mir kommt nun das selbe raus wie bei Google ;)
Gruß
Daniel
Hallo Daniel,
huch … da kam aber eine schnelle Antwort, hab ich garnicht mit gerechnet …
Also , ich hab Dein neues GPS.py probiert, funktioniert aber leider nicht.
Komme zwar jetzt an einem anderen Punkt raus, aber leider nicht am Standort. Möchte ungerne meine Koordinaten hier posten, vielleicht gibt es da eine andere Möglichkeit.
Hab da vielleicht auch nicht alle Informationen in meinem ersten Post geliefert: Ich habe keine GPS Maus, sondern ein NEO M6 von Ublox. Kostet um die 20€ und funktioniert sehr gut.
Deinen Code habe ich in mein Script implementiert, daran dürfte es aber eigentlich nicht liegen …
Könnte per PM ein paar snapshots senden, vielleicht bekommen wir es dann in den Griff .. ?
Hallo Frank,
mmh. Du benutzt aber auch schon das richtige Koordinatenformat? Es gibt ja folgende Darstellungsarten:
+ DD°MM.MMMM’
+ DD.DDDD°
+ DD° MM’ SS”
Ich errechne z.Z. das zweite.
Um wie viel liegst du den daneben? An der Maus sollte es eigentlich nicht liegen, da die Protokolle Standard sind.
Ansonsten sende mir ruhig mal ein paar Bilder zu :)
Gruß
Daniel
HI Daniel, sorry, alles auf Anfang!
Das System und Dein Script funktionieren SUPER!
Geschätzt würde ich sagen: auf 1m genau!!!
Nach einem Neustart hatte sich das Problem in Luft aufgelöst …
Good Job! Danke nochmal!
Hey Frank,
ah du hast wahrscheinlich noch das alte Skript gehabt und das neue aufkopiert, aber das Skript nicht neu über Python gestartet :)
Wenn sich das Programm ändert, musst du es immer neu starten, da der Python Interpreter das Skript nur beim Aufrufen einmalig einliest.
War schon etwas am verzweifeln, da ich nicht wusste wo jetzt das Problem ist :P
Schön das es nun aber funktioniert! Ich wünsche dir viel Spaß damit :)
Gruß
Daniel
Gibt es dazu auch noch andere GPS Geräte, die ich nutzen kann, denn die von dir angeführte GPS Maus bekomme ich nicht zu kaufen – scheint schon etwas äkter zu sein ?!
Gruss kasi
Hallo Kasi,
du kannst auch jedes andere Modul mit einer seriellen Schnittstelle nehmen (es muss natürlich schon die entsprechenden Protokolle ausgeben :))
Gruß
Daniel
Hallo,
du benutzt die Variable ‚Laenge‘ sowohl für die Länge des Datensatzes als auch für den Längengrad.
Daher auch die seltsame Ausgabe für die Länge des Datensatzes im Screenshot.
# Laenge des Datensatzes feststellen
Laenge = len(Input)
.
.
.
# Laengen und Breitengrad herausfiltern und berechnen
.
.
.
Laenge = round(Laengengrad + (Laengenminute / 60), 6)
Hallo Blechi,
huch, danke für den Hinweis. Den Fehler habe ich gar nicht gesehen.
Das Programm habe ich mal korrigiert. Der Screenshot wird bei Gelegenheit aktualisiert.
Gruß
Daniel
Wir haben hier einen Raspberry B+ und einen Raspberry 2.0
Auf dem B+ funktionier der Befehl cat /dev/ttyUSB0 ohne Probleme, aber auf dem 2.0 spuckt er Fehlerhafte Datensätze aus, teilweilse leer , , , , , teilweise ein komisches Sonderzeichen / Störzeichen.
Gibt es für den 2.0 etwas anderes zu berücksichtigen?
So sieht der Output beim 2.0 aus:
$GPVTG,0.00,T,,M,0.01,N,0.02,K,N*31
▒▒▒▒▒▒▒▒▒▒#$GPGSV,3,2,11,07,40,063,,20,34,302,,15,15,292,,08,11,057,*79
$GPGSV,3,3,11,09,10,111,,21,08,331,,27,08,025,*40
11,057,*79
$GLGSV,3,1,09,75,75,041,,65,59,161,,66,58,313,,76,45,222,*6C
$GLGSV,3,2,09,74,19,042,,83,13,007,17,72,09,149,,67,07,324,*6B
$GLGSV,3,3,09,84,04,056,*57
$GNRMC,185856.935,V,,,,,0.01,0.00,231115,,,N*5F
$GPVTG,0.00,T,,M,0.01,N,0.02,K,N*31
Hallo Verrain,
die Störzeichen könnten von der Schnittstelle kommen.
Das „,,,,“ kommt wegen unzureichendem Empfang der Maus. Dann können einige Daten nicht korrekt bestimmt werden.
Gruß
Daniel
Aber wieso funktioniert es dann mit dem B+, aber nicht mit dem 2.0? Hast du das Modul bereits mit einem 2.0 getestet?
Grüße
Verrain :)
Hallo Verrain,
ich habe es mit einer 512er Variante getestet.
Wie gesagt, die leeren Stellen im Protokoll kommen von der Maus selber. Das andere weiß ich nicht woran es liegt. Es könnte exemplarisch sein, es kann grundsätzlich bei der Version 2 so sein (da sitzt immerhin einen ein anderer Chip drauf). Eventuell liegt das auch an der Maus, weil ich hatte eigentlich nie Probleme :)
Ich habe noch nicht so viel mit der Version 2 gemacht, daher kann ich da recht wenig zu sagen.
Gruß
Daniel
Hallo,
die Seite, auf die der Link „Umrechnen von GPS Koordinaten“ unter „Zusätzliche Infos“ verweist, ist leider tot.
Viele Grüße
Guido
Hallo Guido,
danke für den Hinweis. Ist gefixt.
Gruß
Daniel
Hallo kampi,
nach der Eingabe cat /dev/ttyUSB0 erscheinen bei mir leider keine Daten, jedoch auch keine Fehlermeldung. Dasselbe passiert nach dem GPS-Programm. Wo könnte da der Fehler liegen?
Hallo Johannes,
verwendet das Modul vielleicht eine andere Baudrate? Hast du eine Beschreibung von dem Modul?
Gruß
Daniel
Danke für die super Doku. Habe die letzten Tage mit einem herkömmlichen GPS-Modul gearbeitet und mich nur noch über das instabile mini-UART aufgeregt. Hätte ich früher gewusst, wie einfach sowas per USB ist…
Bei mir war es ein anderer Adapter (GPS/GLONASS U-blox7) und der aktuelle 3er raspi, den habe ich unter /dev/ttyACM0 gefunden. Alles andere wie du beschrieben hast. Genial einfach und einfach genial.
Danke für die Anleitung.
Leider ist das Programm äußerst instabil, denn das Programm bricht nach einiger Zeit von selbst ab.
Datum: 17/06/19
Uhrzeit: 19:15:29
Status: A
Qualitaet: 1
Anzahl Satelliten: 06
Koordinaten Breite: 48.835622
Koordinaten Laenge: 9.071919
Breitengrad: N 48�49’68.24“
Laengengrad: E 9�4’18.91“
Hoehe vom MSL: 363.9
Geschwindigkeit: 0.0 Knoten – 0.0 km/h
Traceback (most recent call last):
File „GPS.py“, line 146, in
UART.flushInput()
File „/usr/lib/python2.7/dist-packages/serial/serialutil.py“, line 566, in flushInput
self.reset_input_buffer()
File „/usr/lib/python2.7/dist-packages/serial/serialposix.py“, line 573, in reset_input_buffer
termios.tcflush(self.fd, termios.TCIFLUSH)
termios.error: (5, ‚Input/output error‘)
Woran kann das liegen?
Hallo Kurt,
hast du in der raspi-config die serielle Anmeldekonsole deaktiviert?
Gruß
Daniel