'( ################################################################################ project: GPSDAEI - GPS data evaluation and interpretation 2015 -------------------------------------------------------------------------------- name : GPSDAEI25.bas copyright : (c) Chris, OE3HBW, JN87AQ, 2015 purpose : GPS data evaluation and interpretation micro : ATmega644 programmer : homebrew (STK200/STK300 emulation) compiler : MCS BASCOM-AVR 2.0.7.8 flash : 25% code build : 0.25 @ 27012015 (27. Jan. 2015) status : test -------------------------------------------------------------------------------- ########################### HARDWARE ########################################### NL-652ETTL GPS Modul Output: NMEA 0183 V2.3 frames with 38400 Bd GGA Global Positioning System Fix Data GSA GPS receiver operating mode (DOP values) GSV Number of SVs, PRN, elevation, azimuth, SNR RMC Recommended Minimum Specific GPS/TRANSIT data VTG Actual track made good and speed over ground used: RMCstat Status Data valid = A / Data invalid = V RMCdate Date --> ddmmyy GGAfixe Quality 0=invalid 1=valid SPS mode 2=DGPS 6=Est/DR GGAlate Latidude GGAlone Longitude GGAalte Altitude VTGspog Speed over ground GGAtime GPS time GGAsate Number of satellites ################################################################################ ') '$PROG &HFF,&HD7,&HD9,&HFC 'Take care! Fuse Bits !!! $regfile = "m644def.dat" 'ATmega644 $crystal = 14745600 '14.7456 MHz $baud = 38400 'stack and framesize not optimized! $hwstack = 200 $framesize = 500 $swstack = 300 $lib "glcdKS108.lbx" 'GLCD Lib '----- Config PORTs ------------------------------------------------------------ DDRD = &b0000_0010 'as Input and PORTD = &b1111_1100 'PullUp for keypad with S1 - S5 'PORTA in Config MMCSD_HC.bas defined '----- Config GLCD ------------------------------------------------------------- Config Graphlcd = 128 * 64sed , Dataport = PortC , Controlport = PortB , _ Cd = 0 , Rd = 1 , Ce = 2 , Ce2 = 3 , Enable = 4 , Reset = 5 '----- Config USART ------------------------------------------------------------ Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , _ Databits = 8 , Clockpol = 0 Config Serialin = Buffered , Size = 128 , Bytematch = 36 '$ = Start sentence '----- Config Interrupts ------------------------------------------------------- Config INT0 = Falling On INT0 isr_KeyPad 'Interrupt-Routine Externer Int0 Enable INT0 '------------------------------------------------------------------------------- Declare Sub Menu() Declare Sub mnuShow() Declare Sub StatusWindow() Declare Sub WGSWindow() Declare Sub MHWindow() Declare Sub SpeedWindow() Declare Sub DTimeWindow() Declare Sub DecimalGrad() Declare Sub CalcGrid(ByVal mf As Byte) Declare Sub Maidenhead() Declare Sub GPSdate() Declare Sub GPStimeConv() Declare Sub Tracking() Declare Sub TrackingWindow() Const nmealenmax = 85 Const FieldLenMax = 13 Const mnuMaxLns = 10 'Menu-tree: MAX nodes Const glcdrows = 6 Const leapsec = 16 Const delaysec = 2 Const UTC2MEZ = 1 Const TrckTime = 10 'Tracking idle time in sec '----------------------- Dim tbyte1 As Byte Dim i As Byte Dim j As Byte '----- SD Card --------- Dim BTemp1 As Byte Dim SDOK As Byte Dim LTemp1 As Long Dim TrkStr As String * 75 'DaumenxPi; noch exakt angeben! Dim tpcount As Long Dim SDfile As String * 12 'SDHC file name '----- NMEA ------------ Dim nmeastr As String * nmealenmax Dim nmeaID As String * 16 Dim achar As String * 1 Dim Commas(16) As String * FieldLenMax Dim RMCstat As String * 1 Dim RMCdate As String * 6 Dim GGAtime As String * 10 Dim GGAlate As String * 10 Dim GGAlone As String * 10 Dim GGAalte As String * 10 Dim GGAfixe As String * 10 Dim GGAsate As String * 10 Dim VTGspog As String * 10 '----- DecimalGrad ----- Dim GStrLat As String * 10 Dim MStrLat As String * 10 Dim GStrLon As String * 10 Dim MStrLon As String * 10 Dim GSngLat As Single Dim MSngLat As Single Dim GSngLon As Single Dim MSngLon As Single Dim dgLat As Single Dim dgLon As Single '----- Maidenhead ----- Dim tmps As Single Dim tmpb As Byte Dim ChrStr As String * 26 Dim ChrStrOvl(27) As Byte At ChrStr Overlay Dim NumStr As String * 10 Dim NumStrOvl(11) As Byte At NumStr Overlay Dim QTH As String * 11 Dim LocStrOvl(12) As Byte At QTH Overlay '----- DTime ----- Dim dd As String * 2 Dim mm As String * 2 Dim yy As String * 2 Dim Dat As String * 10 Dim tmpStr As String * 3 Dim tmpTh As Single Dim tmpTm As Single Dim tmpTs As Single Dim TSec As Single Dim tmpT1 As Single Dim tmpT2 As Single Dim UTCh As Integer Dim UTCm As Integer Dim UTCs As Integer Dim UTC As String * 8 Dim MEZ As String * 8 '----- Menu ----- Dim mnuSlct As Word Dim mnuSlctOld As Word Dim mnuNCnt As Byte Dim mnuFb As Byte Dim mnuPntr As Byte Dim mnuTxt(mnuMaxLns) As String * 13 Dim mnuNode(mnuMaxLns) As Word '---- KeyPad ----- Dim KeyCode As Byte '####################### Main ################################################## '----- Initialization ---------------------------------------------------------- Enable Interrupts Enable Serial Glcdcmd &h3E , 1 : Glcdcmd &h3E , 2 'display off Waitms 100 Glcdcmd &h3F , 1 : Glcdcmd &h3F , 2 'display on Setfont Font8x8 'Font 8x8 laden Cls ShowPic 32 , 0 , IntroPic 'Intro Bild anzeigen Wait 3 ChrStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" NumStr = "0123456789" mnuSlct = 0 Cls '----- Main Loop --------------------------------------------------------------- Do Call Menu() 'Menu Loop End '######################## Subs ################################################# '------------------------ Menu ------------------------------------------------- Sub Menu() 'Menu tree Select Case mnuSlct Case 0:'Main-Menu mnuFb = 0 'if back then jump to node x mnuNCnt = 5 'how many nodes in this layer mnuTxt(1) = "Status" 'node text mnuNode(1) = 1 'node number mnuTxt(2) = "Navigation" mnuNode(2) = 2 mnuTxt(3) = "Speed" mnuNode(3) = 3 mnuTxt(4) = "Time/Date" mnuNode(4) = 4 mnuTxt(5) = "Tracking" mnuNode(5) = 5 mnuTxt(6) = "Program" mnuNode(6) = 6 Call mnuShow 'call menu display and navigation control Case 1: 'Status Call StatusWindow() mnuSlct = 0 'jump back to menu selection 0 Case 2: 'Navigation mnuFb = 0 mnuNCnt = 2 mnuTxt(1) = "WGS84" mnuNode(1) = 21 mnuTxt(2) = "Maidenhead" mnuNode(2) = 22 Call mnuShow Case 21: 'WGS84 Call WGSWindow() mnuSlct = 2 Case 22: 'Maidenhead Call MHWindow() mnuSlct = 2 Case 3: 'Speed Call SpeedWindow() mnuSlct = 0 Case 4: 'Date/Time Call DTimeWindow() mnuSlct = 0 Case 5: 'Tracking Call TrackingWindow() mnuSlct = 0 Case 6: 'Program Wait 1 mnuSlct = 0 Case Else: mnuSlct = 0 End Select End Sub Sub mnuShow() 'Display and navigation for menu-tree mnuSlctOld = mnuSlct mnuPntr = 1 While mnuSlctOld = mnuSlct Cls j = mnuPntr + glcdrows Decr j If j > mnuNCnt Then j = mnuNCnt For i = 1 To j If i = mnuPntr Then LCDAT i , 10 , ">" , 1 Else LCDAT i , 10 , " " , 0 End If LCDAT i , 20 , mnuTxt(i) Next i KeyCode = &hF8 Do 'Wait until key pressed Loop until KeyCode <> &hF8 Select Case KeyCode Case &hF0: mnuSlct = mnuFb 'KeyLeft < S1 Case &hE8: If mnuPntr > 1 Then Decr mnuPntr 'KeyUp S2 Case &hD8: If mnuPntr < mnuNCnt Then Incr mnuPntr 'KeyDwn S3 Case &hB8: mnuSlct = mnuNode(mnuPntr) 'KeyRight > S4 End Select Wend End Sub '------------------------ GLCD Windows ----------------------------------------- Sub StatusWindow() Cls Box(0 , 0) -(127 , 63) , 1 LCDAT 1 , 1 , " " , 1 LCDAT 2 , 1 , " Status " , 1 Do LCDAT 4 , 20 , "Stat" : LCDAT 4 , 60 , RMCstat LCDAT 5 , 20 , "Fixe" : LCDAT 5 , 60 , GGAfixe LCDAT 6 , 20 , "Sats" : LCDAT 6 , 60 , GGAsate LCDAT 7 , 20 , "SDHC" : LCDAT 7 , 60 , SDOK Wait 1 Loop until KeyCode = &h78 End Sub Sub WGSWindow() Cls Box(0 , 0) -(127 , 63) , 1 LCDAT 1 , 1 , " " , 1 LCDAT 2 , 1 , " WGS Nav " , 1 Do LCDAT 4 , 10 , "Lat" : LCDAT 4 , 48 , GGAlate LCDAT 5 , 10 , "Lon" : LCDAT 5 , 40 , GGAlone LCDAT 6 , 10 , "Alt" : LCDAT 6 , 40 , GGAalte Waitms 500 Loop until KeyCode = &h78 End Sub Sub MHWindow() Cls Box(0 , 0) -(127 , 63) , 1 LCDAT 1 , 1 , " " , 1 LCDAT 2 , 1 , " QTH-Locator " , 1 Do Call Maidenhead() LCDAT 5 , 20 , QTH Waitms 500 Loop until KeyCode = &h78 End Sub Sub SpeedWindow() Cls Box(0 , 0) -(127 , 63) , 1 LCDAT 1 , 1 , " " , 1 LCDAT 2 , 1 , " Speed " , 1 Do LCDAT 5 , 10 , "Spog" : LCDAT 5 , 50 , VTGspog Waitms 500 Loop until KeyCode = &h78 End Sub Sub DTimeWindow() Cls Box(0 , 0) -(127 , 63) , 1 LCDAT 1 , 1 , " " , 1 LCDAT 2 , 1 , " Date/Time " , 1 Call GPSdate LCDAT 4 , 10 , "Dat" : LCDAT 4 , 40 , Dat Do Call GPStimeConv() LCDAT 6 , 15 , "MEZ" : LCDAT 6 , 50 , MEZ LCDAT 7 , 15 , "UTC" : LCDAT 7 , 50 , UTC Loop until KeyCode = &h78 End Sub Sub TrackingWindow() Cls Box(0 , 0) -(127 , 63) , 1 LCDAT 1 , 1 , " " , 1 LCDAT 2 , 1 , " Tracking " , 1 If GGAfixe <> "0" then Call Tracking Else LCDAT 5 , 20 , "No Fix!" LCDAT 6 , 20 , "No Tracking..." End If Do 'NOP Loop until KeyCode = &h78 End Sub '------------------------ Conversions ------------------------------------------ Sub DecimalGrad() 'Lon 01600.8446 'Lat 4741.8729 GStrLon = Mid(GGAlone , 1 , 3) MStrLon = Mid(GGAlone , 4 , 7) GSngLon = Val(GStrLon) MSngLon = Val(MStrLon) MSngLon = MSngLon / 60 dgLon = GSngLon + MSngLon GStrLat = Mid(GGAlate , 1 , 2) MStrLat = Mid(GGAlate , 3 , 7) GSngLat = Val(GStrLat) MSngLat = Val(MStrLat) MSngLat = MSngLat / 60 dgLat = GSngLat + MSngLat End Sub Sub CalcGrid(ByVal mf As Byte) tmps = tmps * mf tmpb = Int(tmps) tmpb = tmpb + 1 tmps = Frac(tmps) End Sub Sub Maidenhead() 'QTH-Locator (extended version with 10 characters) Call DecimalGrad() dgLon = dgLon + 180 dgLat = dgLat + 90 LocStrOvl(7) = " " 'Longitude ------------------------- tmps = dgLon * 0.05 '/ 20 tmpb = Int(tmps) tmpb = tmpb + 1 tmps = Frac(tmps) LocStrOvl(1) = ChrStrOvl(tmpb) Call CalcGrid(10) LocStrOvl(3) = NumStrOvl(tmpb) Call CalcGrid(24) LocStrOvl(5) = ChrStrOvl(tmpb) Call CalcGrid(10) LocStrOvl(8) = NumStrOvl(tmpb) Call CalcGrid(24) LocStrOvl(10) = ChrStrOvl(tmpb) 'Latitude -------------------------- tmps = dgLat * 0.1 '/ 10 tmpb = Int(tmps) tmpb = tmpb + 1 tmps = Frac(tmps) LocStrOvl(2) = ChrStrOvl(tmpb) Call CalcGrid(10) LocStrOvl(4) = NumStrOvl(tmpb) Call CalcGrid(24) LocStrOvl(6) = ChrStrOvl(tmpb) Call CalcGrid(10) LocStrOvl(9) = NumStrOvl(tmpb) Call CalcGrid(24) LocStrOvl(11) = ChrStrOvl(tmpb) End Sub Sub GPSdate() dd = Mid(RMCdate , 1 , 2) mm = Mid(RMCdate , 3 , 2) yy = Mid(RMCdate , 5 , 2) Dat = "20" + yy Dat = Dat + "." Dat = Dat + mm Dat = Dat + "." Dat = Dat + dd End Sub Sub GPStimeConv() tmpStr = Mid(GGAtime , 1 , 2) 'h tmpTh = Val(tmpStr) tmpTh = tmpTh * 3600 tmpStr = Mid(GGAtime , 3 , 2) 'm tmpTm = Val(tmpStr) tmpTm = tmpTm * 60 tmpStr = Mid(GGAtime , 5 , 5) 's tmpTs = Val(tmpStr) TSec = tmpTh + tmpTm TSec = TSec + tmpTs 'GPS Time in seconds TSec = TSec - leapsec 'Schaltsekunden TSec = TSec + delaysec 'Verarbeitungszeit tmpT1 = TSec / 3600 UTCh = Int(tmpT1) tmpT2 = Frac(tmpT1) tmpT1 = tmpT2 * 60 UTCm = Int(tmpT1) tmpT2 = Frac(tmpT1) tmpT1 = tmpT2 * 60 UTCs = Round(tmpT1) UTC = Str(UTCh) UTC = UTC + ":" UTC = UTC + Str(UTCm) UTC = UTC + ":" UTC = UTC + Str(UTCs) UTCh = UTCh + UTC2MEZ MEZ = Str(UTCh) MEZ = MEZ + ":" MEZ = MEZ + Str(UTCm) MEZ = MEZ + ":" MEZ = MEZ + Str(UTCs) End Sub '------------------------ Data Logging ----------------------------------------- Sub Tracking() SDOK = 0 tpcount = 0 SDfile = "gps_data.asc" $include "Config_MMCSD_HC.inc" '--> Config Software SPI on PortA4-7 If Gbdriveerror = 0 Then $include "Config_AVR-DOS.inc" '--> Cfilehandles = 1 / Csepfathandle = 0 Btemp1 = Initfilesystem(1) 'with MBR If Btemp1 = 0 Then 'Filesystem OK Open SDfile For Append As #3 If Gbdoserror = 0 Then Do TrkStr = "" TrkStr = Str(tpcount) + "," + RMCdate + "," + GGAtime + _ "," + GGAlate + "," + GGAlone Print #3 , TrkStr Incr tpcount LCDAT 5 , 15 , "TP:" : LCDAT 5 , 40 , tpcount Wait trckTime Loop until KeyCode = &h78 SDOK = 1 else SDOK = 0 'Gbdoserror End If Flush #3 Close #3 else SDOK = 0 'Filesystem error End If else SDOK = 0 'Gbdrive error End If If SDOK = 0 Then 'Error LCDAT 5 , 20 , "SD Error!" LCDAT 6 , 20 , "No Tracking" End If End Sub '---------------------- Interrupt service requests ----------------------------- isr_KeyPad: KeyCode = PIND AND &b1111_1000 'Read Pin3-7 Return Serial0CharMatch: 'If Char = "$" Pushall nmeastr = "" nmeaID = "" Do tbyte1 = Inkey() achar = Chr(tbyte1) nmeastr = nmeastr + achar 'add character to NMEA string Loop Until achar = Chr(10) 'until Char = nmeaID = Mid(nmeastr , 1 , 6) '$ + adress field If nmeaID = "$GPRMC" Then tbyte1 = Split(nmeastr , Commas(1) , ",") RMCstat = Commas(3) 'valid/invalid data RMCdate = Commas(10) 'date ddmmyy ElseIf nmeaID = "$GPGGA" Then tbyte1 = Split(nmeastr , Commas(1) , ",") GGAtime = Commas(2) 'time of fix (hhmmss) GGAlate = Commas(3) 'latitude If Commas(4) = "S" Then Ggalate = "-" + Ggalate 'N/S GGAlone = Commas(5) 'longitude If Commas(6) = "W" Then Ggalone = "-" + Ggalone 'E/W GGAfixe = commas(7) 'fix quality (0=invalid, 1=GPS fix, 2=DGPS fix) GGAsate = commas(8) 'number of satellites being tracked GGAalte = commas(10) 'altitude above sea level ElseIf nmeaID = "$GPVTG" Then tbyte1 = Split(nmeastr , Commas(1) , ",") VTGspog = Commas(8) 'speed over ground End If Popall return '----- Data -------------------------------------------------------------------- IntroPic: $bgf "TestPic2.bgf" $include "font8x8.font" '############################ End Of File ######################################