How do I discern Maidenhead Locator from GPS lat long info.


Closed Thread
Results 1 to 40 of 126

Hybrid View

  1. #1
    Join Date
    Dec 2011
    Location
    IO93ok
    Posts
    190

    Default Re: How do I discern Maidenhead Locator from GPS lat long info.

    This is the full code with the Ints active but it's just updating first character.

    Code:
    ;
    ;        GPS NMEA Display code with GPSDO monitoring
    ;
    ; 			         PIC16F876A                             
    ;                                   __________                                          
    ;                          !MCLR |1        28| RB7------D7              
    ;     PLL Volt--AN0---RA0 |2        27| RB6------D6          
    ;    adc spare--AN1---RA1 |3        26| RB5------D5                     
    ;    adc spare--AN2---RA2 |4        25| RB4------D4                     
    ;    adc spare--AN3---RA3 |5        24| RB3------LCD E                     
    ;                  spare---RA4 |6        23| RB2------LCD RS                
    ;    adc spare--AN4---RA5 |7        22| RB1------spare
    ;                Ground---Vss |8        21| RB0------PPS In      
    ;                OSC1---XTAL |9        20| VDD------ +5 V        
    ;                OSC2---XTAL |10       19| Vss------Ground
    ;                  spare---RC0 |11       18| RC7------H-RX -- GPS NMEA In
    ;                  spare---RC1 |12       17| RC6------H-TX -- GPS Command Out
    ;                  spare---RC2 |13       16| RC5------spare
    ;               Pbutton---RC3 |14       15| RC4------spare           
    ;                                       ----------                                               
    ;====================================================================='
    ' Program to display returned value of a GPS NMEA string on RA4
    ' LCD in 4-BIT mode PIC16F876a controller 4Mhz clock Fuse PWRT BODEN
    ' 
    'Typical GPS sentence string: $GPRMC,192144.62,A,5041.6058,N,00412.6124,E,0.45,3 57.74,081205,,*0B
    
    'The default sentences are continuously output. 
    'Now suppose I want to read only one particular sentence I need to program the GPS to do that.
    
    'The input message  ILOG controls which sentences are logged.
    
    '$PRWIILOG,???,V,,,\r,\n
    
    'Inputting this sentence, disables all the sentences.
    
    'Now suppose we want only RMC sentence then input the following sentence serially to gps
    
    '$PRWIILOG,RMC,A,,,,\r\n
    
    'The \r() and \n () are sentence terminator in NMEA
    
    'V disables that particular sentence while A enables that sentence.
    
    
    
    @  __config  _HS_OSC & _WDT_ON & _PWRTE_ON & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _WRT_OFF & _DEBUG_OFF & _CP_OFF
    
    
    ; Place a copy of these variables in your Main program for digit characters--
    ;--   The compiler will tell you which lines to un-comment                --
    ;--   Do Not un-comment these lines                                       --
    ;---------------------------------------------------------------------------
    ;wsave   VAR BYTE    $20     SYSTEM      ' location for W if in bank0
    wsave   VAR BYTE    $70     SYSTEM       ' alternate save location for W 
                                             ' if using $70, comment wsave1-3
    
    ' --- IF any of these three lines cause an error ?? ------------------------
    '       Comment them out to fix the problem ----
    ' -- Which variables are needed, depends on the Chip you are using -- 
    'wsave1  VAR BYTE    $A0     SYSTEM      ' location for W if in bank1
    'wsave2  VAR BYTE    $120    SYSTEM      ' location for W if in bank2
    ;wsave3  VAR BYTE    $1A0    SYSTEM      ' location for W if in bank3
    ' --------------------------------------------------------------------------
    
                              ; Must use the 32-bit Floating Point routines
    INCLUDE "FP2032.bas"      ; 32-bit Floating Point for 14-bit cores with RAM at $20
    INCLUDE "Average.bas"     ; DT's 16-bit Analog Module averaging values
    INCLUDE "DT_INTS-14.bas"  ; Base Interrupt System
    INCLUDE "ReEnterPBP.bas"
    
    Define LCD_DREG PORTB     ' Port for LCD Data
    Define LCD_DBIT 4         ' Set LCD starting data bit  
    Define LCD_RSREG PORTB    ' Port for RegisterSelect (RS) bit
    Define LCD_RSBIT 2        ' Port Pin for RS bit  (pin9)
    Define LCD_EREG PORTB     ' Port for Enable (E) bit
    Define LCD_EBIT 3         ' Port Pin for E bit    (pin7)
    Define LCB_BITS 4         ' Using 4-bit bus
    
    Define LCD_COMMANDUS 1500 ' Command Delay (uS)
    define LCD_DATAUS 50      ' Data Delay (uS)
    
    DEFINE OSC 4
    
    DEFINE ADC_BITS 10        ' Setup ADC 
    DEFINE ADC_SAMPLEUS 5
    DEFINE ADC_CLOCK 1
    
    DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
    DEFINE HSER_BAUD 4800
    DEFINE HSER_CLROERR 1 ' Clear overflow automatically
    
    OPTION_REG.6 = 1            ' Interrupt rising edge
    OPTION_REG.7 = 0            ' Enable Pull-Up's
    
    PPS VAR PORTB.0
    Pbutton VAR PORTC.3
    
    ' Initialise ADC
    ADCON1 = %10000100 ' Set PORTA analog and RIGHT justify result
    ADCON0 = %01000001 ' Configure and turn on A/D Module channel 0 Fosc 8
    
    'Declare variables
    volt VAR WORD     ' scaled value real part
    voltd1 VAR WORD   ' scaled value first decimal place
    voltd2 VAR WORD   ' scaled value second decimal place
    
    'Allocate Variables for GPS: ####################
    TimeOut CON 2000            
                                                                
    hh VAR BYTE             'hours
    mm VAR BYTE             'minutes
    ss VAR BYTE             'seconds
    knots VAR WORD          'speed in knots (units)
    knotsten VAR BYTE       'speed in knots (tens)
    course VAR WORD         'heading
    latdeg VAR BYTE         'degrees latitude
    latmin VAR BYTE         'minutes latitude
    latsecs VAR WORD        'seconds latitude
    NS VAR BYTE             'north or south
    londeg VAR BYTE         'degrees longitude
    lonmin VAR BYTE         'minutes longitude
    lonsecs VAR WORD        'seconds longtitude
    EW VAR BYTE             'east or west
    d VAR BYTE              'day
    m VAR BYTE              'month
    y VAR BYTE              'year
    
    ;###################################################
    
    butt VAR BYTE           'pushbutton variable
    marker VAR BYTE         'toggle marker
    marker2 VAR BYTE        'UTC or BST
    
    MH     VAR BYTE[10]     'locator variables##########
                                                       ;
    Idx       VAR BYTE                                 ;
    AddChar   VAR BYTE                                 ;
    Divisor   VAR BYTE[4]                              ;
    AARG_SAVE VAR BYTE[4]   '----------------###########
    
    nPos  var byte          ' digit variables
    nDig  var byte          '--------------------
    
    Idx2 VAR BYTE           ' Month variables
    X VAR BYTE                                  ;
    Char VAR WORD           '--------------------
    
    scroll VAR BYTE
    
    fix VAR BYTE            'GPS fix - Yes="A"  No="V"
    
    butt = 0                ;clear button variable
    marker = 0              ;set marker to zero for full info display at start
    marker2 = 0             ;set UTC
    PAUSE 50
    
    ;--------------------------------------------------------------------------
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler    INT_INT,        _Clock,      PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    ;--------------------------------------------------------------------------  
    @   INT_ENABLE   INT_INT     ; enable external (INT) interrupts    
                             
    LCDOut $fe,$80,"    GPS Decoder     "   ; scrolling opening display
    LCDOut $FE,$c0," G8VLQ  March 2014  "
    Pause 2000
       for scroll = 1 to 20                 ' FOR..NEXT loop so message scrolls off the LCD to the left
                lcdout $fe,24               ' Scrolls display one position to the left
                pause 100                   ' Pause 150 ms
       next scroll                          ' do loop again till max count
                pause 1500                   ' Pause 1000ms       
                lcdout $fe,1                ' Clears LCD 
    
    ;------------------------------------------------
    
    Initialisation:    ;Leaving GPRMC as only sentence output     
    HSEROUT ["$PRWIILOG,GGA,V,,,",13,10]
    PAUSE 100            
    HSEROUT ["$PRWIILOG,GSA,V,,,",13,10]
    PAUSE 100
    HSEROUT ["$PRWIILOG,GSV,V,,,",13,10]
    PAUSE 100
    HSEROUT ["$PRWIILOG,ZCH,V,,,",13,10]
    PAUSE 100
                
    ;-------------------------------------------------            
                
    
    GPS: 'read GPS  #############################################################################################
    
    HSerIn Timeout,Clock,[wait("$GPRMC"),wait(","),DEC2 hh,DEC2 mm,DEC2 ss,wait(","),fix,wait(","),DEC2 _
    latdeg,DEC2 latmin,wait("."),DEC4 latsecs,wait(","),NS,wait(","),DEC3 londeg,DEC2 lonmin,wait("."),DEC4 lonsecs,_
    wait(","),EW,wait(","),knots,wait("."),DEC2 knotsten,wait(","),DEC3 course,wait(","),DEC2 d,DEC2 m,DEC2 y]
    
    IF marker = 1 THEN BigClock     ; keeps big clock running if value is 1
    IF marker2 = 1 THEN Plusone                                                                    
                        ;--------------------------------------------------------                                                         ;
    
    BUTTON Pbutton,0,100,0,butt,1,BigClockClear      ;button press to jump to fullscreen big clock
    
    GOSUB PLL         ;get the A/D value of pll control voltage
    GOSUB ShowMonth   ;show month as letters
    GOSUB Locator     ;maidenhead locator
    ;GOSUB BST
    GOSUB Clock       ;medium digit clock
    
    goto GPS          ; ##########################################################################################
    
    ;---------------------------------------------------------------
    ;         MAIDENHEAD CONVERSION   --  Darrel Taylor
    ;---------------------------------------------------------------
    Locator:
    ASM
    MOVE?CF32  macro C, F       ; put a Floating Point Constant in an FP variable
        MOVE?CW  (C & 0xFFFF), F
        MOVE?CW  (C >> 16), F + 2
      endm
    
    MOVE?FF32  macro Fin, Fout  ; Copy an FP var to another FP var
        MOVE?WW  Fin, Fout
        MOVE?WW  Fin + 2, Fout + 2
      endm
    ENDASM
    ;-------------------------------------------------------------------------------
    
    ;----[convert Longitude Sexagesimal to Decimal Degrees]-------------------------
    Aint = lonsecs : GOSUB ItoFA    ; decimal portion of Minutes
    Bint = 10000 : GOSUB ItoFB          ; divided by 100
    GOSUB fpdiv
    Bint = LonMin : GOSUB ItoFB       ; add whole portion of Minutes
    GOSUB fpadd
    Bint = 60 : GOSUB ItoFB           ; divide by 60
    GOSUB fpdiv
    Bint = LonDeg : GOSUB ItoFB       ; add degrees
    GOSUB fpadd
    IF EW = "W" THEN              ; if west of Prime Meridian
        @ MOVE?FF32 AARGB2, BARGB2    ; copy Float AARG to BARG
        Aint = 0    : GOSUB ItoFA     ; subtract from 0 to negate
        GOSUB fpsub
    ENDIF
    
    Bint = 180  : GOSUB ItoFB         ; add 180
    GOSUB fpadd
    
    ;----[Have Longitude in AARG as Float]------------------------------------------
    
    FOR Idx = 0 TO 8 STEP 2
        SELECT CASE Idx
          CASE 0 : AddChar = "A"
                   @ MOVE?CF32 0x83200000, _Divisor   ; 20
          CASE 2 : AddChar = "0"
                   @ MOVE?CF32 0x80000000, _Divisor   ; 2
          CASE 4 : AddChar = "a"
                   @ MOVE?CF32 0x7B2AAAAB, _Divisor   ; 0.0833333
          CASE 6 : AddChar = "0"
                   @ MOVE?CF32 0x78088889, _Divisor   ; 0.00833333
          CASE 8 : AddChar = "a"
                   @ MOVE?CF32 0x73360B61, _Divisor   ; 0.000347222
        END SELECT
        GOSUB MH_Digit
    NEXT Idx
    
    ;----[convert Latitude Sexagesimal to Decimal Degrees]--------------------------
    
    Aint = latsecs : GOSUB ItoFA    ; decimal portion of Minutes
    Bint = 10000 : GOSUB ItoFB          ; divided by 100
    GOSUB fpdiv
    Bint = LatMin : GOSUB ItoFB       ; add whole portion of Minutes
    GOSUB fpadd
    Bint = 60 : GOSUB ItoFB           ; divide by 60
    GOSUB fpdiv
    Bint = LatDeg : GOSUB ItoFB       ; add degrees
    GOSUB fpadd
    IF NS = "S" THEN              ; if south of equator
        @ MOVE?FF32 AARGB2, BARGB2    ; copy Float AARG to BARG
        Aint = 0    : GOSUB ItoFA     ; subtract from 0 to negate
        GOSUB fpsub
    ENDIF
    
    Bint = 90  : GOSUB ItoFB          ; add 90
    GOSUB fpadd
    
    ;----[Have Latitude  in AARG as Float]------------------------------------------
    
    FOR Idx = 1 TO 9 STEP 2
        SELECT CASE Idx
          CASE 1 : AddChar = "A"
                   @ MOVE?CF32 0x82200000, _Divisor   ; 10
          CASE 3 : AddChar = "0"
                   @ MOVE?CF32 0x7F000000, _Divisor   ; 1
          CASE 5 : AddChar = "a"
                   @ MOVE?CF32 0x7A2AAAAB, _Divisor   ; 0.0416666
          CASE 7 : AddChar = "0"
                   @ MOVE?CF32 0x770882F1, _Divisor   ; 0.00416666
          CASE 9 : AddChar = "a"
                   @ MOVE?CF32 0x723603EC, _Divisor   ; 0.000173583
        END SELECT
        GOSUB MH_Digit
    NEXT Idx
    ;----[Maidenhead conversion complete]-------------------------------------------
    
    RETURN
    
    ;----[Calculate one digit of the Maidenhead Locator]----------------------------
    
    MH_Digit:
        @ MOVE?FF32 _Divisor, BARGB2      ; put divisor in BARG
        GOSUB fpdiv                       ; do the divide
        @ MOVE?FF32 AARGB2, _AARG_SAVE    ; save AARG for modulus
    
        GOSUB FtoIA                       ; get integer
        MH(Idx) = Aint + AddChar          ; The Character
        Bint = Aint                       ; copy integer result to BARG
        GOSUB ItoFB                       ; convert it to float
        @ MOVE?FF32 _AARG_SAVE, AARGB2    ; restore previous AARG
        GOSUB fpsub                       ; subtract integer
    
        @ MOVE?FF32 _Divisor, BARGB2      ; multiply times original divisor
        GOSUB fpmul                       ; AARG now contains the remainder
    RETURN
    
    ;---------------------------------------------------------------------------
    ;         Month routine
    
    ShowMonth:
        LCDOut $fe,$80+9,DEC2 d," "
        GOSUB Month
        LCDOut " ","20",DEC2 y
        RETURN
    
    Month:
        Idx2 = (m - 1) * 3
        FOR X = Idx2 TO Idx2 + 2
            LOOKUP X,["JanFebMarAprMayJunJulAugSepOctNovDec"],Char
            LCDOUT Char
        NEXT X
    RETURN
    
    ;--------------------------------------------------------------------------
    ;                British Summer Time
    ;--------------------------------------------------------------------------
    
    BST:
     IF m = 3 AND d = 30 THEN Plusone
     IF m >= 03 and m <= 10 THEN Plusone 
    RETURN 
      
    Plusone:
      IF m = 10 and d = 26 then UTC
      IF m >=10 and m <3 then UTC
      hh = hh + 1
      IF hh = 25 THEN hh = 0
      marker2 = 1  
    RETURN  
      
    UTC:  
      marker2 = 0
    RETURN  
    
    ;--------------------------------------------------------------------------
    ;                PLL control voltage read result via Average routine
    ;--------------------------------------------------------------------------
    
    PLL:             ' Measure GPSDO PLL control voltage for TCXO  - Approx 1.65v for lock
    ADCON0.2 = 1     ' Start conversion
    NotDone:
    pause 1
    IF ADCON0.2 = 1 Then NotDone
    value =((ADRESH * 256)+(ADRESL))
    gosub Average
    ' Calculate Voltage to 2 decimal places
    volt = value * 5/1024
    voltd1 = ( value * 5//1024) * 10/1024
    voltd2 = ((value *5 //1024) * 10//1024) * 10/1024
    RETURN
    
    ;--------------------------------------------------------------------------
    
    lock:
    IF (volt=1) AND (voltd1 =6) AND (voltd2 =<9) THEN
    LCDOUT $FE,$C0+9,"Lock  "
    ENDIF
    RETURN 
    
    ;---------------------------------------------------------------------------
    
    ClockClear:             ;Returning from Big Digit Clock, need to clear screen
    
    LCDOut $FE, 1           ;Clear Screen
    marker = 0              ;set marker to full info display
    GOTO GPS
    
    ;--------------------------------------------------------------------------
    
    Clock:                   ;Display medium character time clock
    
    'Set up the digits (http://www.darreltaylor.com/files/CustChar.htm)
    LCDOUT  $FE,$40,$03,$03,$03,$03,$03,$03,$03,$03  ' Cust Char #0  
    LCDOUT  $FE,$48,$0E,$1F,$1B,$1B,$1B,$1B,$1B,$1B  ' Cust Char #1  
    LCDOUT  $FE,$50,$1F,$1F,$18,$18,$18,$18,$1F,$1F  ' Cust Char #2  
    LCDOUT  $FE,$58,$03,$03,$03,$03,$03,$03,$1F,$1F  ' Cust Char #3  
    LCDOUT  $FE,$60,$0E,$1F,$1B,$1B,$1B,$1B,$1F,$0E  ' Cust Char #4  
    LCDOUT  $FE,$68,$1B,$1B,$1B,$1B,$1B,$1B,$1F,$0E  ' Cust Char #5  
    LCDOUT  $FE,$70,$1F,$1F,$03,$03,$03,$03,$1F,$1F  ' Cust Char #6  
    LCDOUT  $FE,$78,$1E,$1F,$03,$03,$03,$03,$03,$03  ' Cust Char #7  
    					
    
        nDig=ss dig 0 : nPos=7 : gosub displaydigit      
        nDig=ss dig 1 : nPos=6 : gosub displaydigit      
          npos=5 : gosub colon                           
        ndig=mm dig 0 : npos=4 : gosub displaydigit      
        ndig=mm dig 1 : npos=3 : gosub displaydigit      
          npos=2 : gosub colon                           
        ndig=hh dig 0 : npos=1 : gosub displaydigit      
        ndig=hh dig 1 : npos=0 : gosub displaydigit      
        
    LCDOUT $FE,$C0+9,"False Data "            ;displays 
        
    IF fix = "A" THEN
    LCDOUT $FE,$C0+9,"Fix  ",#volt, ".", # voltd1,# voltd2,"v"            ;overwrites No Data
    GOSUB lock                                ;checks for pll lock if Fix valid
    ENDIF
        
    
    LCDOUT $fe,$94," G8VLQ  ",STR MH\10," " ;STR is 10 digit Maidenhead Locator
    LCDOut $fe,$d4,DEC2 latdeg,$DF,DEC2 latmin,"'",DEC latsecs DIG 3,DEC latsecs DIG 2,_
    NS,"  ",DEC2 londeg,$DF,DEC2 lonmin,"'",DEC lonsecs DIG 3,DEC lonsecs DIG 2,EW   
    ;$DF is degree symbol, some LCD displays have it in different location
    
    @ INT_RETURN 
    ;RETURN
    
    displaydigit:
    if ndig=0 then gosub zero
    if ndig=1 then gosub one
    if ndig=2 then gosub two
    if ndig=3 then gosub three
    if ndig=4 then gosub four
    if ndig=5 then gosub five
    if ndig=6 then gosub six
    if ndig=7 then gosub seven
    if ndig=8 then gosub eight
    if ndig=9 then gosub nine
    return
    
    Zero:
    	LCDOUT $FE,$80+nPos,1
    	LCDOUT $FE,$C0+nPos,5
    return
    
    One:
    	LCDOUT $FE,$80+nPos,0
    	LCDOUT $FE,$C0+nPos,0
    return
    
    Two:
    	LCDOUT $FE,$80+nPos,7
    	LCDOUT $FE,$C0+nPos,2
    return
    
    Three:
    	LCDOUT $FE,$80+nPos,6
    	LCDOUT $FE,$C0+nPos,3
    return
    
    Four:
    	LCDOUT $FE,$80+nPos,5
    	LCDOUT $FE,$C0+nPos,0
    return
    
    Five:
    	LCDOUT $FE,$80+nPos,2
    	LCDOUT $FE,$C0+nPos,3
    return
    
    Six:
    	LCDOUT $FE,$80+nPos,2
    	LCDOUT $FE,$C0+nPos,5
    return
    
    Seven:
    	LCDOUT $FE,$80+nPos,7
    	LCDOUT $FE,$C0+nPos,0
    return
    
    Eight:
    	LCDOUT $FE,$80+nPos,4
    	LCDOUT $FE,$C0+nPos,5
    return
    
    Nine:
    	LCDOUT $FE,$80+nPos,4
    	LCDOUT $FE,$C0+nPos,3
    return
    
    colon:
          lcdout $fe,$80+nPos,$A5   
          lcdout $FE,$C0+nPos,$A5   
    return
    
    ;---------------------------------------------------------------------------
    BigClockClear:
    
    LCDOut $FE, 1           ;Clear original full data screen
    marker = 1              ;set marker for fullscreen clock loop
    
    'Set up the digits (http://www.darreltaylor.com/files/CustChar.htm)
    'THICK DIGITS
    LCDOUT  $FE,$40,$07,$07,$07,$07,$07,$07,$07,$07  ' Cust Char #0  
    LCDOUT  $FE,$48,$1C,$1C,$1C,$1C,$1C,$1C,$1C,$1C  ' Cust Char #1  
    LCDOUT  $FE,$50,$0F,$1F,$1F,$1E,$1C,$1C,$1C,$1C  ' Cust Char #2 
    LCDOUT  $FE,$58,$1E,$1F,$1F,$0F,$07,$07,$07,$07  ' Cust Char #3  
    LCDOUT  $FE,$60,$1C,$1C,$1C,$1C,$1E,$1F,$1F,$0F  ' Cust Char #4  
    LCDOUT  $FE,$68,$07,$07,$07,$07,$0F,$1F,$1F,$1E  ' Cust Char #5  
    LCDOUT  $FE,$70,$1F,$1F,$1F,$00,$00,$00,$00,$00  ' Cust Char #6  
    LCDOUT  $FE,$78,$00,$00,$00,$00,$00,$1F,$1F,$1F  ' Cust Char #7 
    
    ;#############################################################################################
    
    GPS2:
    HSerIn Timeout,Clock,[wait("$GPRMC"),wait(","),DEC2 hh,DEC2 mm,DEC2 ss]
    
    ;############################################################################################## 
    
    BUTTON Pbutton,0,100,0,butt,1,ClockClear     ;button press to change back to full info display
                         
    BigClock:               ;Display Big Digit fullscreen clock 
    
        nDig=ss dig 0 : nPos=17 : gosub displaydigit1           
        nDig=ss dig 1 : nPos=14 : gosub displaydigit1           
                        npos=13 : gosub colon                    
        ndig=mm dig 0 : npos=10 : gosub displaydigit1           
        ndig=mm dig 1 : npos=7 : gosub displaydigit1            
                        npos=6 : gosub colon1                    
        ndig=hh dig 0 : npos=3 : gosub displaydigit1              
        ndig=hh dig 1 : npos=0 : gosub displaydigit1   
        
                   
        
    GOTO GPS2       
    
    displaydigit1:
    if ndig=0 then gosub Zero1
    if ndig=1 then gosub One1
    if ndig=2 then gosub Two1
    if ndig=3 then gosub Three1
    if ndig=4 then gosub Four1
    if ndig=5 then gosub Five1
    if ndig=6 then gosub Six1
    if ndig=7 then gosub Seven1
    if ndig=8 then gosub Eight1
    if ndig=9 then gosub Nine1
    return
    
    Zero1:
        LCDOUT $FE,$80+nPos,2
        LCDOUT $FE,$81+nPos,3     ;note added 1 to position for right side of character
        LCDOUT $FE,$C0+nPos,1
        LCDOUT $FE,$C1+nPos,0     ;note added 1
        LCDOUT $FE,$94+nPos,1
        LCDOUT $FE,$95+nPos,0     ;note added 1
        LCDOUT $FE,$D4+nPos,4
        LCDOUT $FE,$D5+nPos,5	;note added 1
    return
    
    One1:
          LCDOUT $FE,$80+nPos," "
    	LCDOUT $FE,$81+nPos,0
    	LCDOUT $FE,$C0+nPos," "
    	LCDOUT $FE,$C1+nPos,0
    	LCDOUT $FE,$94+nPos," "
    	LCDOUT $FE,$95+nPos,0
    	LCDOUT $FE,$D4+nPos," "
    	LCDOUT $FE,$D5+nPos,0
    return
    
    Two1:
    	LCDOUT $FE,$80+nPos,6
    	LCDOUT $FE,$81+nPos,3
    	LCDOUT $FE,$C0+nPos,7
    	LCDOUT $FE,$C1+nPos,5
    	LCDOUT $FE,$94+nPos,1
    	LCDOUT $FE,$95+nPos," "
    	LCDOUT $FE,$D4+nPos,4
    	LCDOUT $FE,$D5+nPos,7
    return
    
    Three1:
          LCDOUT $FE,$80+nPos,6
    	LCDOUT $FE,$81+nPos,3
    	LCDOUT $FE,$C0+nPos,7
    	LCDOUT $FE,$C1+nPos,5
    	LCDOUT $FE,$94+nPos," "
    	LCDOUT $FE,$95+nPos,3
    	LCDOUT $FE,$D4+nPos,7
    	LCDOUT $FE,$D5+nPos,5
    return
    
    Four1:
          LCDOUT $FE,$80+nPos,1
    	LCDOUT $FE,$81+nPos," "
    	LCDOUT $FE,$C0+nPos,4
    	LCDOUT $FE,$C1+nPos,7
    	LCDOUT $FE,$94+nPos," "
    	LCDOUT $FE,$95+nPos,1
    	LCDOUT $FE,$D4+nPos," "
    	LCDOUT $FE,$D5+nPos,1
    return
    
    Five1:
    	LCDOUT $FE,$80+nPos,2
    	LCDOUT $FE,$81+nPos,6
    	LCDOUT $FE,$C0+nPos,1
    	LCDOUT $FE,$C1+nPos," "
    	LCDOUT $FE,$94+nPos,6
    	LCDOUT $FE,$95+nPos,3
    	LCDOUT $FE,$D4+nPos,7
    	LCDOUT $FE,$D5+nPos,5
    return
    
    Six1:
    	LCDOUT $FE,$80+nPos,2
    	LCDOUT $FE,$81+nPos,6
    	LCDOUT $FE,$C0+nPos,1
    	LCDOUT $FE,$C1+nPos," "
    	LCDOUT $FE,$94+nPos,2
    	LCDOUT $FE,$95+nPos,3
    	LCDOUT $FE,$D4+nPos,4
    	LCDOUT $FE,$D5+nPos,5
    return
    
    Seven1:
    	LCDOUT $FE,$80+nPos,6
    	LCDOUT $FE,$81+nPos,3
    	LCDOUT $FE,$C0+nPos," "
    	LCDOUT $FE,$C1+nPos,0
    	LCDOUT $FE,$94+nPos," "
    	LCDOUT $FE,$95+nPos,0
    	LCDOUT $FE,$D4+nPos," "
    	LCDOUT $FE,$D5+nPos,0
    return
    
    Eight1:
    	LCDOUT $FE,$80+nPos,2
    	LCDOUT $FE,$81+nPos,3
    	LCDOUT $FE,$C0+nPos,4
    	LCDOUT $FE,$C1+nPos,5
    	LCDOUT $FE,$94+nPos,2
    	LCDOUT $FE,$95+nPos,3
    	LCDOUT $FE,$D4+nPos,4
    	LCDOUT $FE,$D5+nPos,5
    return
    
    Nine1:
    	LCDOUT $FE,$80+nPos,2
    	LCDOUT $FE,$81+nPos,3
    	LCDOUT $FE,$C0+nPos,4
    	LCDOUT $FE,$C1+nPos,5
    	LCDOUT $FE,$94+nPos," "
    	LCDOUT $FE,$95+nPos,0
    	LCDOUT $FE,$D4+nPos,7
    	LCDOUT $FE,$D5+nPos,5
    return
    
    colon1:      
          lcdout $fe,$C0+nPos,$A5   
          lcdout $FE,$94+nPos,$A5  
    return
    Last edited by tasmod; - 28th April 2014 at 13:07.
    Rob.

    The moment after you press "Post" is the moment you actually see the typso

  2. #2
    Join Date
    Dec 2011
    Location
    IO93ok
    Posts
    190

    Default Re: How do I discern Maidenhead Locator from GPS lat long info.

    Hi Darrel,

    Hmmm, looking at the various timings I don't see how this can be done.

    The NMEA string is output at the same point, the epoch of the PPS pulse, so the code is executing the string read when it also needs to start to display the 'advanced' time.

    As I see it at the moment, the code reads the gps string, then parses it, saving each piece to the assigned variable and runs the subroutines before initiating the display.

    As a test, I added two seconds to the seconds variable. Then comparing against a radio time signal it was almost the same. I say almost as it is not quite two seconds out in code execution.
    I suppose I could add a suitable pause value and bring it inline but I would have to test the offset, if any, over a period of operation. This assumes code execution always takes the same time to execute.

    Any ideas would be welcome.
    Rob.

    The moment after you press "Post" is the moment you actually see the typso

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612

    Default Re: How do I discern Maidenhead Locator from GPS lat long info.

    Hi Rob,
    I haven't been following this thread in detail so I apolgize if I'm suggesting something that's already been covered or isn't doable for whatever reason.

    Looking at the code you posted, and as you mentioned, you spend quite a bit of time in the ISR. I have two questions/suggestions.
    A) Why do you need to reload the custom characters each time? Wouldn't it be better to load them once at startup?
    B) Can't you simply set a flag in the ISR (ie UpdateDisplay = 1) which you then poll in the main loop? If the flag is set you update the display and reset the flag.

    Obviously there must be enough clock cycles between interrupts to do whatever needs to be done - no matter "where" it's being done (inside or out of the ISR).

    Doing (B) above you basically can't have the HSERIN statement within the main loop as it will "block" the processor for up to TimeOut ms (2000 in the code as posted). What you'd need to do is either introduce UART interrupt or simply poll the UART RX interrupt flag within the mainloop (provided the mainloop is "tight" enough to not overflow the UART receive buffer (2 bytes).

    As I see it at the moment, the code reads the gps string, then parses it,
    Yes and no. It doesn't read, then parses it. HSERIN is parsing the string as the bytes comes in, one by one. If it didn't do that you'd have to have a recieve buffer as big as the complete NMEA string. But again, the code in your ISR takes considerable amount of time and it's quite possible that if an interrupt occurs in the middle of the HSERIN statment (quite possible) the ISR is stealing too much time so the the receive buffer (2 bytes) overruns and HSERIN "gets lost".

    At 4800 baud each byte is a about 2ms long so if your ISR takes more than 4ms to execute it will most definitely cause issues for the HSERIN. Seeing all those LCDOUT statements within the ISR and the subroutines it calls makes me think your ISR runs way up into the tens of ms.

    /Henrik.
    Last edited by HenrikOlsson; - 29th April 2014 at 21:00.

  4. #4
    Join Date
    Dec 2011
    Location
    IO93ok
    Posts
    190

    Default Re: How do I discern Maidenhead Locator from GPS lat long info.

    Hi Henrik,

    Quite a bit to digest there. Good food for thought. Thanks.

    I missed the fact that the custom characters for the medium digits was constantly loading in the loop. I've moved that to the beginning now out of the loop, it is loaded at start up.

    The BigDigit clock did only load it's characters once then entered it's own loop, so that's taken care of.


    The main problem as I see it is that the gps string start occurs at the same time as the 'seconds' rise point. In the gps module the start of the rise of the PPS also triggers the NMEA string output. In other words the seconds epoch occurs for both. I don't know if it's possible to receive the string and trigger the display code at the same time. I was just trying to get to a more accurate time.

    The time is very close now anyway allowing for code run timing. I could add a small pause to bring it closer I suppose.
    Rob.

    The moment after you press "Post" is the moment you actually see the typso

  5. #5
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612

    Default Re: How do I discern Maidenhead Locator from GPS lat long info.

    Hi Rob,
    More thoughts.....
    Since, if I'm not mistaken, the time is parsed from the NMEA string using the PPS signal to initiate a display update will update the display with the time information from the last received string which is basically one second "old". I think that the best you can do really is to simply grab and parse the string and then update the display.

    If you're receiving the full 82byte NMEA string that will take ~170ms, add the actual display update code to that - you'll be a couple of hundred ms off.

    /Henrik.

  6. #6
    Join Date
    Dec 2011
    Location
    IO93ok
    Posts
    190

    Default Re: How do I discern Maidenhead Locator from GPS lat long info.

    Hi Henrik,

    I've been doing some more reading regarding the NMEA string from the Rockwell datasheets. (19 pages in one 142 in other !)

    I've discovered two choice bits.

    (1.) The string is always after the event, so is 1 second late as you said.

    (2.) Standard laid down for time this way is up to +/- .9 seconds regardless of (1.) above.

    Rockwell do a binary protocol at 9600 baud which is 'message' driven. So you can actually poll for time separately with far more accuracy but it would require a complete code rewrite.


    I'm trying to keep code tight in the BigClock sub which only reads the h, m, s, part of string. This is at beginning of the string anyway. I update in reverse to display, s m h.

    At the moment I've added 2 seconds before display and with the other code changes, it's as near as I can see visually using the PPS LED. It is almost on the PPS event. That is near enough for me. Checking against MSF radio time signal using Spectrum Lab software, it's very close.
    Visually humans can discern a 250ms difference, so as I can hardly see any difference, it should be closer than 250ms diff.
    I could load the output into SpecLab to compare both signals I suppose. I may eventually do that anyway as I'm curious to what the code timing is.
    I have the frequency lock part spot on, so it would be nice to get the time part as well, but I don't think its possible.

    For my sins, in my other life I am an official timekeeper, timing to hundredths of a second. I can see '100ths differences there ok
    Amazing really how many times a day I see exactly the same time to the hundreth of a second, two competitors achieve.



    Another idea, but I suspect will gain nothing is :-

    Read string full time once at start up.
    Display

    loop:
    Then read only seconds.
    Increment software clock s m h
    update display
    loop

    String read would be very quick. Approx 20ms.

    EDIT:
    Just realised that at 20ms I would have read h m s anyway, so pseudo code above is pointless.
    Last edited by tasmod; - 1st May 2014 at 11:58.
    Rob.

    The moment after you press "Post" is the moment you actually see the typso

  7. #7
    Join Date
    Oct 2010
    Posts
    413

    Default Re: How do I discern Maidenhead Locator from GPS lat long info.

    Dear all,

    first of all i would like to congrats the work have been done in this post.

    I would also like to inform you once again that im not a programmer. So my knowledge at programming is really low.

    I try to setup as a hobby a gps and project the info to ulcd that i have many years at my small lab.

    Here is the code up to now:

    Code:
    @ ERRORLEVEL -306 ; this command prevents the compiler to give you a notice of
                      ; crossing page boundary - make sure bits are set 
    
    PORTB = 0
    input portb.0
    ; -----[ Variables ]-------
    
    PWRLED      var     PORTb.1   ; this shows that the initialization is finished
    LCD         var     PORTb.2   ; to LCD operation
    GPS_TX      var     PORTb.0   ; info from GPS 
    GPS_RX      var     PORTb.4   ; COMMANDS TO GPS, this feature is not 
    Testled     var     PORTb.5   ;ill try to use this when GPS module find signal
    pause 2000
    
    ' -----[ Variables ]-------------------------------------------------------
    '   $GPRMC,090045.000,A,3823.6645,N,02353.3600,E,0.02,195.80,170518,,,A*62
    '   $GNGGA,140405.000,3823.6010,N,02353.3054,E,1,9,0.88,0.8,M,35.9,M,,*40
    
    hh          var     byte    'hours
    mm          var     byte    'minutes
    ss          var     byte    'seconds  
    sss         var     word    'milisecs
    degrees	    VAR     BYTE    'latitude/longitude degrees
    minutes	    VAR     BYTE    'latitude/Longitude minutes
    minutesD    VAR	    word    'latitude/LONGITUDE DECIMAL MINUTES
    dir         VAR     BYTE    ' direction (latitude: 0 = N, 1 = S / longitude: 0 = E, 1 = W)
    degrees2    VAR     BYTE    'latitude/longitude degrees
    minutes2    VAR	    BYTE    'latitude/Longitude minutes
    minutesD2   VAR	    word    'latitude/LONGITUDE DECIMAL MINUTES
    dir2        var     byte    ;direction (latitude: 0 = N, 1 = S / longitude: 0 = E, 1 = W)
    SatNo       VAR	    BYTE    'number of satellites connected
    knots       var     word    'speed over ground
    knots2      var     byte    'speed over ground
    course      var     word    'course
    course2     var     byte    'course
    day         var     byte    'day
    month       var     byte    'month
    year        var     byte    'year
    i           var     word    
    GNRMC       var     word
    GNGGA       var     WORD
    FIX         var     word
    Modefix     var     byte
    horizon     var     byte
    precision   var     byte
    meter       var     byte
    METERS      var     byte
    Meters2     var     byte
    
    ' -----------------  [ Initialization ]----------------------
    serout2 LCD,32,[$55]      ' uOLED Initialize
    pause 2000
    serout2 lcd,32,[$56,$01]
    pause 1000
    serout2 lcd,32,[$45]
    pause 500
    serout2 lcd,32,[$55]
    pause 500
    serout2 lcd,32,[$45]
    pause 500
    serout2 lcd,32,[$73,$00,$03,$11,$ff,$ff," Leonardo Bilalis",$00]
    pause 200                       
    serout2 lcd,32,[$73,$02,$06,$10,$ff,"     Copyright 2018",$00]
    pause 3000
    serout2 lcd,32,[$45]
    pause 1000
    serout2 lcd,32,[$73,$02,$06,$10,$ff,$ff,"      GPS.........",$00]
    pause 500
    serout2 lcd,32,[$45]
    pause 200
    HIGH pwrled
    
    '--------------------   [MAIN] ------------------------------
    
    Main: 
    
    ;$GPRMC,090045.000,A,3823.6645,N,02353.3600,E,0.02,195.80,170518,,,A*62
    
    serin2 gps_tx,84,[wait("$GNRMC"),_                              ;we wait for $GNRMC
    wait(","),dec2 hh,dec2 mm,dec2 ss,wait("."),dec3 sss,_          ;we wait for 090045.000
    wait(","),fix,_                                                 ;we wait for A
    wait(","),dec2 degrees,dec2 minutes,wait("."),dec4 minutesd,_   ;we wait for 3823.6645
    wait(","),dir,_                                                 ;we wait for N 
    wait(","),dec3 degrees2,dec2 minutes2,wait("."),dec4 minutesd2,_;we wait for 02353.3600
    wait(","),dir2,_                                                ;we wait for E
    wait(","),dec knots,wait("."),dec2 knots2,_                     ;we wait for 0.02
    wait(","),dec3 course,wait("."),_                               ;we wait for 195.80
    wait(","),dec2 day,dec2 month,dec2 year]                        ;we wait for 170518
    
    pause 100
    
    ;$GNGGA,140405.000,3823.6010,N,02353.3054,E,1,9,0.88,0.8,M,35.9,M,,*40
    
    serin2 gps_tx,84,[wait("$GNGGA"),_
    wait(","),dec2 hh,dec2 mm,dec2 ss,wait("."),dec3 sss,_ 
    wait(","),dec2 degrees,dec2 minutes,wait("."),dec4 minutesd,_ 
    wait(","),dir,_
    wait(","),dec3 degrees2,dec2 minutes2,wait("."),dec4 minutesd2,_
    wait(","),dir2,_
    wait(","),modefix,_
    wait(","),dec2 satno,_
    wait(","),dec3 horizon,dec precision,_
    wait(","),meter,dec2 METERS,dec Meters2]
    
    pause 100
    
    serout2 lcd,32,[$73,$03,$00,$00,$ff,$ff,"Protocol:",dec5 GNRMC,$00] ; THIS IS NOT WORKING
    pause 200
    serout2 lcd,32,[$73,$00,$02,$00,$ff,$ff,"Date:",dec2 day,dec2 month,dec2 year,$00] ; THIS IS NOT WORKING
    pause 200
    serout2 lcd,32,[$73,$00,$04,$00,$ff,$ff,"TIME: ",dec2 hh+3," :",dec2 mm," :",dec2 ss,$00]
    pause 200
    serout2 lcd,32,[$73,$00,$06,$00,$ff,$ff,"Satellites:",dec2 satno," ","Fixed:",fix,$00]
    pause 200
    serout2 lcd,32,[$73,$00,$08,$00,$ff,$ff,"Lat : ",dec2 degrees,dec2 minutes,".",dec4 minutesd," ",dir,$00]
    pause 200
    serout2 lcd,32,[$73,$00,$0A,$00,$ff,$ff,"Lon : ",dec3 degrees2,dec2 minutes2,".",dec4 minutesd2," ",dir2,$00]
    pause 200
    serout2 lcd,32,[$73,$00,$0C,$00,$ff,$ff,"GND SPEED : ",dec knots*1852/1000,".",dec2 knots2,$00]
    pause 200
    serout2 lcd,32,[$73,$00,$0E,$00,$ff,$ff,"Meters : ",dec2 METERS,dec Meters2,$00] ; THIS IS NOT WORKING
    
    pause 5000
    serout2 lcd,32,[$45]
    pause 100
    goto main
    
    if fix = "V" then notfix
    
    notfix: 
    serout2 lcd,32,[$73,$00,$03,$11,$ff,$ff,"   Waiting for GPS",$00]
    pause 100
    serout2 lcd,32,[$73,$02,$06,$10,$ff,"     Copyright 2018",$00]
    pause 1000
    serout2 lcd,32,[$45]
    pause 200
    goto main
    
    '-------------------- [ CLEAR ] -----------------------------
    Clearlcd:
    serout2 lcd,32,[$45]
    pause 500
    RETURN
    What i would like to do is to display:

    Protocol : GNRMC

    DATE :
    TIME :
    Satellites:
    LAT :
    LON :
    GND SPEED:
    METERS:

    I have the following problem.

    1. Cannot display the DATE. Something is wrong at my code and there is not proper display of the date.
    2. I have put a loop for display all the factors, because i need to clear the LCD every time something is change. So please could you help me understand how could i manage to display the factors and only change on the fly the ones really going like Time, LAT, LON, GND SPEED, SATs etc.
    3. The Protocol command is not working
    4. The speed is not working properly, i think i need to do better the conversion
    5. The meters are not displaying, there is a wrong value in there.
    6. I need to convert the measurements from the NMEA message LAT and LON to google numbers.

    Please check what i have done till now in order for me to understand what it is needed.

    Name:  gpspic1.png
Views: 11177
Size:  467.0 KB

    Name:  gpspic2.png
Views: 11267
Size:  495.9 KB

    Name:  gpspic3.png
Views: 11346
Size:  568.9 KB

    Name:  gpspic4.png
Views: 11141
Size:  633.2 KB

    Name:  gpspic5.png
Views: 11171
Size:  361.8 KB

    Name:  gpspic6.png
Views: 11145
Size:  348.2 KB

    Name:  gpspic7.png
Views: 11562
Size:  325.0 KB

Similar Threads

  1. LAT replaces PORT command?
    By markscotford in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 3rd December 2011, 16:37
  2. Need Info for PBP?
    By azmax100 in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 30th January 2009, 07:44
  3. Replies: 1
    Last Post: - 27th July 2008, 06:14
  4. dmx info.
    By oscar in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 8th May 2005, 11:54

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts