If you can make sense of it here is the firmware for the FAT16 version of the datalogger I sell.
Code:
'$GPGGA,170834,4124.8963,N,08151.6838,W,1,05,1.5,280.2,M,-34.0,M,,,*75
'$GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62
'This design is meant for GPS_LOGGER_F_D No Battery Check
Device = 18F2620
XTAL = 8
Declare PLL_REQ = True
OSCCON = %01110000 'Internal 8 MHz clock select
OSCTUNE.6 = 1 ' Frequency Multiplier PLL for INTOSC Enable bit
ALL_DIGITAL = True
Declare WATCHDOG = True
FLOAT_DISPLAY_TYPE = LARGE
' Device Fuse configuration
CONFIG_START
OSC = INTIO67 ; Internal Oscillator
FCMEN = OFF ; Failsafe Clock Monitor Disabled
IESO = OFF ; Int/Ext Oscillator Switch Over Disabled
PWRT = OFF ; Power Up Timer Disabled
BOREN = OFF ; Brownout Reset Disabled
WDT = OFF ; Watchdog Timer Disabled
MCLRE = OFF ; MCLR Disabled
WDTPS = 256 ; 15000 x 4mS = 60 seconds
LVP = OFF ' Low_Voltage Programming
PBADEN = OFF ; PORTB Digital
CONFIG_END
'GPS Varibles
Dim LAT As Float
Dim SIGN_LAT As Float
Dim LON As Float
Dim SIGN_LONG As Float
Dim FIX As Byte
Dim SAT As Byte
Dim ALT As Float
Dim SPD As Float
Dim HDG As Float
Dim IDX_GP As Byte 'GP Sentence IDX
Dim IDX_INT As Word 'Inteval IDX
Dim IDX_B As Byte 'Baud IDX
Dim IDX_SAVE As Byte
Dim GPGSV_TOT As Byte
'Position of Dilution Precision Variables
Dim PDOP As Float
Dim HDOP As Float
Dim VDOP As Float
'*******************************************************************************
'Test LED Setup
Dim BLINKS As Byte
Dim NUM_BLINKS As Byte
'*******************************************************************************
'Extract the Value Variables
Dim GPS_BLOOP As Byte ' \
Dim GPS_EXTRACT_ITEM As Byte ' \
Dim GPS_COMMA_COUNT As Byte ' General purpose variables
Dim GPS_CHARPOS As Byte ' /
Dim GPS_CHAR As Byte ' /
'*******************************************************************************
'GPS_PARSE Variables
Dim GPS_DATA_STRING[20] As Byte ' Temp buffer
Symbol GPS_RXBUFFER_LENGTH = 100
Dim GPS_RXBUFF[GPS_RXBUFFER_LENGTH] As Byte ' Serial buffer for NMEA sentences
Dim GPVTG_STR[GPS_RXBUFFER_LENGTH] As Byte
Dim GPRMC_STR[GPS_RXBUFFER_LENGTH] As Byte
Dim GPGSV_STR[GPS_RXBUFFER_LENGTH] As Byte
Dim GPGSV_STR1[GPS_RXBUFFER_LENGTH] As Byte
Dim GPGSV_STR2[GPS_RXBUFFER_LENGTH] As Byte
Dim GPGSV_STR3[GPS_RXBUFFER_LENGTH] As Byte
Dim GPGSA_STR[GPS_RXBUFFER_LENGTH] As Byte
Dim GPGLL_STR[GPS_RXBUFFER_LENGTH] As Byte
Dim GPGGA_STR[GPS_RXBUFFER_LENGTH] As Byte
'*******************************************************************************
'String to Float Variables
Dim N As Byte
Dim STF_STRING_IN[20] As Byte 'String to Float Variables
Dim STF_POWER_10 As Float
Dim STF_RESULT As Float
Dim STF_SIGN As Byte
Dim STF_CHAR As Byte
Dim STF_CHARPOS As Byte
Dim STF_TEMP As Float
Dim TEST_CHAR As Byte
Dim TEST_CHAR_IDX As Byte
'*******************************************************************************
'String to Float Variables
Dim DDMM_STRING_IN[20] As Byte 'String to Float Variables
Dim DDMM_POWER_10 As Float
Dim DDMM_RESULT As Float
Dim DDMM_SIGN As Byte
Dim DDMM_CHAR As Byte
Dim DDMM_CHARPOS As Byte
Dim DDMM_CHARPOS_LOW As Byte
Dim DDMM_TEMP As Float
Dim DDMM_TEMP_STR[6] As Byte
'*******************************************************************************
'Config File Variables
Dim CONFIG_BUFF[50] As Byte
Dim CONFIG_VALUE As Word
Dim CONFIG_IDX As Byte
Dim INTERVAL_INIT As Word
INTERVAL_INIT = 0
Dim X As Word
Dim INTERVAL As Word
Dim INTERVAL_SD As Word
Dim INTERVAL_EPROM As Word
Dim MODE_INIT As Byte
MODE_INIT = %11111111
Dim MODE As Byte
Dim MODE_SD As Byte
Dim MODE_EPROM As Byte
Dim FIXED_INIT As Byte
FIXED_INIT = 0
Dim FIXED As Byte
Dim FIXED_SD As Byte
Dim FIXED_EPROM As Byte
'*******************************************************************************
'SD VARIABLES
Dim Response As Byte 'SD Card Response
Dim IDX_FL As Byte 'Filename Index
Dim SAMPLES As Byte '# of Samples to take before writing file
Dim WRITE_MODE As Byte '0 = NMEA & 1 = KML
Symbol LED = PORTB.2
'*******************************************************************************
'SD PIN DECLARES
Symbol SD_CS = PORTC.0 'SPI CS to SD CS (SD pin 1)
Symbol SD_DI = PORTC.5 'SPI DO to SD DI (SD Pin 2)
Symbol SD_CLK = PORTC.3 'SPI CLK to SD CLK (SD Pin 5)
Symbol SD_DO = PORTC.4 'SPI DI to SD DO (SD Pin 7)
'*******************************************************************************
Include "RY_GPS_PARSEI_EB85_LIB.PBP" 'Include managed library file
'*******************************************************************************
'HSERIAL = 38400 BAUD
RCSTA = $90 ' Enable serial port & continuous receive
TXSTA = $20 ' Enable transmit, BRGH = 0
SPBRG = 12 ' 38400 Baud @ 0.16%
'*******************************************************************************
'TURN MOSFET SWITCH ON
Low PORTB.1
'*******************************************************************************
'SETUP ADC
TRISA.0=1 ' Configure as Input
TRISA.1=1 ' Configure as Input
ADCON2.7 = 1
Dim BATTERY As Word
Dim BATTERY_ON As Byte
Dim VOLTSB As Float
Dim VOLTST As Float
Dim COUNTS As Word
Dim TEMPC As Float
Dim TEMPF As Float
'*******************************************************************************
'BUBBLE SORT VARIABLES
Symbol SAMPLES_TO_TAKE = 5 ' The amount of samples to take
Dim SWAPTMP As Word ' Temporary variable for swapping
Dim INDEX As Byte ' Holds the position in the sort
Dim SWAP_OCCURED As Byte ' Indicates if the sort is complete
Dim SAMPLE[SAMPLES_TO_TAKE + 1] As Word ' Create an array to hold the samples
'*******************************************************************************
'RESTART PIC VALUES
Dim emaN_eliF_DS[8] As Byte
Dim txE_eliF_DS[8] As Byte
'*******************************************************************************
'Get Date and Time From GPS
INIT:
NUM_BLINKS = 1 :GoSub LED_TEST
GoSub INIT_SD_CARD
NUM_BLINKS = 2 :GoSub LED_TEST
GoSub READ_CONFIG_FILE
NUM_BLINKS = 3 :GoSub LED_TEST
GoSub GPRMC_EXTRACT
NUM_BLINKS = 4 :GoSub LED_TEST
GoSub INIT_SD_CREATE
NUM_BLINKS = 5 :GoSub LED_TEST
'*******************************************************************************
MAIN:
GoSub BATTERY_CHECK
GoSub BATTERY_LEVEL
GoSub TEMPERATURE_LEVEL
If MODE.7 = 0 Then
GoSub NMEA_EXTRACT
GoSub BATTERY_CHECK
GoSub NMEA_WRITE
ElseIf MODE.7 = 1 Then
'Extract NMEA Sentences
If MODE.4 = 1 Or MODE.3 = 1 Or MODE.0 = 1 Then GoSub GPRMC_EXTRACT
If MODE.6 = 1 Or MODE.5 = 1 Or MODE.2 = 1 Then GoSub GPGGA_EXTRACT
If MODE.2 = 1 Then GoSub GPGSA_EXTRACT
'Process NMEA Data
If MODE.4 = 1 Or MODE.3 = 1 Or MODE.0 = 1 Then GoSub GPRMC_PROCESS
If MODE.6 = 1 Or MODE.5 = 1 Or MODE.2 = 1 Then GoSub GPGGA_PROCESS
If MODE.2 = 1 Then GoSub GPGSA_PROCESS
GoSub BATTERY_CHECK
GoSub KML_WRITE
EndIf
If BATTERY < 1000 Then GoSub LOW_BAT_BLINK
If INTERVAL > 0 Then GoSub PIC_SLEEP
GoTo MAIN
'*******************************************************************************
PIC_SLEEP:
If INTERVAL > 29 Then GoSub GPS_SLEEP
X = INTERVAL
WDTCON=1 ; software enable WDT
Repeat
@Sleep ; sleep 256 x 4mS per loop
nop
Dec X
Until X = 0
WDTCON=0 ; software disable WDT
If INTERVAL > 29 Then GoSub GPS_WAKE
Return
'*******************************************************************************
GPS_SLEEP:
High PORTB.1 'Turn off power to GPS and SD Card
Return
'*******************************************************************************
GPS_WAKE:
Low PORTB.1 'Turn on GPS and SD Card
DelayMS 1000
GoSub INIT_SD_CARD 'Init SD Card
DelayMS 10
SD_File_Name = Str emaN_eliF_DS 'Reload Filename
SD_File_Ext = Str txE_eliF_DS 'Reload File Extension
Response = SD_Append_File 'Reopen file for Appending
DelayMS 10
Response = SD_Save_File
Clear X
Repeat 'Wait till GPS gets a fix again
GoSub GPGGA_EXTRACT
GoSub GPGGA_PROCESS
If FIX = 0 Then GoSub NO_FIX_BLINK
Inc X
Until FIX > 0 Or X > 99
Return
'*******************************************************************************
BATTERY_CHECK:
ADCON1 = %00001111 'Set PORTA Digital
BATTERY_ON = PORTA.0
If BATTERY_ON = 0 Then GoTo BATTERY_CHECK 'Loop Until SCAP1 Dies!
Return
'*******************************************************************************
BATTERY_LEVEL:
ADCON1 = %00001101 'Set PORTA.0 &.1 Analog
For N = 0 To SAMPLES_TO_TAKE
SAMPLE[N] = ADIn 0
DelayMS 10
Next
GoSub BUBBLE_SORT
BATTERY = SAMPLE[2]
VOLTSB = BATTERY / 1024 * 3.3
Return
'*******************************************************************************
TEMPERATURE_LEVEL:
ADCON1 = %00001101 'Set PORTA.0 &.1 Analog
For N = 0 To SAMPLES_TO_TAKE
SAMPLE[N] = ADIn 1
DelayMS 10
Next
GoSub BUBBLE_SORT
COUNTS = SAMPLE[2]
VOLTST = COUNTS / 1024 * 3.3
TEMPC = (VOLTST - .424) /.00625
TEMPF = TEMPC * 9 /5
TEMPF = TEMPF + 32
Return
'*******************************************************************************
BUBBLE_SORT:
Repeat
SWAP_OCCURED = 0 ' Clear flag that indicates swap.
INDEX = 0
Repeat ' For each cell of the array...
If SAMPLE[INDEX] > SAMPLE[INDEX + 1] Then ' Move larger values up.
SWAPTMP = SAMPLE[INDEX] ' ..by swapping them.
SAMPLE[INDEX] = SAMPLE[INDEX + 1]
SAMPLE[INDEX + 1] = SWAPTMP
SWAP_OCCURED = 1 ' Set bit if swap occurred.
EndIf
Inc INDEX
Until INDEX = SAMPLES_TO_TAKE ' Check next cell of the array.
Until SWAP_OCCURED = 0 ' Keep sorting until no more swaps.
Return
'*******************************************************************************
INIT_SD_CARD:
DelayMS 250
Response = 0
Repeat
Low LED
'Response = SD_Init_FS_MSSP SD_SPI_FOSC_64
Response = SD_Init_FS
High LED
DelayMS 150
Until Response = 0
Return
'*******************************************************************************
READ_CONFIG_FILE:
DelayMS 100
SD_File_Name = "CONFIG"
SD_File_Ext = "CSV"
Response = SD_Check_For_File
'READ_CONFIG_STRING
If Response = 0 Then '0 - File Present 1 - File Not Present
Response = SD_Open_File
'Get Spec'd Sampling Interval
GoSub READ_CONFIG_VALUE
INTERVAL_SD = Val (CONFIG_BUFF,Dec)
'Get Spec'd NMEA/KML Mode
GoSub READ_CONFIG_VALUE
MODE_SD = Val (CONFIG_BUFF,BIN)
'Get FIXED/NOT FIXED Recording Option
GoSub READ_CONFIG_VALUE
FIXED_SD = Val (CONFIG_BUFF,Dec)
'Read EPROM Values
GoSub READ_CONFIG_EPROM
'Compare SD and EPROM Values
Select INTERVAL_SD
Case 0 To 65535
If INTERVAL_SD <> INTERVAL_EPROM Then
INTERVAL = INTERVAL_SD
Else
INTERVAL = INTERVAL_EPROM
EndIf
Case Else
INTERVAL = INTERVAL_EPROM
EndSelect
'Compare SD and EPROM Values
Select MODE_SD
Case 0 To 255
If MODE_SD <> MODE_EPROM Then
MODE = MODE_SD
Else
MODE = MODE_EPROM
EndIf
Case Else
MODE = MODE_EPROM
EndSelect
'Compare SD and EPROM Values
Select FIXED_SD
Case 0 To 1
If FIXED_SD <> FIXED_EPROM Then
FIXED = FIXED_SD
Else
FIXED = FIXED_EPROM
EndIf
Case Else
FIXED = FIXED_EPROM
EndSelect
ElseIf Response = 1 Then 'File Not Present
'Read Values from EPROM and Process
GoSub READ_CONFIG_EPROM
INTERVAL = INTERVAL_EPROM
MODE = MODE_EPROM
FIXED = FIXED_EPROM
GoSub WRITE_CONFIG_FILE
EndIf
GoSub WRITE_CONFIG_EPROM
Return
'*******************************************************************************
INIT_SD_CREATE:
GoSub INIT_SD_CHECK_WRITE
GoSub INIT_SD_HEADER
Return
'*******************************************************************************
INIT_SD_CHECK_WRITE:
DelayMS 100
Clear IDX_FL
Repeat
Select IDX_FL
Case < 10
SD_File_Name = "GPSXX00" + Str$ (Dec IDX_FL) 'File Name, upper case only!
Case < 100
SD_File_Name = "GPSXX0" + Str$ (Dec IDX_FL) 'File Name, upper case only!
Case < 255
SD_File_Name = "GPSXX" + Str$ (Dec IDX_FL) 'File Name, upper case only!
EndSelect
SD_File_Ext = "CSV" 'File Ext, upper case only!
Response = SD_Check_For_File 'Check if file already exists
Inc IDX_FL
Until Response = 1
Str emaN_eliF_DS = Str SD_File_Name 'Save Filename for Restarting SD Card
Str txE_eliF_DS = Str SD_File_Ext 'Save Ext for Restarting SD Card
Response = SD_New_File
Response = SD_Save_File
Return
'*******************************************************************************
INIT_SD_HEADER:
DelayMS 100
If MODE.7 = 0 Then
'DO NOT WRITE HEADER DATA IN NMEA MODE
ElseIf MODE.7 = 1 Then
If MODE.6 = 1 Then SD_IO_String = "LATITUDE,LONGITUDE"
If MODE.5 = 1 Then SD_IO_String = SD_IO_String + ",ALTITUDE"
If MODE.4 = 1 Then SD_IO_String = SD_IO_String + ",HEADING"
If MODE.3 = 1 Then SD_IO_String = SD_IO_String + ",SPEED"
If MODE.2 = 1 Then SD_IO_String = SD_IO_String + ",SATELLITES" + ",PDOP" + ",HDOP" + ",VDOP"
If MODE.1 = 1 Then SD_IO_String = SD_IO_String + ",FIX"
If MODE.0 = 1 Then SD_IO_String = SD_IO_String + ",UTC TIME" + ",UTC DATE"
'SD_IO_String = SD_IO_String + ",COUNTS" + ",VOLTS"
'SD_IO_String = SD_IO_String + ",COUNTS" + ",TEMPC" + ",TEMPF"
'SD_IO_String = SD_IO_String + ",TEMPC" + ",TEMPF"
SD_IO_String = SD_IO_String + 13 + 10
SD_Write_String_To_File
EndIf
Response = SD_Save_File
Return
'*******************************************************************************
NMEA_EXTRACT:
If MODE.0 = 1 Then
HSerIn[Wait("$GPRMC")]
GoSub RECEIVE_GP_SENTENCE
StrN GPRMC_STR = Str GPS_RXBUFF
EndIf
If MODE.1 = 1 Then
'Capture First GPGSV String
HSerIn [Wait("$GPGSV")]
GoSub RECEIVE_GP_SENTENCE
StrN GPGSV_STR = Str GPS_RXBUFF
'Determine How Many Strings Present?
GPS_EXTRACT_ITEM = 1
GoSub EXTRACT_THE_VALUE
GPGSV_TOT = Val(GPS_DATA_STRING,Dec)
'Capture all the GPGSV sentences
Select GPGSV_TOT
Case 1
HSerIn [Wait("$GPGSV,1,1")]
GoSub RECEIVE_GP_SENTENCE
StrN GPGSV_STR1 = Str GPS_RXBUFF
Case 2
HSerIn [Wait("$GPGSV,2,1")]
GoSub RECEIVE_GP_SENTENCE
StrN GPGSV_STR1 = Str GPS_RXBUFF
HSerIn [Wait("$GPGSV,2,2")]
GoSub RECEIVE_GP_SENTENCE
StrN GPGSV_STR2 = Str GPS_RXBUFF
Case 3
HSerIn [Wait("$GPGSV,3,1")]
GoSub RECEIVE_GP_SENTENCE
StrN GPGSV_STR1 = Str GPS_RXBUFF
HSerIn [Wait("$GPGSV,3,2")]
GoSub RECEIVE_GP_SENTENCE
StrN GPGSV_STR2 = Str GPS_RXBUFF
HSerIn [Wait("$GPGSV,3,3")]
GoSub RECEIVE_GP_SENTENCE
StrN GPGSV_STR3 = Str GPS_RXBUFF
EndSelect
EndIf
If MODE.2 = 1 Then
HSerIn [Wait("$GPGSA")]
GoSub RECEIVE_GP_SENTENCE
StrN GPGSA_STR = Str GPS_RXBUFF
EndIf
If MODE.3 = 1 Then
HSerIn [Wait("$GPGGA")]
GoSub RECEIVE_GP_SENTENCE
StrN GPGGA_STR = Str GPS_RXBUFF
EndIf
Return
'*******************************************************************************
RECEIVE_GP_SENTENCE:
Clear GPS_CHARPOS
Clear GPS_RXBUFF
Repeat ' Create a loop to receive the serial string
HSerIn [GPS_CHAR] ' Receive a character serially
If GPS_CHAR = 13 Then Break ' Exit the loop if the string reaches the end
GPS_RXBUFF[GPS_CHARPOS] = GPS_CHAR ' Convert ASCII to INT and load array GPS_RXBUFF
Inc GPS_CHARPOS
Until GPS_CHARPOS > GPS_RXBUFFER_LENGTH ' Repeat the loop until the buffer runs out
Return
'*******************************************************************************
NMEA_WRITE:
If MODE <> 0 Then
High LED
If MODE.0 = 1 Then
SD_IO_String = "$GPRMC" + Str GPRMC_STR + 13 + 10
Response = SD_Write_String_To_File
EndIf
If MODE.1 = 1 Then
Select GPGSV_TOT
Case 1
SD_IO_String = "$GPGSV,1,1" + Str GPGSV_STR + 13 + 10
Response = SD_Write_String_To_File
Case 2
SD_IO_String = "$GPGSV,2,1" + Str GPGSV_STR1 + 13 + 10
Response = SD_Write_String_To_File
SD_IO_String = "$GPGSV,2,2" + Str GPGSV_STR2 + 13 + 10
Response = SD_Write_String_To_File
Case 3
SD_IO_String = "$GPGSV,3,1" + Str GPGSV_STR1 + 13 + 10
Response = SD_Write_String_To_File
SD_IO_String = "$GPGSV,3,2" + Str GPGSV_STR2 + 13 + 10
Response = SD_Write_String_To_File
SD_IO_String = "$GPGSV,3,3" + Str GPGSV_STR3 + 13 + 10
Response = SD_Write_String_To_File
EndSelect
EndIf
If MODE.2 = 1 Then
SD_IO_String = "$GPGSA" + Str GPGSA_STR + 13 + 10
Response = SD_Write_String_To_File
EndIf
If MODE.3 = 1 Then
SD_IO_String = "$GPGGA" + Str GPGGA_STR + 13 + 10
Response = SD_Write_String_To_File
EndIf
Inc IDX_SAVE
If IDX_SAVE = 255 Then
Response = SD_Save_File
IDX_SAVE = 0
EndIf
Low LED
EndIf
Return
'*******************************************************************************
GPGGA_EXTRACT:
Clear GPS_RXBUFF
HSerIn [Wait("$GPGGA")]
GPS_CHARPOS = 0
Repeat ' Create a loop to receive the serial string
HSerIn [GPS_CHAR] ' Receive a character serially
If GPS_CHAR = 13 Then Break ' Exit the loop if the string reaches the end
GPGGA_STR[GPS_CHARPOS] = GPS_CHAR ' Convert ASCII to INT and load array GPS_RXBUFF
Inc GPS_CHARPOS
Until GPS_CHARPOS > GPS_RXBUFFER_LENGTH ' Repeat the loop until the buffer runs out
Return
'*******************************************************************************
GPGGA_PROCESS:
Str GPS_RXBUFF = Str GPGGA_STR
If MODE.7 = 1 Then
'GET LAT
GPS_EXTRACT_ITEM = 2
GoSub EXTRACT_THE_VALUE
Str STF_STRING_IN = Str GPS_DATA_STRING
GoSub STRING_TO_FLOAT
LAT = STF_RESULT / 100
StrN DDMM_STRING_IN = Str$(DEC6 LAT)
GoSub DDMM_TO_FLOAT
LAT = DDMM_RESULT
'GET LAT SIGN
GPS_EXTRACT_ITEM = 3
GoSub EXTRACT_THE_VALUE
If GPS_DATA_STRING[0] = "N" Then SIGN_LAT = 1
If GPS_DATA_STRING[0] = "S" Then SIGN_LAT = -1
LAT = LAT * SIGN_LAT
'GET LON
GPS_EXTRACT_ITEM = 4
GoSub EXTRACT_THE_VALUE
Str STF_STRING_IN = Str GPS_DATA_STRING
GoSub STRING_TO_FLOAT
LON = STF_RESULT / 100
StrN DDMM_STRING_IN = Str$(DEC6 LON)
GoSub DDMM_TO_FLOAT
LON = DDMM_RESULT
'GET LON SIGN
GPS_EXTRACT_ITEM = 5
GoSub EXTRACT_THE_VALUE
If GPS_DATA_STRING[0] = "W" Then SIGN_LONG = -1
If GPS_DATA_STRING[0] = "E" Then SIGN_LONG = 1
LON = LON * SIGN_LONG
EndIf
'GET FIX - Always Get Fix
GPS_EXTRACT_ITEM = 6
GoSub EXTRACT_THE_VALUE
FIX = Val(GPS_DATA_STRING,Dec)
If MODE.2 = 1 Then
'GET SAT
GPS_EXTRACT_ITEM = 7
GoSub EXTRACT_THE_VALUE
SAT = Val(GPS_DATA_STRING,Dec)
EndIf
If MODE.5 = 1 Then
'GET ALT
GPS_EXTRACT_ITEM = 9
GoSub EXTRACT_THE_VALUE
Str STF_STRING_IN = Str GPS_DATA_STRING
GoSub STRING_TO_FLOAT
ALT = STF_RESULT
EndIf
Return
'*******************************************************************************
GPRMC_EXTRACT:
Clear GPS_RXBUFF
HSerIn [Wait("$GPRMC")]
GPS_CHARPOS = 0
Repeat ' Create a loop to receive the serial string
HSerIn [GPS_CHAR]
If GPS_CHAR = 13 Then Break ' Exit the loop if the string reaches the end
GPRMC_STR[GPS_CHARPOS] = GPS_CHAR ' Convert ASCII to INT and load array GPS_RXBUFF
Inc GPS_CHARPOS
Until GPS_CHARPOS > GPS_RXBUFFER_LENGTH ' Repeat the loop until the buffer runs out
Return
'*******************************************************************************
GPRMC_PROCESS:
Str GPS_RXBUFF = Str GPRMC_STR
If MODE.0 = 1 Then
'GET TIME
GPS_EXTRACT_ITEM = 1
GoSub EXTRACT_THE_VALUE
SD_Hours = (GPS_DATA_STRING[0] - 48) * 10
SD_Hours = (GPS_DATA_STRING[1] - 48) + SD_Hours
SD_Minutes = (GPS_DATA_STRING[2] - 48) * 10
SD_Minutes = (GPS_DATA_STRING[3] - 48) + SD_Minutes
SD_Seconds = (GPS_DATA_STRING[4] - 48) * 10
SD_Seconds = (GPS_DATA_STRING[5] - 48) + SD_Seconds
SD_MSeconds = (GPS_DATA_STRING[6] - 48) * 10
SD_MSeconds = (GPS_DATA_STRING[7] - 48) + SD_MSeconds
'GET DATE
GPS_EXTRACT_ITEM = 9
GoSub EXTRACT_THE_VALUE
SD_Day = (GPS_DATA_STRING[0] - 48) * 10
SD_Day = (GPS_DATA_STRING[1] - 48) + SD_Day
SD_Month = (GPS_DATA_STRING[2] - 48) * 10
SD_Month = (GPS_DATA_STRING[3] - 48) + SD_Month
SD_Year = (GPS_DATA_STRING[4] - 48) * 10
SD_Year = (GPS_DATA_STRING[5] - 48) + SD_Year
EndIf
If MODE.3 = 1 Then
'GET SPD
GPS_EXTRACT_ITEM = 7
GoSub EXTRACT_THE_VALUE
Str STF_STRING_IN = Str GPS_DATA_STRING
GoSub STRING_TO_FLOAT
SPD = STF_RESULT * 1.150779448 'KNOTS -> MPH
EndIf
If MODE.4 = 1 Then
'GET HDG
GPS_EXTRACT_ITEM = 8
GoSub EXTRACT_THE_VALUE
Str STF_STRING_IN = Str GPS_DATA_STRING
GoSub STRING_TO_FLOAT
HDG = STF_RESULT
EndIf
Return
'*******************************************************************************
GPGSA_EXTRACT:
Clear GPS_RXBUFF
HSerIn [Wait("$GPGSA")]
GPS_CHARPOS = 0
Repeat ' Create a loop to receive the serial string
HSerIn [GPS_CHAR]
If GPS_CHAR = 13 Then Break ' Exit the loop if the string reaches the end
GPGSA_STR[GPS_CHARPOS] = GPS_CHAR ' Convert ASCII to INT and load array GPS_RXBUFF
Inc GPS_CHARPOS
Until GPS_CHARPOS > GPS_RXBUFFER_LENGTH ' Repeat the loop until the buffer runs out
Return
'*******************************************************************************
GPGSA_PROCESS:
Str GPS_RXBUFF = Str GPGSA_STR
If MODE.2 = 1 Then
'GET PDOP
GPS_EXTRACT_ITEM = 15
GoSub EXTRACT_THE_VALUE
Str STF_STRING_IN = Str GPS_DATA_STRING
GoSub STRING_TO_FLOAT
PDOP = STF_RESULT
'GET HDOP
GPS_EXTRACT_ITEM = 16
GoSub EXTRACT_THE_VALUE
Str STF_STRING_IN = Str GPS_DATA_STRING
GoSub STRING_TO_FLOAT
HDOP = STF_RESULT
'GET VDOP
GPS_EXTRACT_ITEM = 17
GoSub EXTRACT_THE_VALUE
Str STF_STRING_IN = Str GPS_DATA_STRING
GoSub STRING_TO_FLOAT
VDOP = STF_RESULT
EndIf
Return
'*******************************************************************************
KML_WRITE:
If FIXED = 0 Or FIX > 0 Then 'Test whether it's okay to write data or not
High LED
If MODE.6 = 1 Then SD_IO_String = Str$(DEC8 LAT) + "," + Str$(DEC8 LON)
If MODE.5 = 1 Then SD_IO_String = SD_IO_String + "," + Str$(DEC1 ALT)
If MODE.4 = 1 Then SD_IO_String = SD_IO_String + "," + Str$(DEC1 HDG)
If MODE.3 = 1 Then SD_IO_String = SD_IO_String + "," + Str$(DEC1 SPD)
If MODE.2 = 1 Then SD_IO_String = SD_IO_String + "," + Str$(Dec SAT) + "," + Str$(DEC1 PDOP) + "," + Str$(DEC1 HDOP) + "," + Str$(DEC1 VDOP)
If MODE.1 = 1 Then SD_IO_String = SD_IO_String + "," + Str$(Dec FIX)
If MODE.0 = 1 Then
SD_IO_String = SD_IO_String + "," + Str$(Dec SD_Hours) + ":" + Str$(Dec SD_Minutes) + ":" + Str$(Dec SD_Seconds)
SD_IO_String = SD_IO_String + "," + Str$(Dec SD_Day) + "/" + Str$(Dec SD_Month) + "/" + Str$(Dec SD_Year + 2000)
EndIf
'SD_IO_String = SD_IO_String + "," + Str$(Dec BATTERY) + "," + Str$(DEC4 VOLTSB)
'SD_IO_String = SD_IO_String + "," + Str$(Dec COUNTS) + "," + Str$(DEC4 TEMPC) + "," + Str$(DEC4 TEMPF)
'SD_IO_String = SD_IO_String + "," + Str$(DEC1 TEMPC) + "," + Str$(DEC1 TEMPF)
SD_IO_String = SD_IO_String + 13 + 10
Response = SD_Write_String_To_File
Inc IDX_SAVE
If IDX_SAVE = 255 Then
Response = SD_Save_File
IDX_SAVE = 0
EndIf
Low LED
Else
GoSub NO_FIX_BLINK
EndIf
Return
'*******************************************************************************
EXTRACT_THE_VALUE:
Clear GPS_DATA_STRING
GPS_COMMA_COUNT = 0 ' Reset the comma counting variable
GPS_CHARPOS = 0 ' Start at the beginning of the array
Repeat
GPS_CHAR = GPS_RXBUFF[GPS_CHARPOS] ' Scan the array to parse
If GPS_CHAR = "," Then Inc GPS_COMMA_COUNT ' Increment GPS_COMMA_COUNT if a comma is found
If GPS_COMMA_COUNT = GPS_EXTRACT_ITEM Then ' Have we found the correct comma ?
GPS_BLOOP = 0 ' Yes. So....
Repeat ' Form a loop
Inc GPS_CHARPOS ' Skip over the comma and keep scanning the array
GPS_CHAR = GPS_RXBUFF[GPS_CHARPOS] ' Extract the pieces of the value into GPS_CHAR
If GPS_CHAR = 0 Then Return
If GPS_CHAR = "," Then Return
GPS_DATA_STRING[GPS_BLOOP] = GPS_CHAR'- 48 ' Fill GPS_DATA_STRING with the value, (converted into integers)
Inc GPS_BLOOP ' Point to the next data piece
Until GPS_CHARPOS > GPS_RXBUFFER_LENGTH ' Keep looping until a terminator is found, or the array runs out
Return
EndIf
Inc GPS_CHARPOS
Until GPS_CHARPOS > GPS_RXBUFFER_LENGTH
Return
'*******************************************************************************
STRING_TO_FLOAT:
STF_POWER_10 = 1
STF_RESULT = 0
STF_SIGN = 0
STF_CHARPOS = 0
STF_CHAR = STF_STRING_IN[STF_CHARPOS] ' \ Get a character from the String
Inc STF_CHARPOS ' /
If STF_CHAR = "-" Then ' Have we found a "-" character ?
STF_CHAR = STF_STRING_IN[STF_CHARPOS] ' \ Yes. So Discard the "-" character
Inc STF_CHARPOS ' /
STF_SIGN = 1 ' Indicate that the value is negative
Else If STF_CHAR = "+" Then ' Have we found a "+" character ?
STF_CHAR = STF_STRING_IN[STF_CHARPOS] ' \ Yes. So Discard the "+" character
Inc STF_CHARPOS ' /
EndIf
While 1 = 1 ' Scan the digits before the decimal point (if included)
If STF_CHAR < "0" Then Break ' \
If STF_CHAR > "9" Then Break ' / Exit the loop if non numeric characters found
STF_RESULT = STF_RESULT * 10 ' \
STF_RESULT = STF_RESULT + STF_CHAR ' Calculate the whole part of the floating point value
STF_RESULT = STF_RESULT - "0" ' /
STF_CHAR = STF_STRING_IN[STF_CHARPOS] ' \
Inc STF_CHARPOS ' / Get another character from the string
Wend
If STF_CHAR == "." Then ' Have we found a "." character ?
STF_CHAR = STF_STRING_IN[STF_CHARPOS] ' \ Yes. So Discard the "." character
Inc STF_CHARPOS ' /
While 1 = 1 ' Scan the digits after the decimal point (if included)
If STF_CHAR < "0" Then Break ' \
If STF_CHAR > "9" Then Break ' / Exit the loop if non numeric characters found
STF_POWER_10 = STF_POWER_10 * 10 ' \
STF_TEMP = (STF_CHAR - "0") / STF_POWER_10 ' Calculate the fractional part of the floating point value
STF_RESULT = STF_RESULT + STF_TEMP ' /
STF_CHAR = STF_STRING_IN[STF_CHARPOS] ' \
Inc STF_CHARPOS ' / Get another character from the string
Wend
EndIf
If STF_SIGN = 1 Then STF_RESULT = -STF_RESULT ' Convert to negative if required
Return
'-------------------------------------------------------------------------------
'Convert from DD.MMSS to Decimal Degrees
DDMM_TO_FLOAT:
DDMM_POWER_10 = 1
DDMM_RESULT = 0
DDMM_SIGN = 0
DDMM_CHARPOS = 0
DDMM_CHARPOS_LOW = 0
DDMM_CHAR = DDMM_STRING_IN[DDMM_CHARPOS] ' \ Get a character from the String
Inc DDMM_CHARPOS ' /
If DDMM_CHAR = "-" Then ' Have we found a "-" character ?
DDMM_CHAR = DDMM_STRING_IN[DDMM_CHARPOS] ' \ Yes. So Discard the "-" character
Inc DDMM_CHARPOS ' /
DDMM_SIGN = 1 ' Indicate that the value is negative
Else If DDMM_CHAR = "+" Then ' Have we found a "+" character ?
DDMM_CHAR = DDMM_STRING_IN[DDMM_CHARPOS] ' \ Yes. So Discard the "+" character
Inc DDMM_CHARPOS ' /
EndIf
While 1 = 1 ' Scan the digits before the decimal point (if included)
If DDMM_CHAR < "0" Then Break ' \
If DDMM_CHAR > "9" Then Break ' / Exit the loop if non numeric characters found
DDMM_RESULT = DDMM_RESULT * 10 ' \
DDMM_RESULT = DDMM_RESULT + DDMM_CHAR ' Calculate the whole part of the floating point value
DDMM_RESULT = DDMM_RESULT - "0" ' /
DDMM_CHAR = DDMM_STRING_IN[DDMM_CHARPOS] ' \
Inc DDMM_CHARPOS ' / Get another character from the string
Wend
If DDMM_CHAR == "." Then ' Have we found a "." character ?
DDMM_CHAR = DDMM_STRING_IN[DDMM_CHARPOS] ' \ Yes. So Discard the "." character
Inc DDMM_CHARPOS ' /
While 1 = 1 ' Scan the digits after the decimal point (if included)
If DDMM_CHAR < "0" Then Break ' \
If DDMM_CHAR > "9" Then Break ' / Exit the loop if non numeric characters found
DDMM_TEMP_STR[DDMM_CHARPOS_LOW] = DDMM_CHAR
DDMM_CHAR = DDMM_STRING_IN[DDMM_CHARPOS] ' \
Inc DDMM_CHARPOS ' / Get another character from the string
Inc DDMM_CHARPOS_LOW
If DDMM_CHARPOS_LOW = 5 Then Break 'Quit at DEC6
Wend
DDMM_TEMP = Val(DDMM_TEMP_STR,Dec) ' Convert String to Decimal
DDMM_TEMP = DDMM_TEMP / 60000 ' Convert .MMMMM to .DDDD
DDMM_RESULT = DDMM_RESULT + DDMM_TEMP
EndIf
If DDMM_SIGN = 1 Then DDMM_RESULT = -DDMM_RESULT ' Convert to negative if required
Return
'*******************************************************************************
READ_CONFIG_VALUE:
Clear CONFIG_BUFF
Clear CONFIG_VALUE
Clear CONFIG_IDX
Repeat
Response = SD_Read_Byte_From_File
If Response = "," Then Break
If Response = 13 Then Break
If Response = 10 Then Break
CONFIG_BUFF[CONFIG_IDX] = Response
Inc CONFIG_IDX
Until CONFIG_IDX = 50
Return
'*******************************************************************************
READ_CONFIG_EPROM:
INTERVAL_EPROM.HighByte = ERead 2
INTERVAL_EPROM.LowByte = ERead 3
MODE_EPROM = ERead 4
FIXED_EPROM = ERead 5
Return
'*******************************************************************************
WRITE_CONFIG_EPROM:
EWrite 2,[INTERVAL.HighByte]
EWrite 3,[INTERVAL.LowByte]
EWrite 4,[MODE]
EWrite 5,[FIXED]
Return
'*******************************************************************************
WRITE_CONFIG_FILE:
SD_File_Name = "CONFIG"
SD_File_Ext = "CSV"
Response = SD_New_File
SD_IO_String = Str$(Dec INTERVAL) + "," + Str$(BIN8 MODE) + "," + Str$(Dec FIXED) + 13 + 10
Response = SD_Write_String_To_File
SD_IO_String = "INTERVAL,OPTIONS,FIXED" + 13 + 10
Response = SD_Write_String_To_File
SD_IO_String = "INTERVAL (0-65536) SECONDS" + 13 + 10
Response = SD_Write_String_To_File
SD_IO_String = "NMEA MODE[7]=0 (MODE[7] NC[6] NC[5] NC[4] GPGGA[3] GPGSA[2] GPGSV[1] GPRMC[0])" + 13 + 10
Response = SD_Write_String_To_File
SD_IO_String = "KML MODE[7]=1 (MODE[7] LAT/LONG[6] ALT[5] HDG[4] SPD[3] SAT/DOP[2] FIX[1] TIME/DATE[0])" + 13 + 10
Response = SD_Write_String_To_File
SD_IO_String = "LATITUDE(DD.MMMMMM),LONGITUDE(DD.MMMMMM),ALTITUDE(M),HEADING,SPEED(MPH),SATELLITES,PDOP,HDOP,VDOP,FIX,UTC TIME(HH:MM:SS),DATE(DD/MM/YR)" + 13 + 10
Response = SD_Write_String_To_File
SD_IO_String = "BIT[X]=0=OFF" + 13 + 10
Response = SD_Write_String_To_File
SD_IO_String = "BIT[X]=1=ON" + 13 + 10
Response = SD_Write_String_To_File
SD_IO_String = "FIXED = 0 - DATA ALWAYS WRITTEN" + 13 + 10
Response = SD_Write_String_To_File
SD_IO_String = "FIXED = 1 - DATA ONLY WRITTEN WHEN GPS HAS SATELLITE FIX" + 13 + 10
Response = SD_Write_String_To_File
SD_IO_String = "*NOTE - FIXED OPTION ONLY USED IN KML MODE"
Response = SD_Write_String_To_File
Response = SD_Close_File
Return
'*******************************************************************************
LED_TEST:
Clear BLINKS
Repeat
High LED
DelayMS 150
Low LED
DelayMS 150
Inc BLINKS
Until BLINKS = NUM_BLINKS
DelayMS 250
Return
'*******************************************************************************
NO_FIX_BLINK:
Clear BLINKS
Repeat
High LED
DelayMS 150
Low LED
DelayMS 150
Inc BLINKS
Until BLINKS = 2
Return
'*******************************************************************************
LOW_BAT_BLINK:
Clear BLINKS
Repeat
High LED
DelayMS 150
Low LED
DelayMS 150
Inc BLINKS
Until BLINKS = 4
Return
'*******************************************************************************
'DEFAULT-EPROM
EData As Byte 0, 0, 0, 0, %11111111, 0
'*******************************************************************************
'HSERIAL BAUD MODES - 1200,2400,4800,9600,19200,38400
HSERIAL_RCSTA_DATA: CData As Byte $90,$90,$90,$90,$90,$90,$90,$90
HSERIAL_TXSTA_DATA: CData As Byte $20,$20,$20,$20,$20,$20,$24,$24
HSERIAL_SPBRG_DATA: CData As Byte 255,129,64,32,15,7,21,10
US Distributor of PDS - http://www.ohararp.com/compilers.html
$25 SMT Kapton Stencils - http://www.ohararp.com/


Menu
Recent Articles


Using PDS with SPI GLCD based on ST7565R Controller
Graphic LCDs based on the ST7565 are cheaper then GLCDs with other controllers. SPI requires only four pins. If the circuit