GPS Tacho auf Arduino Basis

Hier kannst du deine Projekte vorstellen

Moderatoren: Tim Sasdrich, Sebi

GPS Tacho auf Arduino Basis

Beitragvon dussel07 » 27.09.2016, 03:07

So,
der erste Tag in DK ist rum und erste Erfolge sind zu verzeichnen!
Seit geraumer Zeit bastele ich für einen Freund an einem GPS Tacho. Als Grundlage dient das Programm und die Schaltung von www.kh-gps.de
Die ersten Erfolge erzielte ich schon vor einigen Monaten "Umwandlung eines Strings in normale dezimal Zahlen" - darauf basierend ist dann auch eine Anzeige der Himmelsrichtung geglückt.
Nach einer ausgiebigen Schaffenspause wird seit Gestern die Geschwindigkeit in Km/H angezeigt.
Die Kür, eine Geschwindigkeitsanzeige mit großen Zahlen auf einem 16x2 Dispay ist mir nach einiger Fleißarbeit heute gelungen - juhu :D

Zur Funktion -
Nach dem Einschalten erscheint ein Begrüßungsfenster das nach ermitteln der Uhrzeitdaten aus dem GPS String (Uhrzeit wird seltsamerweise immer als erstes übertragen) dann zum ersten Fenster wechselt. Im ersten Fenster werden die Uhrzeit und die Temperatur (wenn ein DS18B20 verbaut ist) angezeigt. Erscheint dann hinter der Uhrzeit ein Unterstrich kann mit einem Taster zwischen verschiedenen Anzeigefenstern umgeschaltet werden. Hier kann zwischen den Standortdaten, dem Kurs in Grad (nur in Bewegung) der Geschwindigkeit in Knoten, der Geschwindigkeit in Kmh zuzüglich dem Kurs in Himmelsrichtung (Anzeige zB. "NNW" oder "OSO") und der Anzeige der Geschwindigkeit mit großen Zahlen über zwei Zeilen, gewählt werden.
Über Schalter oder Jumper kann die Baudrate der GPSMaus und die Umstellung von Sommerzeit auf Winterzeit vorgenommen werden.
Was nun noch wünschenswert währe: Ein Kilometerzähler der sich zurück setzen lässt - naja, nächstes Jahr ist auch noch ein Jahr - -

Wer jetzt anmerkt: Das macht mein Billighandy vom Discounter mit links - der hat natürlich recht!! Aber es gibt Menschen die haben kein Handy, und wollen auch keins??? Merkwürdig, oder? Für einen dieser Mitmenschen welcher sich auf Binnenwasserstrassen rumtreibt soll dieses Gebilde werden.

Hier das Bascom Programm:
Spoiler: show
Code: Alles auswählen
'GPS Tacho mit großen Zahlen für die Geschwindigkeit
'auf Grundlage von GPS_Ardu_4  http://www.kh-gps.de   Version für Arduino mit ATMEGA328p
'Display 16x2
'GPS Modul an RX und TX
'Tempsensor DS18B20 an Pin C.3
'Jumper zum umstellen der Baudrate an Pin C.1
'Jumper zum umstellen von Winterzeit auf Sommerzeit an Pin C.0
'Taster gegen Gnd an int.0 (Pin D.2) zum einstellen des Anzeigefensters
'LCD Beleuchtung an Pin B.2




$regfile = "m328pdef.DAT"
$crystal = 16000000
$baud = 4800
$hwstack = 64
$swstack = 128
$framesize = 64

Config Lcdpin = Pin , Db7 = Portd.7 , Db6 = Portd.6 , Db5 = Portd.5 , Db4 = Portd.4 , Rs = Portb.0 , E = Portb.1
Config Lcd = 16 * 2
Cursor Off

'----------------------------------------------------------
'Definition der zusätzlichen Charakter für große Zahlen auf dem 16*2 Display
' LCD-Zeichen Chr(0)
Deflcdchar 0 , 30 , 30 , 30 , 30 , 30 , 30 , 30 , 30
' LCD-Zeichen Chr(1)
Deflcdchar 1 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15
' LCD-Zeichen Chr(2)
Deflcdchar 2 , 31 , 31 , 32 , 32 , 32 , 32 , 31 , 31
' LCD-Zeichen Chr(3)
Deflcdchar 3 , 31 , 31 , 32 , 32 , 32 , 32 , 32 , 32
' LCD-Zeichen Chr(4)
Deflcdchar 4 , 31 , 31 , 32 , 32 , 32 , 32 , 32 , 32        '
' LCD-Zeichen Chr(5)
Deflcdchar 5 , 32 , 32 , 32 , 32 , 32 , 32 , 30 , 30
' LCD-Zeichen Chr(6)
Deflcdchar 6 , 32 , 32 , 32 , 32 , 32 , 32 , 31 , 31
' LCD-Zeichen Chr(7)
Deflcdchar 7 , 32 , 32 , 14 , 14 , 14 , 14 , 32 , 32
Cls
'----------------------------------------------------------

Config 1wire = Portc.3                                      'Pin für Temperatursensor DS18B20

Config Serialin = Buffered , Size = 100

Declare Sub Wait_for_string(byval S As String)
Declare Function Read_string() As String
Declare Sub Buttonscan
Declare Sub Maidenhead
Declare Sub Lcdbig

Dim T_in As Word
Dim T_out As Single
Dim Ar(2) As Byte

Dim Av As String * 10
Dim Lat_ As String * 10
Dim Ns As String * 2
Dim Lon As String * 10
Dim Ew As String * 2
Dim Spd As String * 6
Dim Crs As String * 6
Dim Leng As Byte
Dim Utc As String * 10
Dim Utc1 As String * 2
Dim Utc2 As String * 2
Dim Utc3 As String * 2
Dim Utc4 As String * 8
Dim Maid_out As String * 8

Dim Astep As Byte

Dim Val_hr As Byte
Dim Msz_hr As String * 2

Dim Richtung As Single
Dim Himmelsrichtung As String * 4
Dim Geschwindigkeit As Single
Dim Geschwindigkeit_s As String * 10
Dim Geschwindigkeit_z As String * 5
Dim Geschwindigkeit_e As Word

Dim Lcdbigspalte As Byte
Dim Lcdbigzahl As Byte
Dim A As Byte
Dim B As Byte
Dim Stelle_einer As Byte
Dim Stelle_zehner As Byte
Dim Stelle_hunderter As Byte


Umschalten_baudrate Alias Pinc.1
Config Umschalten_baudrate = Input
Portc.1 = 1

Umschalten_winterzeit Alias Pinc.0
Config Umschalten_winterzeit = Input
Portc.0 = 1

Beleuchtung Alias Portb.2
Config Portb.2 = Output

Beleuchtung = 1

Unterbrechung Alias Pind.2
Config Unterbrechung = Input
Portd.2 = 1

Astep = 0                                                   'definierts Startfenster "Uhrzeit"

'------------------------------------------------------
'Interrupt für Taster an D.2 (Umschaltung Anzeigefenster) einrichten
On Int0 On_int0
Config Int0 = Falling                                       'fallende Flanke
Enable Int0                                                 'INT0 einschalten
Enable Interrupts

If Umschalten_baudrate = 0 Then Baud = 9600

'Startinfo
'------------------------------------------------------
Cls
Locate 1 , 1
Lcd "GPSTacho V.4 auf"
Locate 2 , 1
Lcd "Grundlage KH-GPS"
Wait 4


'Hauptprogrammschleife
'-----------------------------------------------------
Do

   'GPS Empfänger auslesen
   '-----------------------------------------------------
   Call Wait_for_string( "$GPRMC,")                         ' Warte auf $GPRMC

   Utc = Read_string()
   Leng = Len(utc) - 1
   Utc = Left(utc , Leng)
   Utc = Left(utc , 6)

   Av = Read_string()
   Leng = Len(av) - 1
   Av = Left(av , Leng)

   Lat_ = Read_string()
   Leng = Len(lat_) - 1
   Lat_ = Left(lat_ , Leng)

   Ns = Read_string()
   Leng = Len(ns) - 1
   Ns = Left(ns , Leng)

   Lon = Read_string()
   Leng = Len(lon) - 1
   Lon = Left(lon , Leng)

   Ew = Read_string()
   Leng = Len(ew) - 1
   Ew = Left(ew , Leng)

   Spd = Read_string()
   Leng = Len(spd) - 1
   Spd = Left(spd , Leng)

   Crs = Read_string()
   Leng = Len(crs) - 1
   Crs = Left(crs , Leng)

   Utc1 = Left(utc , 2)
   Utc2 = Mid(utc , 3 , 2)
   Utc3 = Mid(utc , 5 , 2)

   'Auslesen des Tempsensor DS18B20
   '------------------------------------------------
   1wreset
   1wwrite &HCC
   1wwrite &H44
   Waitms 200

   1wreset
   1wwrite &HCC
   1wwrite &HBE
   Ar(1) = 1wread(2)
   Waitms 500

   T_in = Ar(2)
   T_in = T_in * 256
   T_in = T_in + Ar(1)

   T_out = T_in / 16
   If T_in > 4095 Then T_out = T_out - 4096

   'locator calculation
   '---------------------------------------------------
   Gosub Maidenhead

   'time calculation for Central Europe
   '---------------------------------------------------------------
   Val_hr = Val(utc1)
   If Umschalten_winterzeit = 0 Then Val_hr = Val_hr + 2 Else Val_hr = Val_hr + 1
   If Val_hr = 24 Then Val_hr = 0
   Msz_hr = Str(val_hr)
   If Len(msz_hr) = 1 Then Msz_hr = "0" + Msz_hr
   If Av = "A" Then Utc4 = Msz_hr + Utc2 + Utc3
   If Av <> "A" Then Utc4 = Msz_hr + ":" + Utc2 + ":" + Utc3

   'Fensterauswahl
   '---------------------------------------------------
   If Astep = 0 Then Goto Fenster1
   If Astep = 1 Then Goto Fenster2
   If Astep = 2 Then Goto Fenster3
   If Astep = 3 Then Goto Fenster4
   If Astep = 4 Then Goto Fenster5
   If Astep = 5 Then Goto Fenster6

   'LCDAnzeige Fenster
   '--------------------------------------------------
   Fenster1:
      Cls
      Locate 1 , 9
      If Av = "A" Then Lcd "_"
      If Av <> "A" Then Lcd " "

      Locate 1 , 1
      Lcd Msz_hr ; ":" ; Utc2 ; ":" ; Utc3

      Locate 1 , 12
      If T_out < 0 Then Locate 1 , 11
      Lcd Fusing(t_out , "#.#") ; Chr(223)
      Goto Fin

      '---------------------------------------------------
   Fenster2:
      Cls
      Gosub Umrechnung_kmh
      If Av = "A" Then Gosub Zuordnung
      If Av <> "A" Then Lcd "Speed: no data"
      Goto Fin

      '--------------------------------------------------
   Fenster3:
      Cls
      Lat_ = Left(lat_ , 7)
      If Lat_ = "," Then Lat_ = " "
      Lon = Left(lon , 8)
      If Lon = "," Then Lon = " "

      Locate 1 , 2
      If Av = "A" Then Lcd Lat_ ; Ns

      If Av = "A" Then Locate 1 , 11
      If Av <> "A" Then Locate 1 , 5
      Lcd Utc4

      Locate 2 , 1
      If Av = "A" Then Lcd Lon ; Ew
      If Av <> "A" Then Lcd "Keine GPS Daten"

      Locate 2 , 11
      If Av = "A" Then Lcd Maid_out
      Goto Fin

      '--------------------------------------------------
   Fenster4:
      Lat_ = Left(lat_ , 8)
      Lon = Left(lon , 9)

      Cls
      Locate 1 , 1
      If Av = "A" Then Lcd "LAT:  " ; Lat_ ; " " ; Ns
      If Av <> "A" Then Lcd "LAT: No Data"

      Locate 2 , 1
      If Av = "A" Then Lcd "LON: " ; Lon ; " " ; Ew
      If Av <> "A" Then Lcd "LON: no data"
      Goto Fin

      '---------------------------------------------------
   Fenster5:
      Cls
      Locate 1 , 1
      If Av = "A" Then Lcd "SPD: " ; Spd ; " Knts."
      If Av <> "A" Then Lcd "SPD: no data"

      Locate 2 , 1
      If Av = "A" Then Lcd "CRS: " ; Crs ; " Degs."
      If Av <> "A" Then Lcd "CRS: no data"
      Goto Fin

      '---------------------------------------------------
   Fenster6:
      Cls
      Gosub Himmelsrichtung_
      Gosub Umrechnung_kmh
      Cls
      Locate 1 , 1
      If Av = "A" Then Lcd "Speed: " ; Geschwindigkeit_s ; " Kmh"
      If Av <> "A" Then Lcd "Speed: no data"

      Locate 2 , 1
      If Av = "A" Then Lcd "Kurs  : " ; Himmelsrichtung
      If Av <> "A" Then Lcd "Kurs: no data"

      '-----------------------------------------------------
   Fin:
      Lat_ = ""
      Lon = ""
      Ns = ""
      Ew = ""
      Maid_out = "      "
