Kampis Elektroecke

GPS

Raspberry Pi

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.

Index Information
0 UTC Zeitstempel (MEZ – 1)
1 Latitude
2 Norden (N) oder Süden (S)
3 Longitude
4 Osten (E) oder Westen (W)
5 Qualität des GPS-Signals
6 Anzahl der Satelliten
7 Horizontale Verringerung der Genauigkeit (Meter)
8 Antennenposition über Meeresspiegel (Meter)
9 Einheit der Höhenangabe
10 Höhendifferenz zwischen Ellipsoid und Geoid
11 Einheit der Höhendifferenz
12 Alter der DGPS-Daten
13 Identifizierung der DGPS Referenzmessstelle
14 Checksumme
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. 

Index Information
0 Anzahl der gesendeten GSV-Datensätze
1 Index des Datensatzes
2 Anzahl sichtbarer Satelliten
3 ID des Satelliten
4 Elevation (-90° bis 90°)
5 Azimut in Richtung Norden (0° bis 359°)
6 Signal-Rausch-Abstand (SNR) in dB (0 bis 99)
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.

Zurück zu UART & USB

96 Kommentare

  1. 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

    1. 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

    2. 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

  2. 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

  3. 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

    1. 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

          1. 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

          2. 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

  4. 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

  5. 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

    1. 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

  6. 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!

    1. 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

      1. Hi,
        das Problem war wohl ein anderes, läuft jetzt. Ich poste hier gern mal einen Link, wenn das Projekt komplett dokumentiert ist.

        1. Hallo, genau das Vorhaben für das Boot mit LCD Display habe ich auch. Gibt es schon eine Doku zu dem Projekt? Gruß, Philip

  7. 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?

  8. 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

    1. 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

      1. …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?

        1. 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

          1. 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.

        2. …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

          1. 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

          2. Hey Boris,

            klasse! Das hört sich gut an :)
            Falls du Fragen haben solltest, kannst du dich natürlich immer melden :)

            Gruß
            Daniel

          3. 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.

          4. 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

          5. Grüss dich,

            warum ergibst du in deinen IF-Anweisung in der while-Schleife Recieve einen hex-Wert?

            alles Gute

    1. 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

      1. 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?

        1. 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

          1. 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.

          2. 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

          3. 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?

          4. 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

  9. 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

    1. 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

      1. 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

  10. 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

    1. 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

  11. 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.

    1. 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

      1. 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.

          1. 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

          2. 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

          3. 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.

          4. 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

          5. 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?

  12. 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

      1. 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

        1. 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

          1. 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

          2. 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

          3. 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.

          4. 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

    1. Eventuell fehlen dem Webserver einfach Zugriffsrechte auf die serielle Schnittstelle oder die Datei liegt außerhalb des Verzeichnisses /var/www.

      Gruß
      Daniel

  13. 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?

    1. 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

    2. 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

      1. 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 .. ?

        1. 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

          1. 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!

          2. 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

  14. 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

    1. Hallo Kasi,

      du kannst auch jedes andere Modul mit einer seriellen Schnittstelle nehmen (es muss natürlich schon die entsprechenden Protokolle ausgeben :))

      Gruß
      Daniel

  15. 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)

    1. 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

  16. 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?

    1. 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

      1. 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

          1. 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

  17. Hallo,
    die Seite, auf die der Link „Umrechnen von GPS Koordinaten“ unter „Zusätzliche Infos“ verweist, ist leider tot.

    Viele Grüße
    Guido

  18. 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?

  19. 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.

  20. 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?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert