-
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.
Quote:
.
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
-
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
-
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
-
Re: How do I discern Maidenhead Locator from GPS lat long info.
Thanks! I'll have a look at that.
-
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! :D
Andy
-
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.
-
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.
-
Re: How do I discern Maidenhead Locator from GPS lat long info.
Quote:
Originally Posted by
Darrel Taylor
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
-
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 ...
-
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.
-
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 :rolleyes:
The routine could also decode the 8th place pair too, which is as close as Maidenhead gets.
-
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. :o
-
Re: How do I discern Maidenhead Locator from GPS lat long info.
Quote:
Originally Posted by
Darrel Taylor
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..... :biggrin:
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.
-
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:
-
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!
-
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 :biggrin:
Sorry I'm late back to the thread. One of the winter bugs has had hold of me, not the type I can rewrite :D
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.
-
Re: How do I discern Maidenhead Locator from GPS lat long info.
Quote:
Originally Posted by
tasmod
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.
-
1 Attachment(s)
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. :D
Attachment 7271
-
Re: How do I discern Maidenhead Locator from GPS lat long info.
Awesome!
Can't wait to see an IO93ok on that LCD.
-
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
-
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. :)
-
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. :o 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.
-
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 :frown:
-
1 Attachment(s)
Re: How do I discern Maidenhead Locator from GPS lat long info.
Here you go Darrel -
Attachment 7293
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
-
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. :D
-
1 Attachment(s)
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.
Attachment 7294
-
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
-
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.:rolleyes:
-
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.
Quote:
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.
Quote:
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.
-
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 :-
Quote:
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.
-
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.
-
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
-
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.:o
-
3 Attachment(s)
Re: How do I discern Maidenhead Locator from GPS lat long info.
Complete working prototype system
Attachment 7298
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.
Attachment 7299
Rear of LCD showing piggyback decoder.
Attachment 7300
-
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,
-
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?
-
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
-
1 Attachment(s)
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.
Attachment 7310
-
Re: How do I discern Maidenhead Locator from GPS lat long info.
Darrel,
I found this regarding the 4th pair.
Quote:
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)
-
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.