GPS ist eine tolle Sache, der freundliche Chinese hat mir einen GPS Empfänger verkauft, der viel mehr kann, als ich brauche.
Der Empfänger braucht nur eine Stromversorgung und gibt dann alle Sekunde ein Datenpaket aus, bestehend aus mehreren Zeilen Text, die immer mit $ beginnen und mit CRLF enden.
Hier der Wikipedia-Eintrag: de.wikipedia.org/wiki/NMEA_0183
Ich habe mir die GPRMC Daten rausgegriffen, da sie mir am einfachsten erscheinen für ein spätere Projekt eines Datenloggers.
Hier brauche ich neben der Position, also Länge und Breite, auch die Uhrzeit und das Datum.
Ziel ist es, später einen GPX-Datensatz als Pfad zu generieren, der in Google Maps lesbar ist.
Das ist das Stichwort zum eigentlichen Problem.
Während NMEA eine Breitenangabe in der Form einer 4-stelligen Breite in Grad mit angehängten Minuten und als Nachkomma noch die dezimalen Bruchteile der Minuten ausgibt, erwartet GPX die Breite 2 stellig mit dezimalem Nachkomma-Rest, was mir ehrlich gesagt, wirklich gefällt.
Beispiel Berliner Reichstag: Breite 52.518620 Länge 13.376187
https://www.google.de/maps/place/52°31'07.0"N+13°22'34.3"E/@52.51862,13.3739983,17z
In NMEA sieht das so aus: Breite 5231.070 und Länge 1322.343
Damit kann aber GPX nichts anfangen, also müssen die Daten zerlegt, berechnet und neu zusammengefügt werden.
Ich mache das mit der Split-Funktion, ist ja alles schön mit Komma getrennt.
Danach werden die 2 Stellen vor dem Punkt ausgelöst (das ist ja die Nachkommastelle in Minuten) und mit dem Wert nach dem Punkt vereinigt, um mit der Teilung durch 60 den dezimalen Anteil zu bekommen. Das ganze wird dann wieder zusammengefügt und als String ausgegeben.
( z.B. Sub Breiteerfassen)
Das funktioniert hier auf dem Schreibtisch super, nur ist das sehr mühsam und wie ich finde, sehr fehleranfällig. Wenn nur eine Stelle verschoben ist, passt es schon nicht mehr. Die ganze String/Long Orgie gefällt mir nicht wirklich.
Habt ihr da andere Ansätze oder geht das nicht anders?
Die Daten sollen später mal sparsam im internen EEprom oder kleinen externen EEprom/Flash abgelegt werden und bei Anforderung als GPX-File ausgegeben werden (das Zusammenbasteln steht auch noch auf der Agenda ;))
https://www.google.de/maps/place/52°31'07.0"N+13°22'34.3"E/@52.51862,13.3739983,17z
Alles anzeigen
Der Empfänger braucht nur eine Stromversorgung und gibt dann alle Sekunde ein Datenpaket aus, bestehend aus mehreren Zeilen Text, die immer mit $ beginnen und mit CRLF enden.
Hier der Wikipedia-Eintrag: de.wikipedia.org/wiki/NMEA_0183
Ich habe mir die GPRMC Daten rausgegriffen, da sie mir am einfachsten erscheinen für ein spätere Projekt eines Datenloggers.
Hier brauche ich neben der Position, also Länge und Breite, auch die Uhrzeit und das Datum.
Ziel ist es, später einen GPX-Datensatz als Pfad zu generieren, der in Google Maps lesbar ist.
Das ist das Stichwort zum eigentlichen Problem.
Während NMEA eine Breitenangabe in der Form einer 4-stelligen Breite in Grad mit angehängten Minuten und als Nachkomma noch die dezimalen Bruchteile der Minuten ausgibt, erwartet GPX die Breite 2 stellig mit dezimalem Nachkomma-Rest, was mir ehrlich gesagt, wirklich gefällt.
Beispiel Berliner Reichstag: Breite 52.518620 Länge 13.376187
https://www.google.de/maps/place/52°31'07.0"N+13°22'34.3"E/@52.51862,13.3739983,17z
In NMEA sieht das so aus: Breite 5231.070 und Länge 1322.343
Damit kann aber GPX nichts anfangen, also müssen die Daten zerlegt, berechnet und neu zusammengefügt werden.
Ich mache das mit der Split-Funktion, ist ja alles schön mit Komma getrennt.
Danach werden die 2 Stellen vor dem Punkt ausgelöst (das ist ja die Nachkommastelle in Minuten) und mit dem Wert nach dem Punkt vereinigt, um mit der Teilung durch 60 den dezimalen Anteil zu bekommen. Das ganze wird dann wieder zusammengefügt und als String ausgegeben.
( z.B. Sub Breiteerfassen)
Das funktioniert hier auf dem Schreibtisch super, nur ist das sehr mühsam und wie ich finde, sehr fehleranfällig. Wenn nur eine Stelle verschoben ist, passt es schon nicht mehr. Die ganze String/Long Orgie gefällt mir nicht wirklich.
Habt ihr da andere Ansätze oder geht das nicht anders?
Die Daten sollen später mal sparsam im internen EEprom oder kleinen externen EEprom/Flash abgelegt werden und bei Anforderung als GPX-File ausgegeben werden (das Zusammenbasteln steht auch noch auf der Agenda ;))
https://www.google.de/maps/place/52°31'07.0"N+13°22'34.3"E/@52.51862,13.3739983,17z
BASCOM-Quellcode: NMEA Auswertung
- $regfile = "m328pdef.dat"
- $crystal = 16000000
- $hwstack = 34
- $swstack = 32
- $framesize = 40
- $baud = 9600
- Ddrb.5 = 1
- Led Alias Portb.5
- Ddrb.4 = 1
- Led2 Alias Portb.4
- Taster Alias Pinc.0
- Portc.0 = 1
- Config Clock = User
- Config Date = Dmy , Separator = .
- On Urxc Serieller_irq
- Enable Urxc
- Enable Interrupts
- Dim Temp As Byte
- Dim Flag As Bit
- Dim Tastflag As Bit
- Dim Zaehler As Byte
- Dim Datensorte As Byte
- 'Datensorte 1 = GNRMC
- Dim Daten As String * 100
- Dim Kopierdaten As String * 100
- Dim Ar(14) As String * 12
- Dim Bcount As Byte
- Dim Temps As String * 12
- Dim Zeit As String * 8
- Dim Datum As String * 8
- Dim Gps_hour As Byte
- Dim Breite As String * 12
- Dim A As Long
- Dim B As Long
- Dim L As Long
- Dim Laenge As String * 12
- Dim Length As Byte
- Dim Lsyssec As Long
- Tastflag = 1
- Const Speichergroesse = 120
- Dim Br(speichergroesse) As Long
- Dim Le(speichergroesse) As Long
- Dim Dt(speichergroesse) As Long
- Dim Datenzaehler As Byte
- Do
- Bitwait Flag , Set
- If Taster = 0 Then Toggle Tastflag
- Led = 1
- Flag = 0
- Bcount = Split(kopierdaten , Ar(1) , ",")
- Gosub Zeiterfassen
- Gosub Datumerfassen
- Gosub Breiteerfassen
- Gosub Laengeerfassen
- If Tastflag = 1 Then
- Print Bcount ; " " ; Kopierdaten
- ' Print Ar(1) ; "," ; Ar(2) ; "," ; Ar(3) ; "," ; Ar(4) ; "," ; Ar(5) ; "," ; Ar(6) ; "," ; Ar(7) ; "," ; Ar(8) ; "," ; Ar(9) ; "," ; Ar(10) ; "," ; Ar(11)
- Print Zeit ; " " ; Breite ; " " ; Laenge ; " " ; Lsyssec ; " " ; Time(lsyssec) ; " " ; Date(lsyssec)
- Print B ; " " ; L
- End If
- If Ar(3) = "A" Then
- Incr Datenzaehler
- If Datenzaehler > Speichergroesse Then Datenzaehler = 1
- Br(datenzaehler) = B
- Le(datenzaehler) = L
- Dt(datenzaehler) = Lsyssec
- Else
- Led2 = 1
- End If
- Waitms 100
- ' Print "Warte auf Daten "
- Led = 0
- Led2 = 0
- Loop
- Laengeerfassen:
- Laenge = Mid(ar(6) , 4 , 2)
- Length = Len(ar(6))
- Length = Length - 6
- Temps = Mid(ar(6) , 7 , Length)
- Laenge = Laenge + Temps
- A = Val(laenge)
- Laenge = Left(ar(6) , 3)
- L = Val(laenge)
- Laenge = Laenge + "."
- A = A / 60
- L = L * 100000
- L = L + A
- Laenge = Laenge + Str(a)
- Return
- Breiteerfassen:
- Breite = Mid(ar(4) , 3 , 2)
- Length = Len(ar(4))
- Length = Length - 5
- Temps = Mid(ar(4) , 6 , Length)
- Breite = Breite + Temps
- A = Val(breite)
- Breite = Left(ar(4) , 2)
- B = Val(breite)
- Breite = Breite + "."
- A = A / 60
- B = B * 100000
- B = B + A
- Breite = Breite + Str(a)
- Return
- Zeiterfassen:
- Temps = Left(ar(2) , 2)
- Gps_hour = Val(temps)
- Gps_hour = Gps_hour + 2
- If Gps_hour > 23 Then
- Gps_hour = Gps_hour - 24
- End If
- Zeit = Str(gps_hour)
- Zeit = Zeit + ":"
- Temps = Mid(ar(2) , 3 , 2)
- Zeit = Zeit + Temps
- Zeit = Zeit + ":"
- Temps = Mid(ar(2) , 5 , 2)
- Zeit = Zeit + Temps
- Return
- Datumerfassen:
- Temps = Left(ar(10) , 2)
- Datum = Temps + ":"
- Temps = Mid(ar(10) , 3 , 2)
- Datum = Datum + Temps
- Datum = Datum + ":"
- Temps = Mid(ar(10) , 5 , 2)
- Datum = Datum + Temps
- Lsyssec = Syssec(zeit , Datum)
- Return
- Serieller_irq:
- Temp = Udr
- 'Print Chr(temp); 'Debug
- If Temp = 13 Then
- If Datensorte = 1 Then
- Kopierdaten = Daten
- Flag = 1
- End If
- 'umkopieren
- Daten = ""
- Zaehler = 1
- Datensorte = 0
- Else
- If Temp = 10 Then
- Else
- Daten = Daten + Chr(temp)
- If Daten = "$GNRMC" Then
- Datensorte = 1
- End If
- End If
- End If
- Return
- 'Beispiel $GPRMC,162614,A,5230.5900,N,01322.3900,E,10.0,90.0,131006,1.2,E,A*13