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


Closed Thread
Page 1 of 4 1234 LastLast
Results 1 to 40 of 126
  1. #1
    Join Date
    Dec 2011
    Location
    IO93ok
    Posts
    190

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

    Hi all,

    I have some idea but maths is not my strong point. I have written what I considered to be the process but not a working code. Am I on the right lines ?(See end)

    This is the relevant information to achieve the locator.

    .
    Longitude is always the first, followed by latitude, for each pair. For simplicity, let's assume that West and South are negative lat/long, as is a common convention. For example purposes, I'm going to use 32.123 W, 14.321 N. The key thing is to do the following.:
    Longitude
    1. Add 180 to the longitude, and take the integer value /20, and add one. Then figure out which letter of the alphabet that corresponds to, usually written in upper case. The example will be 147.877/20=7. Adding one will give the 8th letter of the alphabet, or G. Note 7.877 is remaining.
    2. Take the remainder of what is left, and divide by 2, rounding down. This is the number, no conversion required. The example will give a value of 3. Note 1.877 is remaining.
    3. Take the remainder that is left, and multiply by 12, and add one. Round down to the nearest integer.. This is the letter of the alphabet, usually written in lower case. The example gives a value of 22+1=23. This will be the letter w.
    Latitude
    1. Add 90 to the latitude, and take the integer value /10, and add one. Then figure out which letter of the alphabet that corresponds to, usually written in upper case. The example will be 104.321/10=10. Adding one will give the 8th letter of the alphabet, or J. Note 4.321 is remaining.
    2. Take the remainder of what is left, and round down. This is the number, no conversion required. The example will give a value of 4. Note 0.321 is remaining.
    3. Take the remainder that is left, and multiply by 24, and add one. Round down to the nearest integer.. This is the letter of the alphabet, usually written in lower case. The example gives a value of 7+1=8. This will be the letter g.
    Putting them together by pairs, and alternating first longitude then latitude, gives the grid square for 32.123 W, 14.321 N to be GJ34wg.

    I have the info from the RMC string as :-

    Code:
    latdeg VAR BYTE 'degrees latitude
    latmin VAR BYTE 'minutes latitude
    NS VAR BYTE 'north or south
    londeg VAR BYTE 'degrees longitude
    lonmin VAR BYTE 'minutes longitude
    EO VAR BYTE 'east or west
    My idea of the process is something like this :-

    Code:
    locator:
         lonloc1=londeg + lonmin + 180
         lonloc2=lonloc1/20
         lonloc3=lonloc1//20
         maid1=lonloc2+1
         lookup maid1    ; first main letter
         
         lonloc4=lonloc3//2
         maid3=lonloc3/2     ;first number
         
         
         maid5=lonloc4*12+1
         lookup maid5      ; 1st  2nd letter
         
         
         
         latloc1=latdeg + latmin + 90
         latloc2=latloc1/10+1
         latloc3=latloc1//10
         maid1=latloc2+1
         lookup maid2    ; second main letter
         
         
         maid4=latloc3     ; second number
         
         
         maid6=latloc3*24+1
         lookup maid6      ; 2nd 2nd letter
         
         maidenhead=maid1, maid2, maid3, maid4, maid5, maid6

  2. #2
    Join Date
    Jan 2012
    Location
    Grid EN19MV
    Posts
    157

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

    Weird - I've had this one on my list of things to make for about a year - I got a bit of a start, then other things took over.

    Don't know if this helps, but HERE is a BASIC program that I was going to try to convert.

    If I get going on this again, I'll keep you updated - and please let me know how you're doing with it too.

    Andy
    "I have noticed that even those who assert that everything is predestined and that
    we can change nothing about it still look both ways before they cross the street"


    -Stephen Hawking

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

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

    OK thanks for that I will look at it.

    Meanwhile here is the full code i have for getting the NMEA data I want to display. NOTE the code for maidenhead is the same as above, a work in progress. All untested as yet.
    I do have a fully working code in asm but wanted it in PBP for experimental purposes.

    Code:
    '
    ' Program to display returned value of a GPS on RB0
    ' LCD in 4-BIT mode PIC16F628 controller 4Mhz clock Fuse PWRT BODEN
    ' 
    'GPS sentence: $GPRMC,192144.62,A,5041.6058,N,00412.6124,E,0.45,3 57.74,081205,,*0B
    
    Define LCD_DREG PORTA          ' Port for LCD Data
    Define LCD_DBIT 0                   ' Use upper 4 bits of Port  
    Define LCD_RSREG PORTB         ' Port for RegisterSelect (RS) bit
    Define LCD_RSBIT 4                 ' Port Pin for RS bit  (pin9)
    Define LCD_EREG PORTB          ' Port for Enable (E) bit
    Define LCD_EBIT 5                   ' Port Pin for E bit    (pin7)
    Define LCB_BITS 4                   ' Using 4-bit bus
    Define LCD_LINES 4                  ' Using 2 line Display
    Define LCD_COMMANDUS 2000      ' Command Delay (uS)
    define LCD_DATAUS 50              ' Data Delay (uS)
    
    DEFINE OSC 4
    CMCON = 7
    OPTION_REG.7=0                 ' Enable Pull-Up's
    GPSin VAR PORTB.0
    LED  VAR PortA.4               ' flash per second
    
    TRISA.0=0
    TRISA.1=0
    TRISA.2=0
    TRISA.3=0
    
    TRISA.4=0 ; LED
    
    PAUSE 500
    
    PORTA=0
    PORTB=0
    
    'Allocate Variables for GPS:
    TimeOut CON 3000
    baudGPS CON 24764 '16572 + 8192 (bit 13)
    
    hh VAR BYTE           'hours
    mm VAR BYTE          'minutes
    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
    NS VAR BYTE          'north or south
    londeg VAR BYTE     'degrees longitude
    lonmin VAR BYTE     'minutes longitude
    EO VAR BYTE          'east or west
    j VAR BYTE             'day
    m VAR BYTE            'month
    a VAR BYTE            'year
    
    fix VAR WORD        'GPS fix
    
    
    LCDOut $FE, 1        'Clear Screen
    
    LCDOut $fe,$80," GPS Decoder "
    LCDOut $FE,$c0, " G8VLQ "
    Pause 2000
    LCDOut $FE, 1  
    
    GPS:                 'read GPS
    
    SerIn2 GPSin,baudGPS,Timeout,[wait("$GPRMC"),wait(","),DEC2 hh,DEC2 mm,wait(","),fix,wait(","),DEC2 latdeg,DEC2 latmin,wait(","),NS,wait(","),DEC3 londeg,DEC2 lonmin,wait(","),EO,wait(","),knots,wait("."),DEC2 knotsten,wait(","),DEC3 course,wait(","),DEC2 j,DEC2 m,DEC2 a]
    
    flash:                       ;not accurate pps
    led high
    led low
    
    
    IF fix="V" Then                                            'if no GPS fix
    GOTO LCD1
    EndIF
    
    LCD:                  ; LATER put time and date on first line , remove names
                             ; callsign and QRA (maidenhead) on second line
    
    LCDOut $fe,$80,"DATE: ",DEC2 j,"-",DEC2 m,"-",DEC2 a                                     ; 80 1st line   
    LCDOUT $fe,$c0,"TIME: ",DEC2 hh,":",DEC2 mm                                                 ; c0 2nd line
    LCDOut $fe,$94,"LAT:",DEC2 latdeg,",",DEC2 latmin," ",NS                                  ; 94 3rd line
    LCDOut $fe,$d4,"LON:",DEC2 londeg,",",DEC2 lonmin," ",EO                                ; d4 4th line
    
    GoTo GPS
    
    LCD1:                       ; If invalid data, just shows gps string is received
    
    LCDOut $fe,$80,"  Invalid data  "                                                                       ; 80 1st line
    LCDOUT $fe,$c0,"     No Fix     "                                                                       ; c0 2nd line
    LCDOut $fe,$94,"LAT:",DEC2 latdeg,",",DEC2 latmin," ",NS                                 ; 94 3rd line
    LCDOut $fe,$d4,"LON:",DEC2 londeg,",",DEC2 lonmin," ",EO                                ; d4 4th line
    
    GoTo GPS
    
    locator:
         lonloc1=londeg + lonmin + 180
         lonloc2=lonloc1/20
         lonloc3=lonloc1//20
         maid1=lonloc2+1
         lookup maid1                         ; first main letter
         
         lonloc4=lonloc3//2
         maid3=lonloc3/2                      ;first number
         
         
         maid5=lonloc4*12+1
         lookup maid5                         ; 1st  2nd letter
         
         
         
         latloc1=latdeg + latmin + 90
         latloc2=latloc1/10+1
         latloc3=latloc1//10
         maid1=latloc2+1
         lookup maid2                         ; second main letter
         
         
         maid4=latloc3                        ; second number
         
         
         maid6=latloc3*24+1
         lookup maid6                         ; 2nd 2nd letter
         
         maidenhead=maid1, maid2, maid3, maid4, maid5, maid6
         
          
    
    speed:
    LCDOUT $fe,1
    LCDOut $fe,$80,"SPEED :",knots,".",DEC2 knotsten," KNT"
    LCDOut $fe,$c0,"HEADING:",DEC3 course," DEG"
    
    END
    Last edited by tasmod; - 6th March 2014 at 08:54. Reason: spelling

  4. #4
    Join Date
    Jan 2012
    Location
    Grid EN19MV
    Posts
    157

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

    Thanks! I'll have a look at that.
    "I have noticed that even those who assert that everything is predestined and that
    we can change nothing about it still look both ways before they cross the street"


    -Stephen Hawking

  5. #5
    Join Date
    Jan 2012
    Location
    Grid EN19MV
    Posts
    157

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

    BTW, what are you building? Mine was an idea when I was driving around talking on Amateur Radio Satellites. We were in Grand Forks, North Dakota, and I was waiting for my wife to come out of a store. There happened to be an AO-51 pass happening right then, so I made a couple of contacts - only I had NO IDEA what my grid square was! I used my Winnipeg one, and thought "it would be nice to have a handheld, GPS-based unit that displays your current grid square to 6 digits". And the idea was born. I'll get to it, probably right after I finish the smoker controller I'm working on right now.

    Did you happen to notice how I list my location on the forum? I guess great minds really DO think alike!

    Andy
    Last edited by andywpg; - 8th March 2014 at 19:37. Reason: spelling
    "I have noticed that even those who assert that everything is predestined and that
    we can change nothing about it still look both ways before they cross the street"


    -Stephen Hawking

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

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

    Hi Andy,

    The project is already working, I just wanted more information displayed on LCD. The LCD board piggybacks the LCD display. It has a 16F818 which deals with the NMEA string and ADC functions.

    It's a GPS Disciplined Oscillator producing 10MHz to 10-12 signal. For accuracy of frequency and timing for MS and EME.

    It remains extremely stable but I am slightly improving it by logging the PLL control voltage and the TCXO temp swing.
    By logging I can get a mean control position for either start up purposes or short term 'dropout' from gps. Thus it will keep accuracy for short term outage. If the unit is turned off then on, I can apply the correct PLL control voltage until the gps locks again. Although watching the PLL voltage swing whilst trying to lock was fascinating.

    It also produces a very accurate 1PPS output. I later intend to use this to trigger the NMEA sentence display. You may be aware that the sentence suffers from lag or slight offset depending if the gps module decides to send another, other, information sentence. In my case at the moment it is 1.635 secs BEHIND actual time as my module occasionally sends out the powerID string which puts the timing RMC sentence out.
    I will be turning all off except the RMC sentence. At the moment it is testing phase.

    I get a very strong signal from the 60kHz time signal from Anthorn in the UK so I can actually compare the second epoch via SpecLab software visually.
    Rob.

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

  7. #7
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

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

    Trying to work through the example in post #1.

    Quote Originally Posted by tasmod
    gives the grid square for 32.123 W, 14.321 N to be GJ34wg.
    The best I can come up with is HK33xv at that location.
    Are you sure about the example in post #1?

    And it seems that Andy is in Winnipeg Manitoba Canada.
    And you are near Gainsborough, U.K.

    If those are close, I can't be that far off with the calculations.
    DT

  8. #8
    Join Date
    Jan 2012
    Location
    Grid EN19MV
    Posts
    157

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

    Quote Originally Posted by Darrel Taylor View Post
    And it seems that Andy is in Winnipeg Manitoba Canada.
    Absolutely correct

    And you're right - HK33xv is in the ocean off of Cape Verde

    And 14.321N 32.123W converts to HK34wh - darn near exactly what you calculated
    Last edited by andywpg; - 13th March 2014 at 00:13.
    "I have noticed that even those who assert that everything is predestined and that
    we can change nothing about it still look both ways before they cross the street"


    -Stephen Hawking

  9. #9
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

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

    Thanks Andy, I knew I couldn't be that far off.

    But apparently, I need to work on the math some more.
    Darned Floating-Point ...
    DT

  10. #10
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    Woohoo!

    HK34wh it is!!
    And it's not even midnight yet.

    It's some really ugly code right now, will need to add some "Pretty" to it.

    Are you guy's using PBP3?

    If not, there's only so much "Pretty" I can add.
    DT

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

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

    Just realised you discerned my physical location from my locator. So your code should be OK.

    I did the calc by hand and got it to the example Locator given. ODD. Also needed to reverse calc the 'leftovers'

    One thing not mentioned is W is a negative longtitude. I need put an IF THEN in my code to deal with the 180 for a negative W rather than E.


    If you have ugly code then that's ok with me. I'm using 2.50 Darrel. Long time coding but not enough to be good with PBP

    The routine could also decode the 8th place pair too, which is as close as Maidenhead gets.
    Last edited by tasmod; - 13th March 2014 at 09:33.
    Rob.

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

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

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

    Darn it.

    Scrap what I said about the example. I found my scratch pad and realised I used my own GPS co-ordinates to check the formula given to get my locator. I didn't use the example after all.
    Rob.

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

  13. #13
    Join Date
    Jan 2012
    Location
    Grid EN19MV
    Posts
    157

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

    Quote Originally Posted by Darrel Taylor View Post
    Woohoo!

    HK34wh it is!!
    And it's not even midnight yet.

    It's some really ugly code right now, will need to add some "Pretty" to it.

    Are you guy's using PBP3?
    I am - I look forward to seeing your code because math and I do not get along well.....

    That's actually one of the reasons I have been delaying this project - the math was a bit above me right now.... I have just been using the AMSAT page to convert and see where a grid square takes me on the map.
    Last edited by andywpg; - 13th March 2014 at 15:42.
    "I have noticed that even those who assert that everything is predestined and that
    we can change nothing about it still look both ways before they cross the street"


    -Stephen Hawking

  14. #14
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    An afterthought, before the fact.
    I went through this trying to make sure it didn't require PBP3 since Rob doesn't have it. But now that I've posted it, I realized it requires PBP 2.60 or later. DOH!
    At least you can download the free PBP3 trial version and compile it with that, or you can change the arrayread/arraywrite statements, so I'm not changing it.
    ---------------------------------- -------------------------------- ----------------------------------

    Ok, here goes ...
    It's not as ugly as it was, but without PBP3 there's only so much you can do.

    This code is based on the Perl script on the Wikipedia site for Maidenhead Locator System by Chris Ruvolo.
    Although I had to do things quite differently for the Microchip Floating-Point routines.

    The Microchip Floating-Point routines for PBP are available from http://melabs.com/resources/fp.htm
    Extract the .zip file to the same folder as your source code, or this code.

    To try to make things easy, the routines start out with a String in the same format as the Lat/Lon data of the $GPRMC sentence.

    For instance, an approximation of the IO93ok square is 0 degrees, 47.70 minutes West Longitude by 53 degrees, 26.20 minutes North latitude.
    $GPRMC will present the data as .... 5326.20,N and 00047.70,W.
    These can be parsed from the GPS data, or entered manually with the following two statements ... Note that they are null terminated.
    Code:
    ARRAYWRITE LonStr,["00047.70,W",0]  ; -0° 47.70' 
    ARRAYWRITE LatStr,["5326.20,N",0]   ; 53° 26.20
    I am entering them manually for this sample.

    I'm using the 24-bit Floating-Point routines, since it gave the same results as the 32-bit FP, but you can use either one by simply changing the include file.
    I imagine the 32-bit routines will be better around the edges of each square, but I haven't confirmed that.

    I'm using a 16F1937, so if you are using an 18F ... you'll need to use the 18F FP includes.

    Obviously, you need to initialize your hardware configs first.
    Code:
    ; Filename    : Maidenhead.pbp
    ; Compiler    : PICBASIC PRO Compiler
    ; Target PIC  : 16F1937, but will work with most any chip
    ; Oscillator  : ANY
    ; Keywords    : Maidenhead, Locator, GPS, Amateur Radio
    ; Description : PICBASIC PRO program to convert between
    ;             : GPS Sexagesimal to Maidenhead coordinate systems
    ;-------------------------------------------------------------------------------
    
                           ; use only one of the FP includes
    INCLUDE "FP20.bas"     ; 24-bit Floating Point for 14-bit cores with RAM at $20
    ;INCLUDE "FP2032.bas"   ; 32-bit Floating Point for 14-bit cores with RAM at $20
    
    DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
    DEFINE HSER_SPBRG 25  ' 19200 Baud @ 32MHz, 0.16%
    DEFINE HSER_CLROERR 1 ' Clear overflow automatically
    
    HSEROUT [27,"[2J","Maidenhead Locator",13,10]
    HSEROUT ["16F1937, 32Mhz, PBP3 not required",13,10,13,10]
    
    MH     VAR BYTE[6]
    
    LonStr    VAR BYTE[12]
    LatStr    VAR BYTE[12]
    LonDeg    VAR BYTE
    LonMin    VAR BYTE
    LonMinDec VAR BYTE
    LonDir    VAR BYTE
    LatDeg    VAR BYTE
    LatMin    VAR BYTE
    LatMinDec VAR BYTE
    LatDir    VAR BYTE
    
    ARRAYWRITE LonStr,["00047.70,W",0]  ; -0° 47.70'  <-- Enter location here
    ARRAYWRITE LatStr,["5326.20,N",0]   ; 53° 26.20'
    
    HSEROUT ["LonStr  = ", STR LonStr,13,10]          ; display manual input
    HSEROUT ["LatStr  = ", STR LatStr,13,10]
    
    ;----[parse strings as if they came from a GPS]---------------------------------
    ARRAYREAD LonStr,[DEC3 LonDeg, DEC2 LonMin, Dec LonMinDec, LonDir]
    ARRAYREAD LatStr,[DEC2 LatDeg, DEC2 LatMin, Dec LatMinDec, LatDir]
    
    
    ;----[convert Longitude Sexagesimal to Decimal Degrees]-------------------------
    Aint = LonMinDec : GOSUB ItoFA    ; decimal portion of Minutes
    Bint = 100 : 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 LonDir = "W" THEN              ; if west of Prime Meridian
        GOSUB AtoB
        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]------------------------------------------
    GOSUB SaveLon                     ; save Longitude for later
    Bint = 20   : GOSUB ItoFB         ; Lon / 20
    GOSUB fpdiv
    GOSUB SaveAARG                    ; save AARG for modulus
    GOSUB FtoIA                       ; get integer
    MH(0) = "A" + Aint                ; + "A" = First character
    
                                      ; -- do  Lon // 20 --- (modulus)
    Bint = Aint                       ; copy integer result to BARG
    GOSUB ItoFB                       ; convert it to float
    GOSUB RestoreAARG                 ; restore Lon / 20 to AARG
    GOSUB fpsub                       ; subtract integer
    Bint = 20                         ; multiply times original divisor (20)
    GOSUB ItoFB
    GOSUB fpmul                       ; AARG now contains the modulus
    
    Bint = 2    : GOSUB ItoFB         ; divide modulus by 2
    GOSUB fpdiv
    GOSUB FtoIA                       ; get integer
    MH(2) = "0" + Aint                ; + "0" = Third character
    
    GOSUB RestoreLon                  ; restore Longitude
    Bint = 2 : GOSUB ItoFB
    GOSUB fpdiv                       ; divide by 2
    
    GOSUB FtoIA                       ; get integer
    Bint = Aint * 2  : GOSUB ItoFB    ; put int * 2 in BARG, change back to float
    GOSUB RestoreLon                  ; restore original Longitude
    GOSUB fpsub                       ; subtract A - B
    
    Bint = 12 : GOSUB ItoFB           ; Multiply * 12
    GOSUB fpmul
    GOSUB FtoIA                       ; get integer
    
    MH(4) = "a" + Aint                ; + "a" = Fifth Character
    
    ;----[convert Latitude Sexagesimal to Decimal Degrees]--------------------------
    Aint = LatMinDec : GOSUB ItoFA    ; decimal portion of Minutes
    Bint = 100 : 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 LatDir = "S" THEN              ; if south of equator
        GOSUB AtoB
        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]------------------------------------------
    GOSUB SaveLon                     ; save Latitude for later
    Bint = 10   : GOSUB ItoFB         ; Lat / 10
    GOSUB fpdiv
    GOSUB SaveAARG                    ; save AARG for modulus
    GOSUB FtoIA
    MH(1) = "A" + Aint                ; + "A" = Second character
    
                                      ; -- do  Lat // 10 --- (modulus)
    Bint = Aint                       ; copy integer result to BARG
    GOSUB ItoFB                       ; convert it to float
    GOSUB RestoreAARG                 ; restore Lat / 10 to AARG
    GOSUB fpsub                       ; subtract integer
    Bint = 10                         ; multiply times original divisor (10)
    GOSUB ItoFB
    GOSUB fpmul                       ; AARG now contains the modulus
    
    GOSUB FtoIA
    MH(3) = "0" + Aint                ; + "0" = Fourth character
    
    GOSUB RestoreLon                  ; restore original Latitude
    GOSUB FtoIA                       ; get integer
    Bint = Aint : GOSUB ItoFB         ; put int in BARG, change back to float
    GOSUB RestoreLon                  ; restore original Latitude
    GOSUB fpsub                       ; subtract A - B
    
    Bint = 24 : GOSUB ItoFB           ; Multiply * 24
    GOSUB fpmul
    GOSUB FtoIA                       ; get integer
    
    MH(5) = "a" + Aint                ; + "a" = Sixth character
    
    ;----[Maidenhead conversion complete]-------------------------------------------
    
    HSEROUT ["LOC ",STR MH\6,13,10,13,10] ; show final result
    
    
    Main:                             ; blink an LED when done
        HIGH PORTA.0
        PAUSE 500
        LOW PORTA.0
        PAUSE 500
    GOTO Main
    
    ;-------------------------------------------------------------------------------
    Aexp_Copy    VAR BYTE
    AARGB0_Copy  VAR BYTE
    AARGB1_Copy  VAR BYTE
    AARGB2_Copy  VAR BYTE
    
    Aexp_Lon     VAR BYTE
    AARGB0_Lon   VAR BYTE
    AARGB1_Lon   VAR BYTE
    AARGB2_Lon   VAR BYTE
    
    SaveAARG:
        Aexp_Copy = Aexp
        AARGB0_Copy = AARGB0
        AARGB1_Copy = AARGB1
        AARGB2_Copy = AARGB2
    RETURN
    
    RestoreAARG:
        Aexp = Aexp_Copy
        AARGB0 = AARGB0_Copy
        AARGB1 = AARGB1_Copy
        AARGB2 = AARGB2_Copy
    RETURN
    
    AtoB:
        Bexp = Aexp
        BARGB0 = AARGB0
        BARGB1 = AARGB1
        BARGB2 = AARGB2
    RETURN
    
    SaveLon:
        Aexp_Lon = Aexp
        AARGB0_Lon = AARGB0
        AARGB1_Lon = AARGB1
        AARGB2_Lon = AARGB2
    RETURN
    
    RestoreLon:
        Aexp = Aexp_Lon
        AARGB0 = AARGB0_Lon
        AARGB1 = AARGB1_Lon
        AARGB2 = AARGB2_Lon
    RETURN
    The output from the program in a terminal looks like this ...
    Code:
    Maidenhead Locator
    16F1937, 32Mhz, PBP3 not required
    
    LonStr  = 00047.70,W
    LatStr  = 5326.20,N
    LOC IO93ok
    If you are using an Enhanced 14-bit core like the 16F1937 that I'm using ... you'll need to add the processor to the DEV_FAM.INC file from the FP.zip
    For the 16F1937 add this towards the bottom of the file (before the if statement).
    Code:
        IFDEF   __16F1937          ; Generic Processor Type
    P16CXX      SET    TRUE        ; If P16CXX, use INHX8M file format.
    P16_MAP2    SET    TRUE        ;
        ENDIF
    References:
    Last edited by Darrel Taylor; - 14th March 2014 at 07:09.
    DT

  15. #15
    Join Date
    Jan 2012
    Location
    Grid EN19MV
    Posts
    157

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

    Umm, WOW! Thanks Darrel! And my brain thanks you even more, since it gets uppity when it has to do complex math!
    "I have noticed that even those who assert that everything is predestined and that
    we can change nothing about it still look both ways before they cross the street"


    -Stephen Hawking

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

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

    And a WOW from me Darrel. Thanks for your help. Surprisingly I think I can follow and understand the code

    Sorry I'm late back to the thread. One of the winter bugs has had hold of me, not the type I can rewrite

    The project code I posted above doesn't work in the Serin2 GPS routine. Either the line is incorrect or the speed. I've tried every speed and state but no joy. Signal is at the pic pin every second.

    The code compiles but says 'error, expected [ ' but they are there?

    I will try out the code shortly, many thanks again.
    Rob.

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

  17. #17
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

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

    Quote Originally Posted by tasmod View Post
    The code compiles but says 'error, expected [ ' but they are there?
    The SERIN2 line has a value for the timeout, but there's no label for it to jump to.
    DT

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

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

    Doh, sometimes you can't see the wood for the trees !

    Thanks again Darrel, you've no idea how many times I looked at that line.

    Code is working at base level now and info is on screen, next is to incorporate the Locator code of yours.

    Name:  gpslcd.jpg