Loop
'-------------------------------------------------------

End




'Unterprogramme und Funktionen
'------------------------------------------------------
Sub Wait_for_string(byval S As String) As String
   Local Ii As Byte
   Local Cc As Byte
   Ii = 1
   M1:
      Cc = Waitkey()
      If Cc <> Mid(s , Ii , 1) Then
         Goto M1
      Else
         Incr Ii
         If Ii > Len(s) Then Goto M2
         Goto M1
      End If
   M2:
End Sub


'------------------------------------------------------
Function Read_string() As String
   Local Cc As Byte
   Local Ss As String * 10
   Ss = ""
   Do
      Cc = Waitkey()
      Ss = Ss + Chr(cc)
   Loop Until Cc = ","
   Read_string = Left(ss , 10)
End Function

'------------------------------------------------------
Sub Maidenhead
   'In-Variable: lat, lon, ns, ew as string
   'Out-Variable: maid_out as string
   Local A2x As String * 30
   Local Z2n As String * 25
   Local I As String * 10
   Local Dx As Integer
   Local Dy As Integer
   Local Xxx As Integer
   Local Yyy As Integer
   Local Dxx As Integer
   Local Dyy As Integer
   Local Str1 As String * 1
   Local Str2 As String * 1
   Local Str3 As String * 1
   Local Str4 As String * 1
   Local Str5 As String * 1
   Local Str6 As String * 1
   Local Xxxx As Single
   Local Yyyy As Single

   Local Td1 As String * 10
   Local Tl1 As String * 10
   Local Gd1 As String * 10
   Local Gl1 As String * 10

   Local Td As Single
   Local Tl As Single

   Local Gd As Single
   Local Gl As Single

   Local Yy As Single
   Local Xx As Single

   Td1 = Mid(lat_ , 1 , 2)
   Tl1 = Mid(lat_ , 3 , 5)
   Gd1 = Mid(lon , 1 , 3)
   Gl1 = Mid(lon , 4 , 5)

   Td = Val(td1)
   Tl = Val(tl1)
   Gd = Val(gd1)
   Gl = Val(gl1)

   Tl = Tl / 60
   Yy = Td + Tl

   Gl = Gl / 60
   Xx = Gd + Gl

   If Ns = "S" Then Td = -td
   If Ew = "W" Then Gd = -gd

   A2x = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
   Z2n = "01234567890123456789"

   If Xx < -179.99 Or Xx > 179.99 Then Goto Finsub
   If Yy < -89.99 Or Yy > 89.99 Then Goto Finsub

   Xx = Xx + 180
   Yy = Yy + 90

   Xxx = Xx
   Yyy = Yy

   Dx = Xxx / 20
   Dy = Yyy / 10

   Dxx = Dx + 1
   Dyy = Dy + 1

   Str1 = Mid(a2x , Dxx , 1)
   Str2 = Mid(a2x , Dyy , 1)

   Xxx = Dx * 20
   Yyy = Dy * 10

   Xx = Xx - Xxx
   Yy = Yy - Yyy

   Xxxx = Xx * 100
   Yyyy = Yy * 100

   Dx = Xxxx / 200
   Dy = Yyyy / 100

   Dxx = Dx + 1
   Dyy = Dy + 1

   Str3 = Mid(z2n , Dxx , 1)
   Str4 = Mid(z2n , Dyy , 1)

   Dxx = Dx * 2
   Dyy = Dy * 1

   Xx = Xx - Dxx
   Yy = Yy - Dyy

   Xxxx = Xx * 1000
   Yyyy = Yy * 1000

   Xxx = Xxxx
   Yyy = Yyyy

   Xxxx = Xxx / 83.333333
   Yyyy = Yyy / 41.666666

   Dx = Xxxx
   Dy = Yyyy

   Dxx = Dx + 1
   Dyy = Dy + 1

   Str5 = Mid(a2x , Dxx , 1)
   Str6 = Mid(a2x , Dyy , 1)

   Maid_out = Str1 + Str2
   Maid_out = Maid_out + Str3
   Maid_out = Maid_out + Str4
   Maid_out = Maid_out + Str5
   Maid_out = Maid_out + Str6
   Finsub:
End Sub


'LCDBig: Funktion zum Schreiben der grossen Zahlen auf dem LCD
'----------------------------------------------------------
Sub Lcdbig
   ' Zeile 1
   Locate 1 , Lcdbigspalte
   Select Case Lcdbigzahl
      Case 0 : Lcd Chr(1) ; Chr(3) ; Chr(0)
      Case 1 : Lcd Chr(32) ; Chr(0) ; Chr(32)
      Case 2 : Lcd Chr(3) ; Chr(2) ; Chr(0)
      Case 3 : Lcd Chr(3) ; Chr(2) ; Chr(0)
      Case 4 : Lcd Chr(1) ; Chr(6) ; Chr(0)
      Case 5 : Lcd Chr(1) ; Chr(2) ; Chr(4)
      Case 6 : Lcd Chr(1) ; Chr(2) ; Chr(4)
      Case 7 : Lcd Chr(3) ; Chr(2) ; Chr(0)
      Case 8 : Lcd Chr(1) ; Chr(2) ; Chr(0)
      Case 9 : Lcd Chr(1) ; Chr(2) ; Chr(0)
   End Select

   ' Zeile 2
   Locate 2 , Lcdbigspalte
   Select Case Lcdbigzahl
      Case 0 : Lcd Chr(1) ; Chr(6) ; Chr(0)
      Case 1 : Lcd Chr(32) ; Chr(0) ; Chr(32)
      Case 2 : Lcd Chr(1) ; Chr(2) ; Chr(5)
      Case 3 : Lcd Chr(6) ; Chr(2) ; Chr(0)
      Case 4 : Lcd Chr(32) ; Chr(32) ; Chr(0)
      Case 5 : Lcd Chr(6) ; Chr(2) ; Chr(0)
      Case 6 : Lcd Chr(1) ; Chr(2) ; Chr(0)
      Case 7 : Lcd Chr(32) ; Chr(1) ; Chr(32)
      Case 8 : Lcd Chr(1) ; Chr(2) ; Chr(0)
      Case 9 : Lcd Chr(5) ; Chr(6) ; Chr(0)
   End Select
End Sub


'------------------------------------------------------
Himmelsrichtung_:
   Richtung = Val(crs)
   Select Case Richtung
      Case 0 To 11:
         Himmelsrichtung = "N"
      Case 12 To 34:
         Himmelsrichtung = "NNO"
      Case 35 To 56:
         Himmelsrichtung = "NO"
      Case 57 To 79:
         Himmelsrichtung = "ONO"
      Case 80 To 101:
         Himmelsrichtung = "O"
      Case 102 To 124:
         Himmelsrichtung = "OSO"
      Case 125 To 146:
         Himmelsrichtung = "SO"
      Case 147 To 169:
         Himmelsrichtung = "SSO"
      Case 170 To 191:
         Himmelsrichtung = "S"
      Case 192 To 214:
         Himmelsrichtung = "SSW"
      Case 215 To 236:
         Himmelsrichtung = "SW"
      Case 237 To 259:
         Himmelsrichtung = "WSW"
      Case 260 To 281:
         Himmelsrichtung = "W"
      Case 282 To 304:
         Himmelsrichtung = "WNW"
      Case 305 To 326:
         Himmelsrichtung = "NW"
      Case 327 To 345:
         Himmelsrichtung = "NNW"
      Case 346 To 359:
         Himmelsrichtung = "N"
   End Select
Return


'------------------------------------------------------
Umrechnung_kmh:
   Geschwindigkeit = Val(spd)
   Geschwindigkeit = Geschwindigkeit * 1852
   Geschwindigkeit = Geschwindigkeit / 1000
   If Geschwindigkeit < 0.5 Then
      Geschwindigkeit = 0
   End If
   Geschwindigkeit_s = Str(geschwindigkeit)
   Geschwindigkeit_s = Fusing(geschwindigkeit , "#.#")
   Geschwindigkeit_z = Fusing(geschwindigkeit , "#.")
   Geschwindigkeit_e = Val(geschwindigkeit_z)

Return


'------------------------------------------------------
Zuordnung:
   B = Geschwindigkeit_e
   Stelle_einer = B Mod 10
   B = B - Stelle_einer
   B = B / 10
   Stelle_zehner = B Mod 10
   B = B - Stelle_zehner
   B = B / 10
   Stelle_hunderter = B Mod 10
   Lcdbigspalte = 1 : Lcdbigzahl = Stelle_hunderter : Lcdbig
   Lcdbigspalte = 4 : Lcdbigzahl = Stelle_zehner : Lcdbig
   Lcdbigspalte = 7 : Lcdbigzahl = Stelle_einer : Lcdbig
   Locate 2 , 12 : Lcd "KmH"
Return


'------------------------------------------------------
On_int0:
   Astep = Astep + 1
   If Astep > 5 Then Astep = 0
   Waitms 500
Return


Ein paar Bilder folgen Morgen.
Ja, - ich bin Zwilling
Benutzeravatar
dussel07
 
Beiträge: 1606
Registriert: 30.04.2009, 21:04
Wohnort: Goslar

Re: GPS Tacho auf Arduino Basis

Beitragvon Tim Sasdrich » 27.09.2016, 04:56

Code: Alles auswählen
Utc = Read_string()
Leng = Len(utc) - 1
Utc = Left(utc , Leng)
Utc = Left(utc , 6)
Was bewirken hier Zeile 2 und 3? Nichts?

Code: Alles auswählen
X = Read_string()
Leng = Len(X) - 1
X = Left(X , Leng)
Sowas hast du recht oft verwendet, sofern ich das verstehe entfernst du ein Komma. Wäre es da nicht sinnvoller, die Empfangsroutine anzupassen? Z.B. so:
Code: Alles auswählen
Function Read_string() As String
   Local Cc As Byte
   Local Ss As String * 10
   Ss = ""
   Cc = Waitkey()
   Do
      Ss = Ss + Chr(cc)
      Cc = Waitkey()
   Loop Until Cc = ","
   Read_string = Left(ss , 10)
End Function


Code: Alles auswählen
If Umschalten_winterzeit = 0 Then Val_hr = Val_hr + 2 Else Val_hr = Val_hr + 1
If Val_hr = 24 Then Val_hr = 0
Ob das so funktioniert? 23 Uhr + 2 h gibt 25 Uhr. Wohl besser:
Code: Alles auswählen
If Val_hr >= 24 Then Val_hr = Val_hr - 24
Wenn du auch noch das Datum verwendest, könntest du den Wochentag berechnen mit Target = DayOfWeek(strDate) und beides anzeigen (Z.B. Fenster 1, Zeile 2). Zudem lässt sich dann auch recht einfach berechnen, ob Sommer oder Winterzeit ist. Der Schalter ließe sich dann z.B. für die Umstellug zwischen deutscher und UTC-Zeit nutzen. Oder du berechnest aus der Position noch die Zeitzone, dann vielleicht Umschaltung zwischen Deutscher und Ortszeit. :mrgreen:

Code: Alles auswählen
Himmelsrichtung_:
   Richtung = Val(crs)
   Select Case Richtung
      Case 0 To 11:
         Himmelsrichtung = "N"
      Case 12 To 34:
         Himmelsrichtung = "NNO"
      Case 35 To 56:
         Himmelsrichtung = "NO"
      Case 57 To 79:
         Himmelsrichtung = "ONO"
      Case 80 To 101:
         Himmelsrichtung = "O"
      Case 102 To 124:
         Himmelsrichtung = "OSO"
      Case 125 To 146:
         Himmelsrichtung = "SO"
      Case 147 To 169:
         Himmelsrichtung = "SSO"
      Case 170 To 191:
         Himmelsrichtung = "S"
      Case 192 To 214:
         Himmelsrichtung = "SSW"
      Case 215 To 236:
         Himmelsrichtung = "SW"
      Case 237 To 259:
         Himmelsrichtung = "WSW"
      Case 260 To 281:
         Himmelsrichtung = "W"
      Case 282 To 304:
         Himmelsrichtung = "WNW"
      Case 305 To 326:
         Himmelsrichtung = "NW"
      Case 327 To 345:
         Himmelsrichtung = "NNW"
      Case 346 To 359:
         Himmelsrichtung = "N"
   End Select
   Lookup
Return
Funktioniert wohl, aber könnte evtl. auch mit bisschen Mathe und dann Himmelsrichtung = Lookupstr(richtungsnr , Richtungen) funktionieren. Ich weiß nicht, was schneller und effektiver ist.

Code: Alles auswählen
On_int0:
   Astep = Astep + 1
   If Astep > 5 Then Astep = 0
   Waitms 500
Return
500 ms ist aber eine große Entprellung.

Die Temperatur würde ich in "°C" angeben, nicht nur in "°". Und auch den Rest in der Standard-Einheit: "km/h", "kn", "°" oder "deg"

Und in z.B. Fenster 4 stehen die Positionswerte zwar schön untereinander, aber nicht weltweit. Nicht überall hat Lat eine und Lon 2 Stellen vor dem Komma. Solltest also aufpassen, dass es zumindest für den Einsatzbereich passt. Evtl. hilft auch der Befehl target = FORMAT(source, "mask").


Sollen nur paar Tipps sein, was du umsetzt, bleibt natürlich dir überlassen. Wie auch immer, ich bin natürlich gespannt auf die Bilder.
"Der Kluge lernt aus allem und von jedem, der Normale aus seinen Erfahrungen und der Dumme weiß alles besser." - Sokrates (470 - 399 v. Chr.), griechischer Philosoph
Tim Sasdrich
 
Beiträge: 2922
Registriert: 07.01.2009, 14:15
Wohnort: Villingen-Schwenningen

Re: GPS Tacho auf Arduino Basis

Beitragvon dussel07 » 27.09.2016, 17:20

Hallo Tim
ich habe mal ein paar Anregungen Umgesetzt.
Die Endprellung lässt sich leider nicht kleiner wählen ?? Wenn ich einen Wert unter 500ms eingebe überspringt das Programm reglmäßig ein Fenster.
Eine Datumsanzeige und ein Antennensymbol habe ich hinzu gefügt.
Wer mag:
Spoiler: show
Code: Alles auswählen
'GPS Tacho mit großen Zahlen für die Geschwindigkeit
'auf Grundlage von GPS_Ardu_4  http://www.kh-gps.de   Version für Arduino mit ATMEGA328p
'Display 16x2
'GPS Modul an RX und TX
'Tempsensor DS18B20 an Pin C.3
'Jumper zum umstellen der Baudrate an Pin C.1
'Jumper zum umstellen von Winterzeit auf Sommerzeit an Pin C.0
'Taster gegen Gnd an int.0 (Pin D.2) zum einstellen des Anzeigefensters
'LCD Beleuchtung an Pin B.2




$regfile = "m328pdef.DAT"
$crystal = 16000000
$baud = 4800
$hwstack = 64
$swstack = 128
$framesize = 64

Config Lcdpin = Pin , Db7 = Portd.7 , Db6 = Portd.6 , Db5 = Portd.5 , Db4 = Portd.4 , Rs = Portb.0 , E = Portb.1
Config Lcd = 16 * 2
Cursor Off


'----------------------------------------------------------

Config 1wire = Portc.3                                      'Pin für Temperatursensor DS18B20

Config Serialin = Buffered , Size = 100

Declare Sub Wait_for_string(byval S As String)
Declare Function Read_string() As String
Declare Sub Buttonscan
Declare Sub Maidenhead
Declare Sub Lcdbig

Dim Var_ant As Bit
Dim Var_big As Bit

Dim T_in As Word
Dim T_out As Single
Dim Ar(2) As Byte

Dim Av As String * 10
Dim Lat_ As String * 10
Dim Ns As String * 2
Dim Lon As String * 10
Dim Ew As String * 2
Dim Spd As String * 6
Dim Crs As String * 6
Dim Leng As Byte
Dim Utc As String * 10
Dim Utc1 As String * 2
Dim Utc2 As String * 2
Dim Utc3 As String * 2
Dim Utc4 As String * 8
Dim Maid_out As String * 8
Dim Tag As String * 2
Dim Monat As String * 2
Dim Jahr As String * 2
Dim Dat As String * 8

Dim Astep As Byte

Dim Val_hr As Byte
Dim Msz_hr As String * 2

Dim Richtung As Single
Dim Himmelsrichtung As String * 4
Dim Geschwindigkeit As Single
Dim Geschwindigkeit_s As String * 10
Dim Geschwindigkeit_z As String * 5
Dim Geschwindigkeit_e As Word

Dim Lcdbigspalte As Byte
Dim Lcdbigzahl As Byte
Dim A As Byte
Dim B As Byte
Dim Stelle_einer As Byte
Dim Stelle_zehner As Byte
Dim Stelle_hunderter As Byte


Umschalten_baudrate Alias Pinc.1
Config Umschalten_baudrate = Input
Portc.1 = 1

Umschalten_winterzeit Alias Pinc.0
Config Umschalten_winterzeit = Input
Portc.0 = 1

Beleuchtung Alias Portb.2
Config Portb.2 = Output

Beleuchtung = 1

Unterbrechung Alias Pind.2
Config Unterbrechung = Input
Portd.2 = 1

Astep = 0                                                   'definierts Startfenster "Uhrzeit"

'------------------------------------------------------
'Interrupt für Taster an D.2 (Umschaltung Anzeigefenster) einrichten
On Int0 On_int0
Config Int0 = Falling                                       'fallende Flanke
Enable Int0                                                 'INT0 einschalten
Enable Interrupts

If Umschalten_baudrate = 0 Then Baud = 9600

