• PicŪ Basic


  • GPS code example

    Original Post by Ryan 'ohararp'

    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/
    This article was originally published in forum thread: GPS code example started by John Drew View original post
  • Recent Activity

    Gerard-23282

    12F1572 and PWM

    Thread Starter: Gerard

    Hello, when I write HPWM PORTA.0, 50, 100 I have the following message when compiling ERROR : Device does not contain any hardware PWM channels!...

    Gerard Today, 14:53 Go to last post
    mahmood-24694

    LM75 smalest temp. indicator

    Thread Starter: mahmood

    Hi all this thermal sensor (LM75) works just with one 3pin LED. consider 25' C. the red led blink twice and green led blink five time. it so...

    mahmood Yesterday, 22:43 Go to last post