Views: 3452
Size:  12.0 KB
    Rob.

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

  19. #19
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

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

    Awesome!

    Can't wait to see an IO93ok on that LCD.
    DT

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

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

    Hi Darrel,
    Hmm, I wanted to move on to final stages of the project adding the locator code but before I could I came up against something I've not had before.

    I was using a 16f628A and wanted to port across to a 16F818 for a single adc channel use. (Monitor a pll control voltage)

    I had errors of "Argument out of range" when I added my usual working ADC code. It works standalone on the 818 nicely.

    The code for gps alone works in the 818 as per lcd pic. So I'm lost now.

    In the working gps code alone, no adc code. I did have some very odd messages re 'out of range' with the code with END at the finish of the code. It seemed like something was hidden in the space in MCS. Deleting back to the final Goto GPS cleared the messages.

    This is the gps code with adc which errors. I daren't add the locator code yet

    Code:
    ; 
    ;
    ; 			        PIC16F818                             
    ;                          __________                                          
    ;     D6-------------RAN2 |1       18| RAN1---------D5                   
    ;     D7-------------RAN3 |2       17| RAN0---------D4                 
    ;     LED------------RAN4 |3       16| OSC1--------XTAL                        
    ;     +5V-----------!MCLR |4       15| OSC2--------XTAL                        
    ;     Ground----------Vss |5       14| VDD---------+5 V                        
    ;     NMEA data-------RB0 |6       13| RB7---------Not used                   
    ;     Serial data out-RB1 |7       12| RB6---------Not used
    ;     Not used--------RB2 |8       11| RB5---------LCD Enable          
    ;     Pushbutton------RB3 |9       10| RB4---------LCD Register select         
    ;                          ----------                                          
    ; 
    
    ;====================================================================='
    ' Program to display returned value of a GPS on RB0
    ' LCD in 4-BIT mode PIC16F818 controller 4Mhz clock Fuse PWRT BODEN
    ' 
    'GPS sentence: $GPRMC,192144.62,A,5041.6058,N,00412.6124,E,0.45,3 57.74,081205,,*0B
    
    
    Define LCD_DREG PORTA          ' Port for LCD Data
    Define LCD_DBIT 0              ' Use upper 4 bits of Port  
    Define LCD_RSREG PORTB         ' Port for RegisterSelect (RS) bit
    Define LCD_RSBIT 4             ' Port Pin for RS bit  (pin9)
    Define LCD_EREG PORTB          ' Port for Enable (E) bit
    Define LCD_EBIT 5              ' Port Pin for E bit    (pin7)
    Define LCB_BITS 4              ' Using 4-bit bus
    Define LCD_LINES 4             ' Using 2 line Display
    Define LCD_COMMANDUS 1500      ' Command Delay (uS)
    define LCD_DATAUS 50           ' Data Delay (uS)
    
    DEFINE OSC 4
    
    OPTION_REG.7=0                 ' Enable Pull-Up's
    GPSin VAR PORTB.0
    ' Initialise ADC
    ADCON1 = %10000100 ' Set PORTA analog and RIGHT justify result
    ADCON0 = %01010001 ' Configure and turn on A/D Module channel 4 Fosc 8
    PAUSE 500
    
    'Declare variables
    val VAR WORD      ' final calculated adc valuesWORD' final calculated adc values
    volt VAR WORD     ' scaled value real part
    voltd1 VAR WORD   ' scaled value first decimal place
    voltd2 VAR WORD   ' scaled value second decimal place
    i var byte        ' counter
    
    '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
    NS VAR BYTE             'north or south
    londeg VAR BYTE         'degrees longitude
    lonmin VAR BYTE         'minutes longitude
    EW VAR BYTE             'east or west
    d VAR BYTE              'day
    m VAR BYTE              'month
    y VAR BYTE              'year
    
    fix VAR WORD 'GPS fix
    
    LCDOut $fe,$80,"   GPS Decoder  "
    LCDOut $FE,$c0, "    G8VLQ Mk1  "
    Pause 500
    LCDOut $FE, 1           'Clear Screen
    
    GPS: 'read GPS
    
    SerIn2 GPSin,188,Timeout,LCD1,[wait("$GPRMC"),wait(","),DEC2 hh,DEC2 mm,DEC2 ss,wait(",")_
    ,fix,wait(","),DEC2 latdeg,DEC2 latmin,wait(","),NS,wait(","),DEC3 londeg,DEC2 lonmin,_
    wait(","),EW,wait(","),knots,wait("."),DEC2 knotsten,wait(","),DEC3 course,wait(","),DEC2 d,DEC2 m,DEC2 y]
    
    
    IF fix="V" Then         'if no GPS fix
    GOTO LCD1
    EndIF
    
    gosub PLL
    
    LCD:      
               
    LCDOut $fe,$80,DEC2 d,"-",DEC2 m,"-",DEC2 y," ",#volt, ".", # voltd1,# voltd2, "Vdc"            ; 80 1st line   
    LCDOUT $fe,$c0,"    ",DEC2 hh,":",DEC2 mm,":",DEC2 ss,"    "                                ; c0 2nd line
    LCDOut $fe,$90," LAT: ",DEC2 latdeg,",",DEC2 latmin," ",NS                                 ; 90 3rd line
    LCDOut $fe,$d0," LON: ",DEC2 londeg,",",DEC2 lonmin," ",EW                                 ; d0 4th line
    
    GoTo GPS
    
    LCD1:       ; If invalid data, just shows gps string is received
    
    LCDOut $fe,$80,#volt, ".", # voltd1,# voltd2, "Vdc"                                         ; 80 1st line
    LCDOUT $fe,$c0,"     No Fix       "                                                       ; c0 2nd line
    LCDOut $fe,$90," LAT: ",DEC2 latdeg,",",DEC2 latmin," ",NS                                ; 90 3rd line
    LCDOut $fe,$d0," LON: ",DEC2 londeg,",",DEC2 lonmin," ",EW                                ; d0 4th line
    
    goto GPS
    
    LCD2:      ; 20 character display. Put time and date on first line , removed names.
               ; callsign and QRA (maidenhead) on second line
    
    LCDOut $fe,$80,DEC2 d,"-",DEC2 m,"-",DEC2 y,DEC2 hh,":",DEC2 mm                         ; 80 1st line
    LCDOut $fe,$80," G8VLQ   "                                                              ; c0 2nd line
    LCDOut $fe,$90,"LAT: ",DEC2 latdeg,",",DEC2 latmin," ",NS                                ; 90 3rd line
    LCDOut $fe,$d0,"LON: ",DEC2 londeg,",",DEC2 lonmin," ",EW                                ; d0 4th line
    
    GoTo GPS
    
    PLL:
    Val = 0                       ' Value returned is the average of 5 conversions
    For i = 0 TO 4
    ADCON0.4 = 1                  ' Start conversion
    NoteDone:
    pause 1
    IF ADCON0.4 = 1 Then NoteDone
    val = val + ((ADRESH * 256)+(ADRESL))
    nEXT I
    VAL = VAL/5
    ' Calculate Volatage to 2 decimal places
    volt = val * 5/1024
    voltd1 = ( val * 5//1024) * 10/1024
    Voltd2 = ((val *5 //1024) * 10//1024) * 10/1024
    RETURN
    Rob.

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

  21. #21
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

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

    The 16F628A has 2K words of program space.
    The 16F818 only has 1K words.

    You're going to need a bigger chip.
    The Maidenhead routine with Floating point libraries will take >1.5K by itself.

    You'll need at least 4K, but why not get one with 8K so you won't have the problem again later.
    I'm sure you'll want to add a Morse Code transmitter and receiver some day.
    DT

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

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

    Now that was completely stupid of me, I apologise for such a silly mistake. I had never seen the message before and assumed it was a code error.

    I never gave it a thought to look at the chip spec. The reason to change over to 818 was just one adc input. The chip otherwise is pin compatible for what I've already done.

    I think I will remake a new display pcb and use the 16f876 28 pin chip that has 8k.

    The project uses the chip to accept the NMEA string from a Rockwell gps module and display it. This older gps module also produces accurate 1PPS and 10kHz signals when gps has a fix.
    I'm using these signals on a pll and divider board to lock a 10mhz tcxo.

    In its present application it would have worked fine but I wanted to monitor the gps pll control voltage on the board to check for frequency lock.
    If the voltage was 1.65v then the oscillator was in lock state.
    The display did show whether the satellites produced a fix but not whether the oscillator had locked against the 10khz frequency. Watching the pll control voltage hunt back and forth whilst the gps attempted a fix was facinating but impractical for 'normal' usage.

    Once I have the display running again I'll report back.
    Rob.

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

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

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

    Just looked in my box o bits and found a 18f1330 which is pin compatible with 4k space.

    Not quite pin compatible unfortunately, ports mixed
    Last edited by tasmod; - 24th March 2014 at 11:02.
    Rob.

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

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

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

    Here you go Darrel -

    Name:  biglcd.jpg
Views: 3848
Size:  42.1 KB


    That display is huge at 4inch by 2 inch (See pic chip in background) Used a 16f876a in the end. That's your BigDigit code put to use as well.
    Display shows 1.65v which indicates to me that the oscillator control voltage is stable and in lock.

    Code needs some polishing especially Month but that's a work in progress :-

    Code:
    ; 
    ;
    ; 			        PIC16F876a                             
    ;                          __________                                          
    ;                   !MCLR |1        28| RB7------D7              
    ;     PLL Volt--AN0---RA0 |2        27| RB6------D6          
    ;         Temp--AN1---RA1 |3        26| RB5------D5                     
    ;               AN2---RA2 |4        25| RB4------D4                     
    ;               AN3---RA3 |5        24| RB3------LCD E                     
    ;         NMEA data---RA4 |6        23| RB2------LCD RS                
    ;               AN4---RA5 |7        22| RB1------
    ;            Ground---Vss |8        21| RB0------       
    ;             OSC1---XTAL |9        20| VDD------ +5 V        
    ;             OSC2---XTAL |10       19| Vss------Ground
    ;                  ---RC0 |11       18| RC7------ 
    ;                  ---RC1 |12       17| RC6------
    ;                  ---RC2 |13       16| RC5------
    ;           pbutton---RC3 |14       15| RC4------           
    ;                          ----------                                          
    ; 
    ;   Serial data out               Not used    Not used        
    ;====================================================================='
    ' Program to display returned value of a GPS on RA4
    ' LCD in 4-BIT mode PIC16F876a controller 4Mhz clock Fuse PWRT BODEN
    ' 
    'GPS sentence: $GPRMC,192144.62,A,5041.6058,N,00412.6124,E,0.45,3 57.74,081205,,*0B
    
    @__config_HS_OSC 
    @__config_BOD_OFF 
    @__config_PWRT_ON 
    @__config_WDT_ON 
    @__config_PROTECT_OFF 
    @__config_LVP_OFF
    
    ;-- Place a copy of these variables in your Main program -------------------
    ;--   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
    ' --------------------------------------------------------------------------
    
    INCLUDE "FP20.bas"     ; 24-bit Floating Point for 14-bit cores with RAM at $20
    
    
    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
    
    OPTION_REG.7=0                 ' Enable Pull-Up's
    GPSin VAR PORTA.4
    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
    PAUSE 500
    
    'Declare variables
    val VAR WORD      ' final calculated adc valuesWORD' final calculated adc values
    volt VAR WORD     ' scaled value real part
    voltd1 VAR WORD   ' scaled value first decimal place
    voltd2 VAR WORD   ' scaled value second decimal place
    i var byte        ' counter
    
    '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 BYTE        'seconds latitude
    NS VAR BYTE             'north or south
    londeg VAR BYTE         'degrees longitude
    lonmin VAR BYTE         'minutes longitude
    lonsecs VAR BYTE        'seconds longtitude
    EW VAR BYTE             'east or west
    d VAR BYTE              'day
    m VAR BYTE              'month
    y VAR BYTE              'year
    
    MH     VAR BYTE[6]
    
    LonMinDec VAR BYTE
    LonDir    VAR BYTE
    
    LatMinDec VAR BYTE
    LatDir    VAR BYTE
    
    nPos  var byte
    nDig  var byte
    
    '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,$40,$02,$02,$02,$02,$02,$02,$02,$02  ' Cust Char #0   
    LCDOUT  $FE,$48,$1F,$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,$1F,$1F,$1B,$1B,$1B,$1B,$1F,$1F  ' Cust Char #4     
    LCDOUT  $FE,$68,$1B,$1B,$1B,$1B,$1B,$1B,$1F,$1F  ' Cust Char #5  
    LCDOUT  $FE,$70,$1F,$1F,$03,$03,$03,$03,$1F,$1F  ' Cust Char #6    
    LCDOUT  $FE,$78,$1F,$1F,$03,$03,$03,$03,$03,$03  ' Cust Char #7 
    LCDOUT  $FE,$40,$03,$03,$03,$03,$03,$03,$03,$03  ' Cust Char #8 
    
    
    fix VAR WORD 'GPS fix
    
    LCDOut $fe,$80,"    GPS Decoder     "
    LCDOut $FE,$c0," G8VLQ  March 2014  "
    Pause 3000
    LCDOut $FE, 1           'Clear Screen
    
    
    GPS: 'read GPS
    
    SerIn2 GPSin,188,Timeout,Clock,[wait("$GPRMC"),wait(","),DEC2 hh,DEC2 mm,DEC2 ss,wait(","),fix,wait(",")_
    ,DEC2 latdeg,DEC2 latmin,wait("."),DEC2 latsecs,wait(","),NS,wait(","),DEC3 londeg,DEC2 lonmin,wait("."),DEC2 lonsecs,_
    wait(","),EW,wait(","),knots,wait("."),DEC2 knotsten,wait(","),DEC3 course,wait(","),DEC2 d,DEC2 m,DEC2 y]
    
    LonMinDec = lonmin
    LatMinDec = latmin
    LonDir = EW
    LatDir = NS
    
    gosub PLL         ;pll control voltage
    GOSUB Locator     ;maidenhead locator
    GOSUB Clock      ; Large digit clock
    goto GPS
    
    If m = 01 then gosub January          ; show month
    If m = 02 then gosub February
    If m = 03 then gosub March
    If m = 04 then gosub April
    If m = 05 then gosub May
    If m = 06 then gosub June
    If m = 07 then gosub July
    If m = 08 then gosub August
    If m = 09 then gosub September
    If m = 10 then gosub October
    If m = 11 then gosub November
    If m = 12 then gosub December
    
    
    ;-------------------------------------------------------------
    
    PLL:
    Val = 0                       ' Value returned is the average of 5 conversions
    For i = 0 TO 4
    ADCON0.2 = 1                  ' Start conversion
    NotDone:
    pause 1
    IF ADCON0.2 = 1 Then NotDone
    val = val + ((ADRESH * 256)+(ADRESL))
    nEXT I
    VAL = VAL/5
    ' Calculate Voltage to 2 decimal places
    volt = val * 5/1024
    voltd1 = ( val * 5//1024) * 10/1024
    Voltd2 = ((val *5 //1024) * 10//1024) * 10/1024
    RETURN
    
    ;---------------------------------------------
    
    Locator:
    ;----[convert Longitude Sexagesimal to Decimal Degrees]-------------------------
    Aint = LonMinDec : GOSUB ItoFA    ; decimal portion of Minutes
    Bint = 100 : 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 LonDir = "W" THEN              ; if west of Prime Meridian
        GOSUB AtoB
        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]------------------------------------------
    GOSUB SaveLon                     ; save Longitude for later
    Bint = 20   : GOSUB ItoFB         ; Lon / 20
    GOSUB fpdiv
    GOSUB SaveAARG                    ; save AARG for modulus
    GOSUB FtoIA                       ; get integer
    MH(0) = "A" + Aint                ; + "A" = First character
    
                                      ; -- do  Lon // 20 --- (modulus)
    Bint = Aint                       ; copy integer result to BARG
    GOSUB ItoFB                       ; convert it to float
    GOSUB RestoreAARG                 ; restore Lon / 20 to AARG
    GOSUB fpsub                       ; subtract integer
    Bint = 20                         ; multiply times original divisor (20)
    GOSUB ItoFB
    GOSUB fpmul                       ; AARG now contains the modulus
    
    Bint = 2    : GOSUB ItoFB         ; divide modulus by 2
    GOSUB fpdiv
    GOSUB FtoIA                       ; get integer
    MH(2) = "0" + Aint                ; + "0" = Third character
    
    GOSUB RestoreLon                  ; restore Longitude
    Bint = 2 : GOSUB ItoFB
    GOSUB fpdiv                       ; divide by 2
    
    GOSUB FtoIA                       ; get integer
    Bint = Aint * 2  : GOSUB ItoFB    ; put int * 2 in BARG, change back to float
    GOSUB RestoreLon                  ; restore original Longitude
    GOSUB fpsub                       ; subtract A - B
    
    Bint = 12 : GOSUB ItoFB           ; Multiply * 12
    GOSUB fpmul
    GOSUB FtoIA                       ; get integer
    
    MH(4) = "a" + Aint                ; + "a" = Fifth Character
    
    ;----[convert Latitude Sexagesimal to Decimal Degrees]--------------------------
    Aint = LatMinDec : GOSUB ItoFA    ; decimal portion of Minutes
    Bint = 100 : 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 LatDir = "S" THEN              ; if south of equator
        GOSUB AtoB
        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]------------------------------------------
    GOSUB SaveLon                     ; save Latitude for later
    Bint = 10   : GOSUB ItoFB         ; Lat / 10
    GOSUB fpdiv
    GOSUB SaveAARG                    ; save AARG for modulus
    GOSUB FtoIA
    MH(1) = "A" + Aint                ; + "A" = Second character
    
                                      ; -- do  Lat // 10 --- (modulus)
    Bint = Aint                       ; copy integer result to BARG
    GOSUB ItoFB                       ; convert it to float
    GOSUB RestoreAARG                 ; restore Lat / 10 to AARG
    GOSUB fpsub                       ; subtract integer
    Bint = 10                         ; multiply times original divisor (10)
    GOSUB ItoFB
    GOSUB fpmul                       ; AARG now contains the modulus
    
    GOSUB FtoIA
    MH(3) = "0" + Aint                ; + "0" = Fourth character
    
    GOSUB RestoreLon                  ; restore original Latitude
    GOSUB FtoIA                       ; get integer
    Bint = Aint : GOSUB ItoFB         ; put int in BARG, change back to float
    GOSUB RestoreLon                  ; restore original Latitude
    GOSUB fpsub                       ; subtract A - B
    
    Bint = 24 : GOSUB ItoFB           ; Multiply * 24
    GOSUB fpmul
    GOSUB FtoIA                       ; get integer
    
    MH(5) = "a" + Aint                ; + "a" = Sixth character
    
    ;----[Maidenhead conversion complete]-------------------------------------------
    RETURN
    ;-------------------------------------------------------------------------------
    Aexp_Copy    VAR BYTE
    AARGB0_Copy  VAR BYTE
    AARGB1_Copy  VAR BYTE
    AARGB2_Copy  VAR BYTE
    
    Aexp_Lon     VAR BYTE
    AARGB0_Lon   VAR BYTE
    AARGB1_Lon   VAR BYTE
    AARGB2_Lon   VAR BYTE
    
    SaveAARG:
        Aexp_Copy = Aexp
        AARGB0_Copy = AARGB0
        AARGB1_Copy = AARGB1
        AARGB2_Copy = AARGB2
    RETURN
    
    RestoreAARG:
        Aexp = Aexp_Copy
        AARGB0 = AARGB0_Copy
        AARGB1 = AARGB1_Copy
        AARGB2 = AARGB2_Copy
    RETURN
    
    AtoB:
        Bexp = Aexp
        BARGB0 = AARGB0
        BARGB1 = AARGB1
        BARGB2 = AARGB2
    RETURN
    
    SaveLon:
        Aexp_Lon = Aexp
        AARGB0_Lon = AARGB0
        AARGB1_Lon = AARGB1
        AARGB2_Lon = AARGB2
    RETURN
    
    RestoreLon:
        Aexp = Aexp_Lon
        AARGB0 = AARGB0_Lon
        AARGB1 = AARGB1_Lon
        AARGB2 = AARGB2_Lon
    RETURN
    ;---------------------------------------
    
    January:
    LCDOut $fe,$80,DEC2 d," Jan ",DEC2 y,"  ",DEC2 hh,":",DEC2 mm,":",DEC2 ss
    RETURN
    
    February:
    LCDOut $fe,$80,DEC2 d," Feb ",DEC2 y,"  ",DEC2 hh,":",DEC2 mm,":",DEC2 ss
    RETURN
    
    March:
    LCDOut $fe,$80,DEC2 d," Mar ",DEC2 y,"  ",DEC2 hh,":",DEC2 mm,":",DEC2 ss
    RETURN
    
    April:
    LCDOut $fe,$80,DEC2 d," Apr ",DEC2 y,"  ",DEC2 hh,":",DEC2 mm,":",DEC2 ss
    RETURN
    
    May:
    LCDOut $fe,$80,DEC2 d," May ",DEC2 y,"  ",DEC2 hh,":",DEC2 mm,":",DEC2 ss
    RETURN
    
    June:
    LCDOut $fe,$80,DEC2 d," Jun ",DEC2 y,"  ",DEC2 hh,":",DEC2 mm,":",DEC2 ss
    RETURN
    
    July:
    LCDOut $fe,$80,DEC2 d," Jul ",DEC2 y,"  ",DEC2 hh,":",DEC2 mm,":",DEC2 ss
    RETURN
    
    August:
    LCDOut $fe,$80,DEC2 d," Aug ",DEC2 y,"  ",DEC2 hh,":",DEC2 mm,":",DEC2 ss
    RETURN
    
    September:
    LCDOut $fe,$80,DEC2 d," Sep ",DEC2 y,"  ",DEC2 hh,":",DEC2 mm,":",DEC2 ss
    RETURN
    
    October:
    LCDOut $fe,$80,DEC2 d," Oct ",DEC2 y,"  ",DEC2 hh,":",DEC2 mm,":",DEC2 ss
    RETURN
    
    November:
    LCDOut $fe,$80,DEC2 d," Nov ",DEC2 y,"  ",DEC2 hh,":",DEC2 mm,":",DEC2 ss
    RETURN
    
    December:
    LCDOut $fe,$80,DEC2 d," Dec ",DEC2 y,"  ",DEC2 hh,":",DEC2 mm,":",DEC2 ss
    RETURN
     
    ;--------------------------------------------------------------------------
    
    Clock:                     ;Display time
     
        nDig=hh dig 1 : nPos=1 : gosub displaydigit
        nDig=hh dig 0 : nPos=2 : gosub displaydigit
          npos=3 : gosub colon
        ndig=mm dig 1 : npos=4 : gosub displaydigit
        ndig=mm dig 0 : npos=5 : gosub displaydigit
          npos=6 : gosub colon
        ndig=ss dig 1 : npos=7 : gosub displaydigit
        ndig=ss dig 0 : npos=8 : gosub displaydigit
        
    LCDOut $fe,$80+9,"  ",DEC2 d,"-",DEC2 m,"-",DEC2 y   
    LCDOut $fe,$c0+9,"    ",#volt, ".", # voltd1,# voltd2,"v" 
    LCDOUT $fe,$94,"   G8VLQ    ",STR MH\6
    LCDOut $fe,$d4,DEC2 latdeg,$DF,DEC2 latmin,"'",DEC2 latsecs,NS," ",DEC2 londeg,$DF,DEC2 lonmin,"'",DEC2 lonsecs,EW                           ; ,#volt, ".", # voltd1,# voltd2,"v"   ; d4 4th line 
    
    
    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,$2E   
    return
    Last edited by tasmod; - 2nd April 2014 at 13:12.
    Rob.

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

  25. #25
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

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

    WooHoo!! That's Beeeeauuuutiful Rob!

    I'm so glad to see it working.

    I do have some suggestions for you about the configs, Months, volts ...
    When your ready to work on it some more.

    P.S. Nice picture of yourself too.
    DT

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

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

    Glad you like it Darrel. I'm very pleased with it. Any ideas very welcome.

    I have also coded a full digit clock over the four lines. At the moment it's a standalone code due to the character loading. Is it possible to load the second set of characters, replacing the original, on a button push ? Maybe using EXT ?

    The idea was to have dual display, button push changes from that shown in pic to a full clock and back again on another push.

    Name:  fulllcd.jpg
Views: 2902
Size:  33.5 KB
    Last edited by tasmod; - 2nd April 2014 at 21:55.
    Rob.

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

  27. #27
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

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

    Yes, you can have as many custom character sets as you want.
    But only one set can be loaded at a time.

    In your last code, the configs you have aren't doing anything.
    They should look like this ... make sure the defaults are commented out in the 16F876A.inc file in your PBP folder.
    Code:
    @  __config  _HS_OSC & _WDT_ON & _PWRTE_ON & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _WRT_OFF & _DEBUG_OFF & _CP_OFF
    And how's this look for the Months ...
    Code:
    DateTime:
        LCDOut $fe,$80,DEC2 d," "
        GOSUB ShowMonth
        LCDOut " ",DEC2 y,"  ",DEC2 hh,":",DEC2 mm,":",DEC2 ss
    RETURN
    
    ShowMonth:
        Idx = (m - 1) * 3
        FOR X = Idx TO Idx + 2
            LOOKUP X,["JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"],Char
            LCDOUT Char
        NEXT X
    RETURN
    DT

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

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

    Hmm, I've always had problems with configs.

    A single line config errors out. Multiple lines actually works and sets my programmer fuses OK.

    I also have severe problems with Mpasmwin 5.20 giving hundreds of errors with PBP which I now just ignore.


    I like the Months code. That's one of the things I just couldn't get right but I was thinking that way.

    How would I go about loading the character set ? I just don't get it.

    The brain is full of different ideas for the project, so many options. Even thought of two lcds.
    Rob.

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

  29. #29
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    Quote Originally Posted by tasmod
    A single line config errors out. Multiple lines actually works and sets my programmer fuses OK.
    Code:
    @__config_HS_OSC 
    @__config_BOD_OFF 
    @__config_PWRT_ON 
    @__config_WDT_ON 
    @__config_PROTECT_OFF 
    @__config_LVP_OFF
    Those lines are not configuration statements.
    They are actually assembly language labels. You could use an asm GOTO to jump to any one of them.
    They will not set the configuration bits in your programmer.

    If the one line __config I gave you gives an error, it's probably the "Overwriting address 2007" error that means you didn't comment the default configs in the .inc file.

    I also have severe problems with Mpasmwin 5.20 giving hundreds of errors with PBP which I now just ignore.
    Very bad idea.
    You should track down every error and fix it.
    How would you know if there are real errors if you always just ignore them.
    If you don't know what they mean ... get help.

    How would I go about loading the character set ? I just don't get it.
    These lines from your code load the custom characters
    Code:
    LCDOUT  $FE,$40,$03,$03,$03,$03,$03,$03,$03,$03  ' Cust Char #0 
    'LCDOUT  $FE,$40,$02,$02,$02,$02,$02,$02,$02,$02  ' Cust Char #0   
    LCDOUT  $FE,$48,$1F,$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,$1F,$1F,$1B,$1B,$1B,$1B,$1F,$1F  ' Cust Char #4     
    LCDOUT  $FE,$68,$1B,$1B,$1B,$1B,$1B,$1B,$1F,$1F  ' Cust Char #5  
    LCDOUT  $FE,$70,$1F,$1F,$03,$03,$03,$03,$1F,$1F  ' Cust Char #6    
    LCDOUT  $FE,$78,$1F,$1F,$03,$03,$03,$03,$03,$03  ' Cust Char #7 
    LCDOUT  $FE,$40,$03,$03,$03,$03,$03,$03,$03,$03  ' Cust Char #8
    You'll have another set of similar lines for your 4-line big digits.
    Executing those lines will overwrite the customs characters you previously loaded.

    However, you can only have 8 custom characters at a time, and you have 9 listed above.
    The one commented as Cust Char #8, is actually Cust Char #0 and will overwrite the first Cust Char #0. Good thing they're the same.
    DT

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

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

    Hi Darrel,

    Many thanks for your help.

    The code I posted was the last working example on this PC connected to the net. The actual programming pc is in another room and not net connected (deliberately). There were a couple of errors, the second $40 character set was one and a missing RETURN was another.
    The Month routine was deliberately moved down from the GPS loop. Since the post I moved it into the loop and reformatted the display lines to suit the new layout. I will however look at the array solution now.

    I've always had problems with Mpasmwin and errors. For instance the code posted has 891 errors at assembly, all of which relate to standard PBP instructions. e.g. LCDOUT alone is an error, FOR is an error etc. etc.

    This is a sample around your Locator code :-
    Error[122] C:\FPOINT\NMEA16F876ABIG.ASM 1049 : Illegal opcode (_LatDir)
    Warning[207] C:\FPOINT\NMEA16F876ABIG.ASM 1052 : Found label after column 1. (GOSUB?L)
    Error[122] C:\FPOINT\NMEA16F876ABIG.ASM 1052 : Illegal opcode (_AtoB)
    Warning[207] C:\FPOINT\NMEA16F876ABIG.ASM 1058 : Found label after column 1. (GOSUB?L)
    Error[122] C:\FPOINT\NMEA16F876ABIG.ASM 1058 : Illegal opcode (_itofa)
    Warning[207] C:\FPOINT\NMEA16F876ABIG.ASM 1061 : Found label after column 1. (GOSUB?L)
    Error[122] C:\FPOINT\NMEA16F876ABIG.ASM 1061 : Illegal opcode (_fpsub)
    Warning[207] C:\FPOINT\NMEA16F876ABIG.ASM 1064 : Found label after column 1. (LABEL?L)
    Error[122] C:\FPOINT\NMEA16F876ABIG.ASM 1064 : Illegal opcode (L00042)
    Warning[207] C:\FPOINT\NMEA16F876ABIG.ASM 1070 : Found label after column 1. (GOSUB?L)
    Error[122] C:\FPOINT\NMEA16F876ABIG.ASM 1070 : Illegal opcode (_itofb)
    Warning[207] C:\FPOINT\NMEA16F876ABIG.ASM 1073 : Found label after column 1. (GOSUB?L)
    Error[122] C:\FPOINT\NMEA16F876ABIG.ASM 1073 : Illegal opcode (_fpadd)
    Warning[207] C:\FPOINT\NMEA16F876ABIG.ASM 1076 : Found label after column 1. (GOSUB?L)
    Error[122] C:\FPOINT\NMEA16F876ABIG.ASM 1076 : Illegal opcode (_SaveLon)
    Warning[207] C:\FPOINT\NMEA16F876ABIG.ASM 1082 : Found label after column 1. (GOSUB?L)
    Error[122] C:\FPOINT\NMEA16F876ABIG.ASM 1082 : Illegal opcode (_itofb)
    Warning[207] C:\FPOINT\NMEA16F876ABIG.ASM 1085 : Found label after column 1. (GOSUB?L)
    Error[122] C:\FPOINT\NMEA16F876ABIG.ASM 1085 : Illegal opcode (_fpdiv)
    Warning[207] C:\FPOINT\NMEA16F876ABIG.ASM 1088 : Found label after column 1. (GOSUB?L)
    Error[122] C:\FPOINT\NMEA16F876ABIG.ASM 1088 : Illegal opcode (_SaveAARG)
    Warning[207] C:\FPOINT\NMEA16F876ABIG.ASM 1091 : Found label after column 1. (GOSUB?L)
    Error[122] C:\FPOINT\NMEA16F876ABIG.ASM 1091 : Illegal opcode (_ftoia)
    Warning[207] C:\FPOINT\NMEA16F876ABIG.ASM 1094 : Found label after column 1. (ADD?CWB)
    Error[108] C:\FPOINT\NMEA16F876ABIG.ASM 1094 : Illegal character (0)
    I will re-install 5.20 and see if it cures it. I'm sure years back I didn't have the problem.
    Rob.

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

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

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

    SOLVED. Wrong MPASM Suite.

    I'm using PBP2.50 and at some point I must have upgraded the MPASM Suite to 8.90.
    I needed to delete and re-install 8.15 instead.

    I now get a complete compile and assemble without any errors.

    Just needed to think quietly about the problem.
    Rob.

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

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

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

    Darrel,

    I tried incorporating your Month code but it causes odd errors in the ShowMonth, based on the FOR/NEXT loop and especially the idx. This is maybe where I placed it in the code but I will continue to try it.

    Right now I have completed the code using the long Month code and I'm able to toggle back and forth between all info onscreen and the fullscreen big digit clock.

    Code:
    ; 
    ;
    ; 			        PIC16F876a                             
    ;                          __________                                          
    ;                          !MCLR |1        28| RB7------D7              
    ;     PLL Volt--AN0---RA0 |2        27| RB6------D6          
    ;         Temp--AN1---RA1 |3        26| RB5------D5                     
    ;                    AN2---RA2 |4        25| RB4------D4                     
    ;                    AN3---RA3 |5        24| RB3------LCD E                     
    ;           NMEA data---RA4 |6        23| RB2------LCD RS                
    ;                    AN4---RA5 |7        22| RB1------
    ;                Ground---Vss |8        21| RB0------       
    ;                OSC1---XTAL |9        20| VDD------ +5 V        
    ;                OSC2---XTAL |10       19| Vss------Ground
    ;                         ---RC0 |11       18| RC7------ 
    ;                         ---RC1 |12       17| RC6------
    ;                         ---RC2 |13       16| RC5------
    ;              pbutton---RC3 |14       15| RC4------           
    ;                          ----------                                          
    ; 
    ;      
    ;====================================================================='
    ' Program to display returned value of a GPS on RA4
    ' LCD in 4-BIT mode PIC16F876a controller 4Mhz clock Fuse PWRT BODEN
    ' 
    'GPS sentence: $GPRMC,192144.62,A,5041.6058,N,00412.6124,E,0.45,3 57.74,081205,,*0B
    
    
    @  __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 -------------------
    ;--   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
    ' --------------------------------------------------------------------------
    
    INCLUDE "FP20.bas"     ; 24-bit Floating Point for 14-bit cores with RAM at $20
    
    
    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
    
    OPTION_REG.7=0                 ' Enable Pull-Up's
    GPSin VAR PORTA.4
    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
    PAUSE 500
    
    'Declare variables
    val VAR WORD      ' final calculated adc valuesWORD' final calculated adc values
    volt VAR WORD     ' scaled value real part
    voltd1 VAR WORD   ' scaled value first decimal place
    voltd2 VAR WORD   ' scaled value second decimal place
    i var byte        ' counter
    
    '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 BYTE        'seconds latitude
    NS VAR BYTE             'north or south
    londeg VAR BYTE         'degrees longitude
    lonmin VAR BYTE         'minutes longitude
    lonsecs VAR BYTE        '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
    
    MH     VAR BYTE[6]
    
    LonMinDec VAR BYTE
    LonDir    VAR BYTE
    
    LatMinDec VAR BYTE
    LatDir    VAR BYTE
    
    nPos  var byte
    nDig  var byte
    
    fix VAR WORD 'GPS fix
    
    LCDOut $fe,$80,"    GPS Decoder     "
    LCDOut $FE,$c0," G8VLQ  March 2014  "
    Pause 3000
    LCDOut $FE, 1           'Clear Screen
    
    butt = 0
    marker = 0
    
    
    GPS: 'read GPS  #############################################################################################
    
    SerIn2 GPSin,188,Timeout,Clock,[wait("$GPRMC"),wait(","),DEC2 hh,DEC2 mm,DEC2 ss,wait(","),fix,wait(",")_
    ,DEC2 latdeg,DEC2 latmin,wait("."),DEC2 latsecs,wait(","),NS,wait(","),DEC3 londeg,DEC2 lonmin,wait("."),DEC2 lonsecs,_
    wait(","),EW,wait(","),knots,wait("."),DEC2 knotsten,wait(","),DEC3 course,wait(","),DEC2 d,DEC2 m,DEC2 y]
    
    IF marker = 1 THEN BigClock
    
    LonMinDec = lonmin
    LatMinDec = latmin
    LonDir = EW
    LatDir = NS
    
    BUTTON Pbutton,0,100,0,butt,1,BigClockClear
    
    If m = 01 then gosub January          ; show month
    If m = 02 then gosub February
    If m = 03 then gosub March
    If m = 04 then gosub April
    If m = 05 then gosub May
    If m = 06 then gosub June
    If m = 07 then gosub July
    If m = 08 then gosub August
    If m = 09 then gosub September
    If m = 10 then gosub October
    If m = 11 then gosub November
    If m = 12 then gosub December
    
    gosub PLL         ;pll control voltage
    GOSUB Locator     ;maidenhead locator
    GOSUB Clock       ;Large digit clock
    goto GPS          ; ##########################################################################################
    
    ;-------------------------------------------------------------
    
    PLL:
    Val = 0                       ' Value returned is the average of 5 conversions
    For i = 0 TO 4
    ADCON0.2 = 1                  ' Start conversion
    NotDone:
    pause 1
    IF ADCON0.2 = 1 Then NotDone
    val = val + ((ADRESH * 256)+(ADRESL))
    nEXT I
    VAL = VAL/5
    ' Calculate Voltage to 2 decimal places
    volt = val * 5/1024
    voltd1 = ( val * 5//1024) * 10/1024
    Voltd2 = ((val *5 //1024) * 10//1024) * 10/1024
    RETURN
    
    ;---------------------------------------------
    
    Locator:
    ;----[convert Longitude Sexagesimal to Decimal Degrees]-------------------------
    Aint = LonMinDec : GOSUB ItoFA    ; decimal portion of Minutes
    Bint = 100 : 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 LonDir = "W" THEN              ; if west of Prime Meridian
        GOSUB AtoB
        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]------------------------------------------
    GOSUB SaveLon                     ; save Longitude for later
    Bint = 20   : GOSUB ItoFB         ; Lon / 20
    GOSUB fpdiv
    GOSUB SaveAARG                    ; save AARG for modulus
    GOSUB FtoIA                       ; get integer
    MH(0) = "A" + Aint                ; + "A" = First character
    
                                      ; -- do  Lon // 20 --- (modulus)
    Bint = Aint                       ; copy integer result to BARG
    GOSUB ItoFB                       ; convert it to float
    GOSUB RestoreAARG                 ; restore Lon / 20 to AARG
    GOSUB fpsub                       ; subtract integer
    Bint = 20                         ; multiply times original divisor (20)
    GOSUB ItoFB
    GOSUB fpmul                       ; AARG now contains the modulus
    
    Bint = 2    : GOSUB ItoFB         ; divide modulus by 2
    GOSUB fpdiv
    GOSUB FtoIA                       ; get integer
    MH(2) = "0" + Aint                ; + "0" = Third character
    
    GOSUB RestoreLon                  ; restore Longitude
    Bint = 2 : GOSUB ItoFB
    GOSUB fpdiv                       ; divide by 2
    
    GOSUB FtoIA                       ; get integer
    Bint = Aint * 2  : GOSUB ItoFB    ; put int * 2 in BARG, change back to float
    GOSUB RestoreLon                  ; restore original Longitude
    GOSUB fpsub                       ; subtract A - B
    
    Bint = 12 : GOSUB ItoFB           ; Multiply * 12
    GOSUB fpmul
    GOSUB FtoIA                       ; get integer
    
    MH(4) = "a" + Aint                ; + "a" = Fifth Character
    
    ;----[convert Latitude Sexagesimal to Decimal Degrees]--------------------------
    Aint = LatMinDec : GOSUB ItoFA    ; decimal portion of Minutes
    Bint = 100 : 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 LatDir = "S" THEN              ; if south of equator
        GOSUB AtoB
        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]------------------------------------------
    GOSUB SaveLon                     ; save Latitude for later
    Bint = 10   : GOSUB ItoFB         ; Lat / 10
    GOSUB fpdiv
    GOSUB SaveAARG                    ; save AARG for modulus
    GOSUB FtoIA
    MH(1) = "A" + Aint                ; + "A" = Second character
    
                                      ; -- do  Lat // 10 --- (modulus)
    Bint = Aint                       ; copy integer result to BARG
    GOSUB ItoFB                       ; convert it to float
    GOSUB RestoreAARG                 ; restore Lat / 10 to AARG
    GOSUB fpsub                       ; subtract integer
    Bint = 10                         ; multiply times original divisor (10)
    GOSUB ItoFB
    GOSUB fpmul                       ; AARG now contains the modulus
    
    GOSUB FtoIA
    MH(3) = "0" + Aint                ; + "0" = Fourth character
    
    GOSUB RestoreLon                  ; restore original Latitude
    GOSUB FtoIA                       ; get integer
    Bint = Aint : GOSUB ItoFB         ; put int in BARG, change back to float
    GOSUB RestoreLon                  ; restore original Latitude
    GOSUB fpsub                       ; subtract A - B
    
    Bint = 24 : GOSUB ItoFB           ; Multiply * 24
    GOSUB fpmul
    GOSUB FtoIA                       ; get integer
    
    MH(5) = "a" + Aint                ; + "a" = Sixth character
    
    ;----[Maidenhead conversion complete]-------------------------------------------
    RETURN
    ;-------------------------------------------------------------------------------
    Aexp_Copy    VAR BYTE
    AARGB0_Copy  VAR BYTE
    AARGB1_Copy  VAR BYTE
    AARGB2_Copy  VAR BYTE
    
    Aexp_Lon     VAR BYTE
    AARGB0_Lon   VAR BYTE
    AARGB1_Lon   VAR BYTE
    AARGB2_Lon   VAR BYTE
    
    SaveAARG:
        Aexp_Copy = Aexp
        AARGB0_Copy = AARGB0
        AARGB1_Copy = AARGB1
        AARGB2_Copy = AARGB2
    RETURN
    
    RestoreAARG:
        Aexp = Aexp_Copy
        AARGB0 = AARGB0_Copy
        AARGB1 = AARGB1_Copy
        AARGB2 = AARGB2_Copy
    RETURN
    
    AtoB:
        Bexp = Aexp
        BARGB0 = AARGB0
        BARGB1 = AARGB1
        BARGB2 = AARGB2
    RETURN
    
    SaveLon:
        Aexp_Lon = Aexp
        AARGB0_Lon = AARGB0
        AARGB1_Lon = AARGB1
        AARGB2_Lon = AARGB2
    RETURN
    
    RestoreLon:
        Aexp = Aexp_Lon
        AARGB0 = AARGB0_Lon
        AARGB1 = AARGB1_Lon
        AARGB2 = AARGB2_Lon
    RETURN
    ;---------------------------------------
    
    January:
    LCDOut $fe,$80+9,DEC2 d," Jan ","20",DEC2 y
    RETURN
    
    February:
    LCDOut $fe,$80+9,DEC2 d," Feb ","20",DEC2 y
    RETURN
    
    March:
    LCDOut $fe,$80+9,DEC2 d," Mar ","20",DEC2 y
    RETURN
    
    April:
    LCDOut $fe,$80+9,DEC2 d," Apr ","20",DEC2 y
    RETURN
    
    May:
    LCDOut $fe,$80+9,DEC2 d," May ","20",DEC2 y
    RETURN
    
    June:
    LCDOut $fe,$80+9,DEC2 d," Jun ","20",DEC2 y
    RETURN
    
    July:
    LCDOut $fe,$80+9,DEC2 d," Jul ","20",DEC2 y
    RETURN
    
    August:
    LCDOut $fe,$80+9,DEC2 d," Aug ","20",DEC2 y
    RETURN
    
    September:
    LCDOut $fe,$80+9,DEC2 d," Sep ","20",DEC2 y
    RETURN
    
    October:
    LCDOut $fe,$80+9,DEC2 d," Oct ","20",DEC2 y
    RETURN
    
    November:
    LCDOut $fe,$80+9,DEC2 d," Nov ","20",DEC2 y
    RETURN
    
    December:
    LCDOut $fe,$80+9,DEC2 d," Dec ","20",DEC2 y
    RETURN
     
     
    ;--------------------------------------------------------------------------
    ClockClear:
    
    LCDOut $FE, 1           'Clear Screen
    marker = 0
    GOTO GPS
    
    Clock:
                         ;Display time
    
    '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,$1F,$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,$1F,$1F,$1B,$1B,$1B,$1B,$1F,$1F  ' Cust Char #4     
    LCDOUT  $FE,$68,$1B,$1B,$1B,$1B,$1B,$1B,$1F,$1F  ' Cust Char #5  
    LCDOUT  $FE,$70,$1F,$1F,$03,$03,$03,$03,$1F,$1F  ' Cust Char #6    
    LCDOUT  $FE,$78,$1F,$1F,$03,$03,$03,$03,$03,$03  ' Cust Char #7 
    
    
    
        nDig=hh dig 1 : nPos=0 : gosub displaydigit
        nDig=hh dig 0 : nPos=1 : gosub displaydigit
          npos=2 : gosub colon
        ndig=mm dig 1 : npos=3 : gosub displaydigit
        ndig=mm dig 0 : npos=4 : gosub displaydigit
          npos=5 : gosub colon
        ndig=ss dig 1 : npos=6 : gosub displaydigit
        ndig=ss dig 0 : npos=7 : gosub displaydigit
          
    LCDOut $fe,$c0+9,"    ",#volt, ".", # voltd1,# voltd2,"v" 
    LCDOUT $fe,$94,"   G8VLQ    ",STR MH\6
    LCDOut $fe,$d4,DEC2 latdeg,$DF,DEC2 latmin,"'",DEC2 latsecs,NS,"  ",DEC2 londeg,$DF,DEC2 lonmin,"'",DEC2 lonsecs,EW                           ; ,#volt, ".", # voltd1,# voltd2,"v"   ; d4 4th line 
    
    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 Screen
    marker = 1
    
    BigClock:
    
    'Set up the digits (http://www.darreltaylor.com/files/CustChar.htm)
    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,$03,$07,$0F,$1E,$1C,$1C,$1C,$1C  ' Cust Char #2  
    LCDOUT  $FE,$58,$18,$1C,$1E,$0F,$07,$07,$07,$07  ' Cust Char #3  
    LCDOUT  $FE,$60,$1C,$1C,$1C,$1C,$1E,$0F,$07,$03  ' Cust Char #4     
    LCDOUT  $FE,$68,$07,$07,$07,$07,$0F,$1E,$1C,$18  ' 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 
    
    
    BUTTON Pbutton,0,100,0,butt,1,ClockClear
    
                         ;Display time
     
        nDig=hh dig 1 : nPos=0 : gosub displaydigit1
        nDig=hh dig 0 : nPos=3 : gosub displaydigit1
          npos=6 : gosub colon1
        ndig=mm dig 1 : npos=7 : gosub displaydigit1
        ndig=mm dig 0 : npos=10 : gosub displaydigit1
          npos=13 : gosub colon1
        ndig=ss dig 1 : npos=14 : gosub displaydigit1
        ndig=ss dig 0 : npos=17 : gosub displaydigit1   
    
    GOTO GPS
    
    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
    	LCDOUT $FE,$C0+nPos,1
        LCDOUT $FE,$C1+nPos,0
    	LCDOUT $FE,$94+nPos,1
        LCDOUT $FE,$95+nPos,0
    	LCDOUT $FE,$D4+nPos,4
        LCDOUT $FE,$D5+nPos,5
    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; - 3rd April 2014 at 11:31.
    Rob.

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

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

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

    Forgive me oh codemaster Darrel.

    The idiot has been programming again. I am but a lowly code serf with an aged addled brain.......................................I forgot to declare the variables in your Month routine.
    Rob.

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

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

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

    Complete working prototype system

    Name:  gpslcd.jpg
Views: 2927
Size:  62.9 KB

    Rockwell GPS Module on right. PLL and TCXO board on left. TCXO is small vertical board top left. Small board at top with all wires is 7805 5v reg board.

    Name:  gpsdo.jpg
Views: 2894
Size:  56.6 KB

    Rear of LCD showing piggyback decoder.

    Name:  llcdrear.jpg
Views: 2922
Size:  29.0 KB
    Last edited by tasmod; - 3rd April 2014 at 13:04.
    Rob.

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

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

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

    Darrel,

    Don't know if you are still reading this thread.

    I wondered how difficult it would be to add the final two numerical digits of the locator so that it is the full 8 digit string.

    I nearly destroyed the prototype when I took it out in the car to test the locator code. The car voltage meant the regulator board became really hot, I was afraid it would fail.

    Thanks,
    Rob.

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

  36. #36
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

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

    The code was based on the pearl script on the Wikipedia page, which only shows how to get 6 digits.

    Do you know of somewhere that shows how to get the last two digits?
    DT

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

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

    Surprisingly I do have it in asm if that helps. I think this is the applicable code after GPS string is parsed. Loc 1 to 8 are the Maidenhead.

    I wanted it all in PBP so I could do what I wanted to achieve. The final two are numeric digits. Mine is 03 if that helps re the original code.

    Code:
    ;'''''''''''''''  Process LONG term '''''''''''''''''''''''''''''''''
        bcf     STATUS, C
        rrf     LongD           ;Easiest to work with LongD/2 everywhere
        btfss   STATUS, C       ;  as Loc works on 2 deg intervals
        goto    NoLongMinsUpdate    
                                
        movlw   LOW(d'6000')    ;Add 1 degree's worth of carry into the 
        addwf   LongMLo         ;   minutes registers if LongD/2 has a carry
        btfsc   STATUS, C
        incf    LongMHi
        movlw   HIGH(d'6000')   ;LongM in range 0 -  12000
        addwf   LongMHi
    NoLongMinsUpdate            ;LongD' now in range 0 - 90
        btfss   NEGLONG
        goto    PosLong
        comf    LongD
        incf    LongD           ;LongD' now in 2's complement +/-90
        
        movf    LongMLo, w      ;Normalise LongM = 12000 - LongM
        sublw   LOW(d'12000')
        movwf   LongMLo         ;if borrow, C = 0, so increment the subtrahend 
        btfss   STATUS, C
        incf    LongMHi
        movf    LongMHi, w
        sublw   HIGH(d'12000')
        movwf   LongMHi
    
        decf    LongD           ;Correct Degrees
    
    PosLong
        movlw   d'90'
        addwf   LongD           ;Normalise D' to 0-180
        movf    LongD, w
        movwf   ALo
        clrf    AHi
    
        movlw   d'10'
        call    DivMod          ;Mod out in A, Div out in B
        movf    BLo, W
        addlw   "A"
        movwf   Loc1
        movf    ALo, w
        addlw   "0"
        movwf   Loc3
    
        rrf     LongMHi         ;Divide by 4 to give range 0 - 2999
        rrf     LongMLo
        rrf     LongMHi
        rrf     LongMLo
        movlw   0x3F
        andwf   LongMHi
    
        movf    LongMLo, w      ;Mins * 100 / 4  DIV 125
        movwf   ALo
        movf    LongMHi, w
        movwf   AHi
        movlw   d'125'
        call    DivMod          ;Mod out in A, Div out in B
        movf    BLo, w
        addlw   "A"
        movwf   Loc5
    
              ;Recover  MOD term (scaled 0 - 124) which stays in ALo
        clrf    AHi
        bcf     STATUS, C
        rlf     ALo             ;Scale to 0 - 248
        movlw   d'25'
        call    DivMod          ;Mod out in A, Div out in B
        movf    BLo, w
        addlw   "0"
        movwf   Loc7	;Result in LongD, LongMHi, LongMLo , NEGLONG
    
    
                ;'''''''''''''''''''Now DO LAT term , LatD is already in range 0 - 90''''''''''''''''''
        btfss   NEGLAT
        goto    PosLat
        comf    LatD
        incf    LatD            ;LatD now in 2's complement +/-90
    
        movf    LatMLo, w       ;Normalise LatM = 6000 - LatM
        sublw   LOW(d'6000')
        movwf   LatMLo   
        btfss   STATUS, C       ;if borrow, C = 0, so increment the subtrahend 
        incf    LatMHi
        movf    LatMHi, w
        sublw   HIGH(d'6000')
        movwf   LatMHi
    
        decf    LatD            ;Correct the degrees
    
    PosLat
        movlw   d'90'
        addwf   LatD            ;Normalise to 0-180
        movf    LatD, w
        movwf   ALo
        clrf    AHi
    
        movlw   d'10'
        call    DivMod          ;Mod out in A, Div out in B
        movf    BLo, W
        addlw   "A"
        movwf   Loc2
        movf    ALo, w
        addlw   "0"
        movwf   Loc4
    
        bcf     STATUS, C
        rrf     LatMHi          ;Divide by 2 to give range 0 - 2999
        rrf     LatMLo
    
        movf    LatMLo, w       ;Mins * 100 / 2  DIV 125
        movwf   ALo
        movf    LatMHi, w
        movwf   AHi
        movlw   d'125'
        call    DivMod          ;Mod out in A, Div out in B
        movf    BLo, w
        addlw   "A"
        movwf   Loc6		
    
              ;Recover  MOD term (scaled 0 - 124) which stays in ALo
        clrf    AHi
        bcf     STATUS, C
        rlf     ALo             ;Scale to 0 - 248
        movlw   d'25'
        call    DivMod
        movf    BLo, w
        addlw   "0"
        movwf   Loc8	;Result in LatD, LatMHi, LatMLo , NEGLAT
    
    
    ShowLoc
        movf    Loc1, W
        call    LcdData
        movf    Loc2, W
        call    LcdData
        movf    Loc3, W
        call    LcdData
        movf    Loc4, W
        call    LcdData
        movf    Loc5, W
        call    LcdData
        movf    Loc6, W
        call    LcdData
        movf    Loc7, W
        call    LcdData
        movf    Loc8, W
        call    LcdData
      
    
        return
    Rob.

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

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

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

    I have made a separate switchable sub for the Big Digit clock which just uses the h, m, s, part of the gps string called alone.

    Pic of result. As near accurate to second as code allows.

    Name:  bigdigit.jpg
Views: 2853
Size:  49.3 KB
    Last edited by tasmod; - 15th April 2014 at 21:15.
    Rob.

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

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

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

    Darrel,

    I found this regarding the 4th pair.

    THIRD PAIR (aa-xx)
    Each field can be further divided into (24) 5 minutes (0.083333 degrees) longitudinal
    by (24) 2.5 minute (0.0416665 degrees) latitudinal zones.

    The first character encodes the longitude and the second encodes the latitude with
    letters “a” thru “x” (refer to example 3 below).

    Example 3:
    Longitude = 0.338038 {Refer to example 2}
    = 0.338038 / 0.083333
    = 4 remainder 0.004706
    = e
    (location in 5th zone)
    Latitude = 0.664048
    = 0.664048 / 0.0416665
    = 15 remainder 0.0390505
    = p
    (location in 16th zone)

    FOURTH PAIR (00-99)
    Each field can be further subdivided into (10) 30 seconds (0.008333 degrees) longitudinal
    by (10) 15 seconds (0.004166) latitudinal zones. The first character encodes the longitude
    and the second encodes the latitude with numbers “0” thru “9” (refer to example 4 below).

    Example 4:
    Longitude = 0.004706 {Refer to example 3}
    = 0.004706 / 0.008333
    = 0 remainder 0.004706
    = 0
    (location in 1st zone)
    Latitude = 0.0390505 {Refer to example 3}
    = 0.0390505 / 0.004166
    = 9 remainder 0.001556
    = 9
    (location in 10th zone)
    Rob.

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

  40. #40
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

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

    Thanks Rob, that is helpful.
    But the routines from the pearl script don't leave the variables in the right state to do the last part.

    I'm trying to recreate it in a spreadsheet to see what values the variables should have at that point.
    But finding time to look at it is difficult right now.

    Just wanted to let you know I'm still working on it.
    DT

Similar Threads

  1. LAT replaces PORT command?
    By markscotford in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 3rd December 2011, 17:37
  2. Need Info for PBP?
    By azmax100 in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 30th January 2009, 08:44
  3. Replies: 1
    Last Post: - 27th July 2008, 07:14
  4. dmx info.
    By oscar in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 8th May 2005, 12: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