'Startinfo
'------------------------------------------------------
Cls
Locate 1 , 1
Lcd "GPSTacho V.4 auf"
Locate 2 , 1
Lcd "Grundlage KH-GPS"
Wait 4


'Hauptprogrammschleife
'-----------------------------------------------------
Do
   If Astep = 0 Then
      If Var_ant = 0 Then Gosub Character_ant
   End If
   If Astep = 1 Then
      If Var_big = 0 Then Gosub Character_big
   End If
   'GPS Empfänger auslesen
   '-----------------------------------------------------
   Call Wait_for_string( "$GPRMC,")                         ' Warte auf $GPRMC

   Utc = Read_string()
   Leng = Len(utc) - 1
   Utc = Left(utc , Leng)
   Utc = Left(utc , 6)

   Av = Read_string()
   Leng = Len(av) - 1
   Av = Left(av , Leng)

   Lat_ = Read_string()
   Leng = Len(lat_) - 1
   Lat_ = Left(lat_ , Leng)

   Ns = Read_string()
   Leng = Len(ns) - 1
   Ns = Left(ns , Leng)

   Lon = Read_string()
   Leng = Len(lon) - 1
   Lon = Left(lon , Leng)

   Ew = Read_string()
   Leng = Len(ew) - 1
   Ew = Left(ew , Leng)

   Spd = Read_string()
   Leng = Len(spd) - 1
   Spd = Left(spd , Leng)

   Crs = Read_string()
   Leng = Len(crs) - 1
   Crs = Left(crs , Leng)

   Dat = Read_string()
   Leng = Len(dat) - 1
   Dat = Left(dat , Leng)

   Utc1 = Left(utc , 2)
   Utc2 = Mid(utc , 3 , 2)
   Utc3 = Mid(utc , 5 , 2)

   Tag = Left(dat , 2)
   Monat = Mid(dat , 3 , 2)
   Jahr = Mid(dat , 5 , 2)

   'Auslesen des Tempsensor DS18B20
   '------------------------------------------------
   1wreset
   1wwrite &HCC
   1wwrite &H44
   Waitms 200

   1wreset
   1wwrite &HCC
   1wwrite &HBE
   Ar(1) = 1wread(2)
   Waitms 500

   T_in = Ar(2)
   T_in = T_in * 256
   T_in = T_in + Ar(1)

   T_out = T_in / 16
   If T_in > 4095 Then T_out = T_out - 4096

   'time calculation for Central Europe
   '---------------------------------------------------------------
   Val_hr = Val(utc1)
   If Umschalten_winterzeit = 0 Then Val_hr = Val_hr + 2 Else Val_hr = Val_hr + 1
   If Val_hr = 24 Then Val_hr = 0
   Msz_hr = Str(val_hr)
   If Len(msz_hr) = 1 Then Msz_hr = "0" + Msz_hr
   If Av = "A" Then Utc4 = Msz_hr + Utc2 + Utc3
   If Av <> "A" Then Utc4 = Msz_hr + ":" + Utc2 + ":" + Utc3

   'Fensterauswahl
   '---------------------------------------------------
   If Astep = 0 Then Goto Fenster1
   If Astep = 1 Then Goto Fenster2
   If Astep = 2 Then Goto Fenster3
   If Astep = 3 Then Goto Fenster4
   If Astep = 4 Then Goto Fenster5
   If Astep = 5 Then Goto Fenster6

   'LCDAnzeige Fenster
   '--------------------------------------------------
   Fenster1:
      Cls
      Locate 1 , 8
      If Av = "A" Then Lcd Chr(0)
      If Av <> "A" Then Lcd Chr(1)

      Locate 1 , 1
      Lcd Msz_hr ; ":" ; Utc2

      Locate 1 , 11
      If T_out < 0 Then Locate 1 , 11
      Lcd Fusing(t_out , "#.#") ; Chr(223) ; "C"

      Locate 2 , 1
      If Av = "A" Then Lcd Tag ; "." ; Monat ; "." ; Jahr
      If Av <> "A" Then Lcd "noch keine Daten"
      Goto Fin

      '---------------------------------------------------
   Fenster2:
      Cls
      Gosub Umrechnung_kmh
      If Av = "A" Then Gosub Zuordnung
      If Av <> "A" Then Lcd "Speed: no data"
      Goto Fin

      '--------------------------------------------------
   Fenster3:
      Gosub Maidenhead
      Cls
      Lat_ = Left(lat_ , 7)
      If Lat_ = "," Then Lat_ = " "
      Lon = Left(lon , 8)
      If Lon = "," Then Lon = " "

      Locate 1 , 2
      If Av = "A" Then Lcd Lat_ ; Ns

      If Av = "A" Then Locate 1 , 11
      If Av <> "A" Then Locate 1 , 5
      Lcd Utc4

      Locate 2 , 1
      If Av = "A" Then Lcd Lon ; Ew
      If Av <> "A" Then Lcd "Keine GPS Daten"

      Locate 2 , 11
      If Av = "A" Then Lcd Maid_out
      Goto Fin

      '--------------------------------------------------
   Fenster4:
      Lat_ = Left(lat_ , 8)
      Lon = Left(lon , 9)

      Cls
      Locate 1 , 1
      If Av = "A" Then Lcd "LAT:  " ; Lat_ ; " " ; Ns
      If Av <> "A" Then Lcd "LAT: No Data"

      Locate 2 , 1
      If Av = "A" Then Lcd "LON: " ; Lon ; " " ; Ew
      If Av <> "A" Then Lcd "LON: no data"
      Goto Fin

      '---------------------------------------------------
   Fenster5:
      Cls
      Locate 1 , 1
      If Av = "A" Then Lcd "SPD: " ; Spd ; " Kn."
      If Av <> "A" Then Lcd "SPD: no data"

      Locate 2 , 1
      If Av = "A" Then Lcd "CRS: " ; Crs ; " Deg."
      If Av <> "A" Then Lcd "CRS: no data"
      Goto Fin

      '---------------------------------------------------
   Fenster6:
      Cls
      Gosub Himmelsrichtung_
      Gosub Umrechnung_kmh
      Cls
      Locate 1 , 1
      If Av = "A" Then Lcd "Speed: " ; Geschwindigkeit_s ; " Km" ; Chr(47) ; "h"
      If Av <> "A" Then Lcd "Speed: no data"

      Locate 2 , 1
      If Av = "A" Then Lcd "Kurs  : " ; Himmelsrichtung
      If Av <> "A" Then Lcd "Kurs: no data"

      '-----------------------------------------------------
   Fin:
      Lat_ = ""
      Lon = ""
      Ns = ""
      Ew = ""
      Maid_out = "      "
Loop
'-------------------------------------------------------

End




'Unterprogramme und Funktionen
'------------------------------------------------------
Sub Wait_for_string(byval S As String) As String
   Local Ii As Byte
   Local Cc As Byte
   Ii = 1
   M1:
      Cc = Waitkey()
      If Cc <> Mid(s , Ii , 1) Then
         Goto M1
      Else
         Incr Ii
         If Ii > Len(s) Then Goto M2
         Goto M1
      End If
   M2:
End Sub


'------------------------------------------------------
Function Read_string() As String
   Local Cc As Byte
   Local Ss As String * 10
   Ss = ""
   Do
      Cc = Waitkey()
      Ss = Ss + Chr(cc)
   Loop Until Cc = ","
   Read_string = Left(ss , 10)
End Function

'------------------------------------------------------
Sub Maidenhead
   'In-Variable: lat, lon, ns, ew as string
   'Out-Variable: maid_out as string
   Local A2x As String * 30
   Local Z2n As String * 25
   Local I As String * 10
   Local Dx As Integer
   Local Dy As Integer
   Local Xxx As Integer
   Local Yyy As Integer
   Local Dxx As Integer
   Local Dyy As Integer
   Local Str1 As String * 1
   Local Str2 As String * 1
   Local Str3 As String * 1
   Local Str4 As String * 1
   Local Str5 As String * 1
   Local Str6 As String * 1
   Local Xxxx As Single
   Local Yyyy As Single

   Local Td1 As String * 10
   Local Tl1 As String * 10
   Local Gd1 As String * 10
   Local Gl1 As String * 10

   Local Td As Single
   Local Tl As Single

   Local Gd As Single
   Local Gl As Single

   Local Yy As Single
   Local Xx As Single

   Td1 = Mid(lat_ , 1 , 2)
   Tl1 = Mid(lat_ , 3 , 5)
   Gd1 = Mid(lon , 1 , 3)
   Gl1 = Mid(lon , 4 , 5)

   Td = Val(td1)
   Tl = Val(tl1)
   Gd = Val(gd1)
   Gl = Val(gl1)

   Tl = Tl / 60
   Yy = Td + Tl

   Gl = Gl / 60
   Xx = Gd + Gl

   If Ns = "S" Then Td = -td
   If Ew = "W" Then Gd = -gd

   A2x = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
   Z2n = "01234567890123456789"

   If Xx < -179.99 Or Xx > 179.99 Then Goto Finsub
   If Yy < -89.99 Or Yy > 89.99 Then Goto Finsub

   Xx = Xx + 180
   Yy = Yy + 90

   Xxx = Xx
   Yyy = Yy

   Dx = Xxx / 20
   Dy = Yyy / 10

   Dxx = Dx + 1
   Dyy = Dy + 1

   Str1 = Mid(a2x , Dxx , 1)
   Str2 = Mid(a2x , Dyy , 1)

   Xxx = Dx * 20
   Yyy = Dy * 10

   Xx = Xx - Xxx
   Yy = Yy - Yyy

   Xxxx = Xx * 100
   Yyyy = Yy * 100

   Dx = Xxxx / 200
   Dy = Yyyy / 100

   Dxx = Dx + 1
   Dyy = Dy + 1

   Str3 = Mid(z2n , Dxx , 1)
   Str4 = Mid(z2n , Dyy , 1)

   Dxx = Dx * 2
   Dyy = Dy * 1

   Xx = Xx - Dxx
   Yy = Yy - Dyy

   Xxxx = Xx * 1000
   Yyyy = Yy * 1000

   Xxx = Xxxx
   Yyy = Yyyy

   Xxxx = Xxx / 83.333333
   Yyyy = Yyy / 41.666666

   Dx = Xxxx
   Dy = Yyyy

   Dxx = Dx + 1
   Dyy = Dy + 1

   Str5 = Mid(a2x , Dxx , 1)
   Str6 = Mid(a2x , Dyy , 1)

   Maid_out = Str1 + Str2
   Maid_out = Maid_out + Str3
   Maid_out = Maid_out + Str4
   Maid_out = Maid_out + Str5
   Maid_out = Maid_out + Str6
   Finsub:
End Sub


'LCDBig: Funktion zum Schreiben der grossen Zahlen auf dem LCD
'----------------------------------------------------------
Sub Lcdbig
   ' Zeile 1
   Locate 1 , Lcdbigspalte
   Select Case Lcdbigzahl
      Case 0 : Lcd Chr(1) ; Chr(3) ; Chr(0)
      Case 1 : Lcd Chr(32) ; Chr(0) ; Chr(32)
      Case 2 : Lcd Chr(3) ; Chr(2) ; Chr(0)
      Case 3 : Lcd Chr(3) ; Chr(2) ; Chr(0)
      Case 4 : Lcd Chr(1) ; Chr(6) ; Chr(0)
      Case 5 : Lcd Chr(1) ; Chr(2) ; Chr(4)
      Case 6 : Lcd Chr(1) ; Chr(2) ; Chr(4)
      Case 7 : Lcd Chr(3) ; Chr(2) ; Chr(0)
      Case 8 : Lcd Chr(1) ; Chr(2) ; Chr(0)
      Case 9 : Lcd Chr(1) ; Chr(2) ; Chr(0)
   End Select

   ' Zeile 2
   Locate 2 , Lcdbigspalte
   Select Case Lcdbigzahl
      Case 0 : Lcd Chr(1) ; Chr(6) ; Chr(0)
      Case 1 : Lcd Chr(32) ; Chr(0) ; Chr(32)
      Case 2 : Lcd Chr(1) ; Chr(2) ; Chr(5)
      Case 3 : Lcd Chr(6) ; Chr(2) ; Chr(0)
      Case 4 : Lcd Chr(32) ; Chr(32) ; Chr(0)
      Case 5 : Lcd Chr(6) ; Chr(2) ; Chr(0)
      Case 6 : Lcd Chr(1) ; Chr(2) ; Chr(0)
      Case 7 : Lcd Chr(32) ; Chr(1) ; Chr(32)
      Case 8 : Lcd Chr(1) ; Chr(2) ; Chr(0)
      Case 9 : Lcd Chr(5) ; Chr(6) ; Chr(0)
   End Select
End Sub


'------------------------------------------------------
Himmelsrichtung_:
   Richtung = Val(crs)
   Select Case Richtung
      Case 0 To 11:
         Himmelsrichtung = "N"
      Case 12 To 34:
         Himmelsrichtung = "NNO"
      Case 35 To 56:
         Himmelsrichtung = "NO"
      Case 57 To 79:
         Himmelsrichtung = "ONO"
      Case 80 To 101:
         Himmelsrichtung = "O"
      Case 102 To 124:
         Himmelsrichtung = "OSO"
      Case 125 To 146:
         Himmelsrichtung = "SO"
      Case 147 To 169:
         Himmelsrichtung = "SSO"
      Case 170 To 191:
         Himmelsrichtung = "S"
      Case 192 To 214:
         Himmelsrichtung = "SSW"
      Case 215 To 236:
         Himmelsrichtung = "SW"
      Case 237 To 259:
         Himmelsrichtung = "WSW"
      Case 260 To 281:
         Himmelsrichtung = "W"
      Case 282 To 304:
         Himmelsrichtung = "WNW"
      Case 305 To 326:
         Himmelsrichtung = "NW"
      Case 327 To 345:
         Himmelsrichtung = "NNW"
      Case 346 To 359:
         Himmelsrichtung = "N"
   End Select
Return


'------------------------------------------------------
Umrechnung_kmh:
   Geschwindigkeit = Val(spd)
   Geschwindigkeit = Geschwindigkeit * 1852
   Geschwindigkeit = Geschwindigkeit / 1000
   If Geschwindigkeit < 0.5 Then
      Geschwindigkeit = 0
   End If
   Geschwindigkeit_s = Str(geschwindigkeit)
   Geschwindigkeit_s = Fusing(geschwindigkeit , "#.#")
   Geschwindigkeit_z = Fusing(geschwindigkeit , "#.")
   Geschwindigkeit_e = Val(geschwindigkeit_z)

Return


'------------------------------------------------------
Zuordnung:
   B = Geschwindigkeit_e
   Stelle_einer = B Mod 10
   B = B - Stelle_einer
   B = B / 10
   Stelle_zehner = B Mod 10
   B = B - Stelle_zehner
   B = B / 10
   Stelle_hunderter = B Mod 10
   Lcdbigspalte = 1 : Lcdbigzahl = Stelle_hunderter : Lcdbig
   Lcdbigspalte = 4 : Lcdbigzahl = Stelle_zehner : Lcdbig
   Lcdbigspalte = 7 : Lcdbigzahl = Stelle_einer : Lcdbig
   Locate 2 , 12 : Lcd "Km" ; Chr(47) ; "H"
Return


'----------------------------------------------------------
Character_ant:
   Var_big = 0
   'Definition der zusätzlichen Charakter für Antenne
   Deflcdchar 0 , 14 , 17 , 21 , 14 , 4 , 21 , 31 , 21
   Deflcdchar 1 , 32 , 32 , 4 , 4 , 4 , 21 , 31 , 21
   Cls
   Var_ant = 1
   Lcd "bitte warten"
Return

'----------------------------------------------------------
Character_big:
   Var_ant = 0
   'Definition der zusätzlichen Charakter für große Zahlen auf dem 16*2 Display
   ' LCD-Zeichen Chr(0)
   Deflcdchar 0 , 30 , 30 , 30 , 30 , 30 , 30 , 30 , 30
   ' LCD-Zeichen Chr(1)
   Deflcdchar 1 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15
   ' LCD-Zeichen Chr(2)
   Deflcdchar 2 , 31 , 31 , 32 , 32 , 32 , 32 , 31 , 31
   ' LCD-Zeichen Chr(3)
   Deflcdchar 3 , 31 , 31 , 32 , 32 , 32 , 32 , 32 , 32
   ' LCD-Zeichen Chr(4)
   Deflcdchar 4 , 31 , 31 , 32 , 32 , 32 , 32 , 32 , 32     '
   ' LCD-Zeichen Chr(5)
   Deflcdchar 5 , 32 , 32 , 32 , 32 , 32 , 32 , 30 , 30
   ' LCD-Zeichen Chr(6)
   Deflcdchar 6 , 32 , 32 , 32 , 32 , 32 , 32 , 31 , 31
   ' LCD-Zeichen Chr(7)
   Deflcdchar 7 , 32 , 32 , 14 , 14 , 14 , 14 , 32 , 32
   Cls
   Var_big = 1
   Lcd "bitte warten"
Return


'------------------------------------------------------
On_int0:
   Astep = Astep + 1
   If Astep > 5 Then Astep = 0
   Cls
   Lcd "bitte warten"
   Waitms 700

Return


Unsere Bastelbude - die Jungschen haben mir so ca. 0,5m² (links der Flasche am linken Rand der Tischplatte) zugestanden - Verbrecher!
Bastelstube.JPG

Dann der Zauberstab - das Lichtschwert - Alles Ignoranten - meine Freunde!!
Der Zauberstab.JPG


und noch einige der Anzeigemöglichkeiten
Start.JPG

gross.JPG

Kurs.JPG

Knoten.JPG
Ja, - ich bin Zwilling
Benutzeravatar
dussel07
 
Beiträge: 1606
Registriert: 30.04.2009, 21:04
Wohnort: Goslar

Re: GPS Tacho auf Arduino Basis

Beitragvon dussel07 » 04.10.2016, 09:16

Kaum wird ein Problem angesprochen schon tritt es auf! Hier mein ich 25Uhr16. Hat sich nach dem Erkennen des GPS Strings dann wieder erledigt aber ohne Korrektur finde ich das blöd. Aktuelle Software wird folgen.
Ja, - ich bin Zwilling
Benutzeravatar
dussel07
 
Beiträge: 1606
Registriert: 30.04.2009, 21:04
Wohnort: Goslar


Zurück zu Projekte

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron