Don't know if THIS PDF will help - but I was using this in my early attempts to get this figured out. It describes how to discern the 7th and 8th digits
Don't know if THIS PDF will help - but I was using this in my early attempts to get this figured out. It describes how to discern the 7th and 8th digits
"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
Hi Darrel,
Many thanks for this.
I wondered about the variables. I did have a try at following the code through in the hope I could perhaps work it out.
As a test. I changed the string to 8 characters and tried adding MH(7) ="0" + AINT/10 and MH(8)="0"+ AINT/10 in Lat and Lon routines after MH4 and MH5 as a trial to see what was displayed.
I think the routine at 8 chrs is referencing the midi digit routine chrs as it displays custom chrs on the LCD in those positions.
I tried repeating MH4 and 5 but renumbered, so that should give 'IO93okok' as the 7th and 8th position but again it accessed custom chrs. A puzzle for me anyway.
Rob.
The moment after you press "Post" is the moment you actually see the typso
Hi Andy,
That's the doc I took the info post from
Regarding working satellites, I downloaded a Maidenhead Locator App for my Android phone. Gives lots of other info too.
Able to get 10 digit locator from the inbuilt gps on the phone.
Rob.
The moment after you press "Post" is the moment you actually see the typso
DT
Nope, it's 24x24.
And your 10-digit locator is IO93ok03kh.
This version is quite different from the last one.
I've tossed out the stuff that came from the pearl script and did it like the PDF mentioned above.
It has to use the 32-bit floating point routines now. 24-bits just didn't have enough resolution for the sub-squares.
While this version is more efficient, it's also harder to understand, sorry.
The output of the program looks like this ...Code:; Filename : Maidenhead_10.pbp ; Compiler : PICBASIC PRO Compiler ; Target PIC : 16F1937, but will work with most any chip ; Oscillator : ANY ; Keywords : Maidenhead, Locator, GPS, Amateure Radio ; Description : PICBASIC PRO program to convert between ; : GPS Sexagesimal to Maidenhead coordinate systems ;------------------------------------------------------------------------------- ; Must use the 32-bit Floating Point routines 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, 32-bit Floating Point",13,10,13,10] MH VAR BYTE[10] 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 Idx VAR BYTE AddChar VAR BYTE Divisor VAR BYTE[4] AARG_SAVE VAR BYTE[4] ;------------------------------------------------------------------------------- ASM MOVE?CF32 macro C, F ; put a Floating Point Constant in an FP variable MOVE?CW (C & 0xFFFF), F MOVE?CW (C >> 16), F + 2 endm MOVE?FF32 macro Fin, Fout ; Copy an FP var to another FP var MOVE?WW Fin, Fout MOVE?WW Fin + 2, Fout + 2 endm ENDASM ;------------------------------------------------------------------------------- ARRAYWRITE LonStr,["00049.77,W",0] ; 0° 47.70' ;<-- enter GPS location here ARRAYWRITE LatStr,["5325.83,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 @ MOVE?FF32 AARGB2, BARGB2 ; copy Float AARG to BARG Aint = 0 : GOSUB ItoFA ; subtract from 0 to negate GOSUB fpsub ENDIF Bint = 180 : GOSUB ItoFB ; add 180 GOSUB fpadd ;----[Have Longitude in AARG as Float]------------------------------------------ FOR Idx = 0 TO 8 STEP 2 SELECT CASE Idx CASE 0 : AddChar = "A" @ MOVE?CF32 0x83200000, _Divisor ; 20 CASE 2 : AddChar = "0" @ MOVE?CF32 0x80000000, _Divisor ; 2 CASE 4 : AddChar = "a" @ MOVE?CF32 0x7B2AAAAB, _Divisor ; 0.0833333 CASE 6 : AddChar = "0" @ MOVE?CF32 0x78088889, _Divisor ; 0.00833333 CASE 8 : AddChar = "a" @ MOVE?CF32 0x73360B61, _Divisor ; 0.000347222 END SELECT GOSUB MH_Digit NEXT Idx ;----[convert Latitude Sexagesimal to Decimal Degrees]-------------------------- Aint = 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 @ MOVE?FF32 AARGB2, BARGB2 ; copy Float AARG to BARG Aint = 0 : GOSUB ItoFA ; subtract from 0 to negate GOSUB fpsub ENDIF Bint = 90 : GOSUB ItoFB ; add 90 GOSUB fpadd ;----[Have Latitude in AARG as Float]------------------------------------------ FOR Idx = 1 TO 9 STEP 2 SELECT CASE Idx CASE 1 : AddChar = "A" @ MOVE?CF32 0x82200000, _Divisor ; 10 CASE 3 : AddChar = "0" @ MOVE?CF32 0x7F000000, _Divisor ; 1 CASE 5 : AddChar = "a" @ MOVE?CF32 0x7A2AAAAB, _Divisor ; 0.0416666 CASE 7 : AddChar = "0" @ MOVE?CF32 0x770882F1, _Divisor ; 0.00416666 CASE 9 : AddChar = "a" @ MOVE?CF32 0x723603EC, _Divisor ; 0.000173583 END SELECT GOSUB MH_Digit NEXT Idx ;----[Maidenhead conversion complete]------------------------------------------- HSEROUT ["LOC ",STR MH\10,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 ;----[Calculate one digit of the Maidenhead Locator]---------------------------- MH_Digit: @ MOVE?FF32 _Divisor, BARGB2 ; put divisor in BARG GOSUB fpdiv ; do the divide @ MOVE?FF32 AARGB2, _AARG_SAVE ; save AARG for modulus GOSUB FtoIA ; get integer MH(Idx) = Aint + AddChar ; The Character Bint = Aint ; copy integer result to BARG GOSUB ItoFB ; convert it to float @ MOVE?FF32 _AARG_SAVE, AARGB2 ; restore previous AARG GOSUB fpsub ; subtract integer @ MOVE?FF32 _Divisor, BARGB2 ; multiply times original divisor GOSUB fpmul ; AARG now contains the remainder RETURN
BTW: Those are really small squares (in red).Code:Maidenhead Locator 16F1937, 32-bit Floating Point LonStr = 00049.77,W LatStr = 5325.83,N LOC IO93ok03kh
Last edited by Darrel Taylor; - 20th April 2014 at 08:05.
DT
Wow, wow and WOW. What can I say? That is your usual brilliant stuff.
I use DT_Ints, Big Digits, ADC Average and now your Locator code.
Many many thanks. I tried but just can't follow it through as you expected
I never realised just how small the final location square was. That's half my plot. Reason is, the gps antenna is on the window ledge on a back room!
If I move to front room it would change !! Stunning.
Now I need to re-organise the screen layout. I didn't think I would run out of room on a 20x4 display.
I will post a picture of the completed item, it's boxed but not quite complete.
Once again, many thanks.
Rob.
The moment after you press "Post" is the moment you actually see the typso
Hmmm, I've transferred the code over into my program but I must have done something wrong as the locator is incorrect.
I'm getting 10 and kd instead of 03 and kh which is correct at back of house. kg at front of house
I will check it over again.
Here's a screenshot of the Android app.
Last edited by tasmod; - 20th April 2014 at 14:17. Reason: add pic
Rob.
The moment after you press "Post" is the moment you actually see the typso
These are some of the results I get ...
Since the main difference is the decimal portion of the Minutes, you might want to look at the values in the LonMinDec and LatMinDec variables.Code:LAT LON Maidenhead Deg Min.Min Deg Min.Min 1234567890 ------------ ------------ ---------- 53° 25.83' -0° 49.77' IO93ok03kh Back Yard 53° 25.82' -0° 49.77' IO93ok03kg Front Yard 53° 25.04' -0° 49.29' IO93ok10kd Wrong Place
They should come from the latsecs and lonsecs variables you parsed from the GPS.
Although, it's not seconds ... it's the decimal portion of the Minutes.
DT
That was it Darrel. I had aliased the wrong variables to save renaming.
Gives correct code at 'back yard' 90% of time. Why 90% ? Well, it faces North and the number of satellites it will lock to for a precise fix varies quite a lot. This is due to antenna position and satellite positions. If I lift antenna slightly, it will improve.
The gps gives a slightly changing fix as it recalculates. According to manual it outputs a 'Fix' in sentence when it has aquired 4 satellites
At the South facing 'front yard' it is 100%, as it will fix 12 satellites, the limit of this gps module.
I'm going to try inputting an initialisation string at start up. This will turn off all sentences except the RMC sentence. This should stop the occasional random catchup 'seconds' jump as another sentence is output. There are four other defaults, GGA , GSV , GSA and ZCH. The latter is the unit channel status.
It appears that they are output randomly according to PC gps serial monitoring program, whilst RMC is per second.
Last edited by tasmod; - 21st April 2014 at 11:34.
Rob.
The moment after you press "Post" is the moment you actually see the typso
Does your GPS module put out more decimal places in the LAT/LON fields?
Since the edge of the square runs through the middle of the house, whether you're at the front window or rear window inside, you're always near the edge.
I imagine that if you were standing in the middle of your back yard, the reading would be more consistent.
One or two more decimals may improve the resolution considerably.
With only two decimals, a difference of .01 is a whole square.
It depends on whether your GPS gives enough data or not.Code:LAT LON Maidenhead Deg Min.Min Deg Min.Min 1234567890 ------------ ------------ ---------- 53° 25.83' -0° 49.77' IO93ok03kh Back Yard 53° 25.82' -0° 49.77' IO93ok03kg Front Yard
When recording NMEA sentences from my Android, it gives 6 decimals.
DT
Again you come to my aid Darrel.
I had limited the output by declaring the lat/lon secs as byte. Changed them to word and it becomes much more stable now. Datasheet says the decimal part is of variable length not fixed, so word should cover it.
I have also improved the start time to fix by finally fitting the Supercap to the gps module, something I should have done a while ago. This gives 48hr backup.
Don't groan but I now have another problem I'm going to look at. The time is now 2 seconds slow. Probably all the code plus the NMEA being slow too.
I'm looking at adding 2 secs then trigger display using DT_Ints on the next PPS pulse rise time. Feasible ??
Rob.
The moment after you press "Post" is the moment you actually see the typso
Hmmm no. I screwed that up somehow.
I realised it was saving DEC2 in the gps string so it would not be any different, so I changed it to DEC4 for now.
I changed the DEC2 in display line to DEC4 and I was getting 4 decimal places on Latitude displayed but Long went to all 0's. So locator was IO84 something.
Will spend some time on it.
Rob.
The moment after you press "Post" is the moment you actually see the typso
Now this is interesting.
If I mess with the size of any 'secs' variables it screws everything up. I can get Lat to 4 decimal places but not Long, it still goes to zero.
Right now I put the code back to original and got IO93ok03kg as the locator. I'm going to reduce this to the 4 pair for display just now, only to get more on screen.
I put my phone with the app running next to the gps antenna.
The phone was showing a fix to 16 sats and gave IO93ok03lh with 53 25.8266 and 0 49.7704 as the co-ordinates.
For mine. When I had the 4 decimal places shown on the display it showed 25.8246
Rob.
The moment after you press "Post" is the moment you actually see the typso
It's between DEC4 in gps string and Aint in locator code.
I can get the display right but not the locator using DEC4 in the gps string and DIGs in the display LCDOUT.
I can get the locator right but not the position display if I just use latsecs as the variable in the gps input string.
Not knowing how Aint works I'm stumped now.
EDIT:
Just walked the property with the phone. Wow, those squares are small. I get LG, LH, KG, KH and guess where the crossover is, yes, right around the room where the unit is. I think I'll stick to DEC2 for now
Last edited by tasmod; - 22nd April 2014 at 15:58.
Rob.
The moment after you press "Post" is the moment you actually see the typso
With DEC4 change it to this for the Longitude ...And do the same thing with the Latitude.Code:;----[convert Longitude Sexagesimal to Decimal Degrees]------------------------- Aint = LonMinDec : GOSUB ItoFA ; decimal portion of Minutes Bint = 10000 : GOSUB ItoFB ; divided by 10000 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 @ MOVE?FF32 AARGB2, BARGB2 ; copy Float AARG to BARG Aint = 0 : GOSUB ItoFA ; subtract from 0 to negate GOSUB fpsub ENDIF Bint = 180 : GOSUB ItoFB ; add 180 GOSUB fpadd
DT
That was it.
Using "DEC4 latsecs/lonsecs" in the gps string and changing to Word size variables uses the 4 decimal places.
Interestingly using battery power for the unit, I got exactly the same reading as the phone app moving the unit around.
Thanks Darrel.
I'm now looking at making the time display more accurate to the second epoch using DT_Ints
Rob.
The moment after you press "Post" is the moment you actually see the typso
Yahooo!
If you are going to add interrupts, you'll need to make some changes.I'm now looking at making the time display more accurate to the second epoch using DT_Ints
SERIN2's baudrate is software timed, and it doesn't like being interrupted.
You'll have to move the serial lines over to RC6 and RC7 (the USART pins).
Then use HSERIN instead of SERIN2.
HSERIN is not affected by the interrupts.
Last edited by Darrel Taylor; - 22nd April 2014 at 23:08.
DT
Hmm, guess which pins are not catered for on pcb ?
Redesign methinks.
Rob.
The moment after you press "Post" is the moment you actually see the typso
Redesign completed. New board made where all pins are accessible and pads for option of pullups/down resistors.
I have altered the software to use HSERIN and HSEROUT and all is well at the moment. It is working just fine.
Using the code in previous post:
My aim was to display the clock triggered by the gps pps signal. I tried DT_Ints and added the @ INT_RETURN where the original Clock sub had RETURN. This caused the display to only update the very first square with random characters per second with PPS signal.
This is the setup naming Clock. I wasn't sure where to put the INT_Enable . I tried just after this ASM and at beginning of Clock routine with same result.
Code:;-------------------------------------------------------------------------- ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler INT_INT, _Clock, PBP, yes endm INT_CREATE ; Creates the interrupt processor ENDASM ;-------------------------------------------------------------------------- @ INT_ENABLE INT_INT ; enable external (INT) interrupts
Rob.
The moment after you press "Post" is the moment you actually see the typso
This is the full code with the Ints active but it's just updating first character.
Code:; ; GPS NMEA Display code with GPSDO monitoring ; ; PIC16F876A ; __________ ; !MCLR |1 28| RB7------D7 ; PLL Volt--AN0---RA0 |2 27| RB6------D6 ; adc spare--AN1---RA1 |3 26| RB5------D5 ; adc spare--AN2---RA2 |4 25| RB4------D4 ; adc spare--AN3---RA3 |5 24| RB3------LCD E ; spare---RA4 |6 23| RB2------LCD RS ; adc spare--AN4---RA5 |7 22| RB1------spare ; Ground---Vss |8 21| RB0------PPS In ; OSC1---XTAL |9 20| VDD------ +5 V ; OSC2---XTAL |10 19| Vss------Ground ; spare---RC0 |11 18| RC7------H-RX -- GPS NMEA In ; spare---RC1 |12 17| RC6------H-TX -- GPS Command Out ; spare---RC2 |13 16| RC5------spare ; Pbutton---RC3 |14 15| RC4------spare ; ---------- ;=====================================================================' ' Program to display returned value of a GPS NMEA string on RA4 ' LCD in 4-BIT mode PIC16F876a controller 4Mhz clock Fuse PWRT BODEN ' 'Typical GPS sentence string: $GPRMC,192144.62,A,5041.6058,N,00412.6124,E,0.45,3 57.74,081205,,*0B 'The default sentences are continuously output. 'Now suppose I want to read only one particular sentence I need to program the GPS to do that. 'The input message ILOG controls which sentences are logged. '$PRWIILOG,???,V,,,\r,\n 'Inputting this sentence, disables all the sentences. 'Now suppose we want only RMC sentence then input the following sentence serially to gps '$PRWIILOG,RMC,A,,,,\r\n 'The \r() and \n ( ) are sentence terminator in NMEA 'V disables that particular sentence while A enables that sentence. @ __config _HS_OSC & _WDT_ON & _PWRTE_ON & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _WRT_OFF & _DEBUG_OFF & _CP_OFF ; Place a copy of these variables in your Main program for digit characters-- ;-- The compiler will tell you which lines to un-comment -- ;-- Do Not un-comment these lines -- ;--------------------------------------------------------------------------- ;wsave VAR BYTE $20 SYSTEM ' location for W if in bank0 wsave VAR BYTE $70 SYSTEM ' alternate save location for W ' if using $70, comment wsave1-3 ' --- IF any of these three lines cause an error ?? ------------------------ ' Comment them out to fix the problem ---- ' -- Which variables are needed, depends on the Chip you are using -- 'wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1 'wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2 ;wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3 ' -------------------------------------------------------------------------- ; Must use the 32-bit Floating Point routines INCLUDE "FP2032.bas" ; 32-bit Floating Point for 14-bit cores with RAM at $20 INCLUDE "Average.bas" ; DT's 16-bit Analog Module averaging values INCLUDE "DT_INTS-14.bas" ; Base Interrupt System INCLUDE "ReEnterPBP.bas" Define LCD_DREG PORTB ' Port for LCD Data Define LCD_DBIT 4 ' Set LCD starting data bit Define LCD_RSREG PORTB ' Port for RegisterSelect (RS) bit Define LCD_RSBIT 2 ' Port Pin for RS bit (pin9) Define LCD_EREG PORTB ' Port for Enable (E) bit Define LCD_EBIT 3 ' Port Pin for E bit (pin7) Define LCB_BITS 4 ' Using 4-bit bus Define LCD_COMMANDUS 1500 ' Command Delay (uS) define LCD_DATAUS 50 ' Data Delay (uS) DEFINE OSC 4 DEFINE ADC_BITS 10 ' Setup ADC DEFINE ADC_SAMPLEUS 5 DEFINE ADC_CLOCK 1 DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0 DEFINE HSER_BAUD 4800 DEFINE HSER_CLROERR 1 ' Clear overflow automatically OPTION_REG.6 = 1 ' Interrupt rising edge OPTION_REG.7 = 0 ' Enable Pull-Up's PPS VAR PORTB.0 Pbutton VAR PORTC.3 ' Initialise ADC ADCON1 = %10000100 ' Set PORTA analog and RIGHT justify result ADCON0 = %01000001 ' Configure and turn on A/D Module channel 0 Fosc 8 'Declare variables volt VAR WORD ' scaled value real part voltd1 VAR WORD ' scaled value first decimal place voltd2 VAR WORD ' scaled value second decimal place 'Allocate Variables for GPS: #################### TimeOut CON 2000 hh VAR BYTE 'hours mm VAR BYTE 'minutes ss VAR BYTE 'seconds knots VAR WORD 'speed in knots (units) knotsten VAR BYTE 'speed in knots (tens) course VAR WORD 'heading latdeg VAR BYTE 'degrees latitude latmin VAR BYTE 'minutes latitude latsecs VAR WORD 'seconds latitude NS VAR BYTE 'north or south londeg VAR BYTE 'degrees longitude lonmin VAR BYTE 'minutes longitude lonsecs VAR WORD 'seconds longtitude EW VAR BYTE 'east or west d VAR BYTE 'day m VAR BYTE 'month y VAR BYTE 'year ;################################################### butt VAR BYTE 'pushbutton variable marker VAR BYTE 'toggle marker marker2 VAR BYTE 'UTC or BST MH VAR BYTE[10] 'locator variables########## ; Idx VAR BYTE ; AddChar VAR BYTE ; Divisor VAR BYTE[4] ; AARG_SAVE VAR BYTE[4] '----------------########### nPos var byte ' digit variables nDig var byte '-------------------- Idx2 VAR BYTE ' Month variables X VAR BYTE ; Char VAR WORD '-------------------- scroll VAR BYTE fix VAR BYTE 'GPS fix - Yes="A" No="V" butt = 0 ;clear button variable marker = 0 ;set marker to zero for full info display at start marker2 = 0 ;set UTC PAUSE 50 ;-------------------------------------------------------------------------- ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler INT_INT, _Clock, PBP, yes endm INT_CREATE ; Creates the interrupt processor ENDASM ;-------------------------------------------------------------------------- @ INT_ENABLE INT_INT ; enable external (INT) interrupts LCDOut $fe,$80," GPS Decoder " ; scrolling opening display LCDOut $FE,$c0," G8VLQ March 2014 " Pause 2000 for scroll = 1 to 20 ' FOR..NEXT loop so message scrolls off the LCD to the left lcdout $fe,24 ' Scrolls display one position to the left pause 100 ' Pause 150 ms next scroll ' do loop again till max count pause 1500 ' Pause 1000ms lcdout $fe,1 ' Clears LCD ;------------------------------------------------ Initialisation: ;Leaving GPRMC as only sentence output HSEROUT ["$PRWIILOG,GGA,V,,,",13,10] PAUSE 100 HSEROUT ["$PRWIILOG,GSA,V,,,",13,10] PAUSE 100 HSEROUT ["$PRWIILOG,GSV,V,,,",13,10] PAUSE 100 HSEROUT ["$PRWIILOG,ZCH,V,,,",13,10] PAUSE 100 ;------------------------------------------------- GPS: 'read GPS ############################################################################################# HSerIn Timeout,Clock,[wait("$GPRMC"),wait(","),DEC2 hh,DEC2 mm,DEC2 ss,wait(","),fix,wait(","),DEC2 _ latdeg,DEC2 latmin,wait("."),DEC4 latsecs,wait(","),NS,wait(","),DEC3 londeg,DEC2 lonmin,wait("."),DEC4 lonsecs,_ wait(","),EW,wait(","),knots,wait("."),DEC2 knotsten,wait(","),DEC3 course,wait(","),DEC2 d,DEC2 m,DEC2 y] IF marker = 1 THEN BigClock ; keeps big clock running if value is 1 IF marker2 = 1 THEN Plusone ;-------------------------------------------------------- ; BUTTON Pbutton,0,100,0,butt,1,BigClockClear ;button press to jump to fullscreen big clock GOSUB PLL ;get the A/D value of pll control voltage GOSUB ShowMonth ;show month as letters GOSUB Locator ;maidenhead locator ;GOSUB BST GOSUB Clock ;medium digit clock goto GPS ; ########################################################################################## ;--------------------------------------------------------------- ; MAIDENHEAD CONVERSION -- Darrel Taylor ;--------------------------------------------------------------- Locator: ASM MOVE?CF32 macro C, F ; put a Floating Point Constant in an FP variable MOVE?CW (C & 0xFFFF), F MOVE?CW (C >> 16), F + 2 endm MOVE?FF32 macro Fin, Fout ; Copy an FP var to another FP var MOVE?WW Fin, Fout MOVE?WW Fin + 2, Fout + 2 endm ENDASM ;------------------------------------------------------------------------------- ;----[convert Longitude Sexagesimal to Decimal Degrees]------------------------- Aint = lonsecs : GOSUB ItoFA ; decimal portion of Minutes Bint = 10000 : GOSUB ItoFB ; divided by 100 GOSUB fpdiv Bint = LonMin : GOSUB ItoFB ; add whole portion of Minutes GOSUB fpadd Bint = 60 : GOSUB ItoFB ; divide by 60 GOSUB fpdiv Bint = LonDeg : GOSUB ItoFB ; add degrees GOSUB fpadd IF EW = "W" THEN ; if west of Prime Meridian @ MOVE?FF32 AARGB2, BARGB2 ; copy Float AARG to BARG Aint = 0 : GOSUB ItoFA ; subtract from 0 to negate GOSUB fpsub ENDIF Bint = 180 : GOSUB ItoFB ; add 180 GOSUB fpadd ;----[Have Longitude in AARG as Float]------------------------------------------ FOR Idx = 0 TO 8 STEP 2 SELECT CASE Idx CASE 0 : AddChar = "A" @ MOVE?CF32 0x83200000, _Divisor ; 20 CASE 2 : AddChar = "0" @ MOVE?CF32 0x80000000, _Divisor ; 2 CASE 4 : AddChar = "a" @ MOVE?CF32 0x7B2AAAAB, _Divisor ; 0.0833333 CASE 6 : AddChar = "0" @ MOVE?CF32 0x78088889, _Divisor ; 0.00833333 CASE 8 : AddChar = "a" @ MOVE?CF32 0x73360B61, _Divisor ; 0.000347222 END SELECT GOSUB MH_Digit NEXT Idx ;----[convert Latitude Sexagesimal to Decimal Degrees]-------------------------- Aint = latsecs : GOSUB ItoFA ; decimal portion of Minutes Bint = 10000 : GOSUB ItoFB ; divided by 100 GOSUB fpdiv Bint = LatMin : GOSUB ItoFB ; add whole portion of Minutes GOSUB fpadd Bint = 60 : GOSUB ItoFB ; divide by 60 GOSUB fpdiv Bint = LatDeg : GOSUB ItoFB ; add degrees GOSUB fpadd IF NS = "S" THEN ; if south of equator @ MOVE?FF32 AARGB2, BARGB2 ; copy Float AARG to BARG Aint = 0 : GOSUB ItoFA ; subtract from 0 to negate GOSUB fpsub ENDIF Bint = 90 : GOSUB ItoFB ; add 90 GOSUB fpadd ;----[Have Latitude in AARG as Float]------------------------------------------ FOR Idx = 1 TO 9 STEP 2 SELECT CASE Idx CASE 1 : AddChar = "A" @ MOVE?CF32 0x82200000, _Divisor ; 10 CASE 3 : AddChar = "0" @ MOVE?CF32 0x7F000000, _Divisor ; 1 CASE 5 : AddChar = "a" @ MOVE?CF32 0x7A2AAAAB, _Divisor ; 0.0416666 CASE 7 : AddChar = "0" @ MOVE?CF32 0x770882F1, _Divisor ; 0.00416666 CASE 9 : AddChar = "a" @ MOVE?CF32 0x723603EC, _Divisor ; 0.000173583 END SELECT GOSUB MH_Digit NEXT Idx ;----[Maidenhead conversion complete]------------------------------------------- RETURN ;----[Calculate one digit of the Maidenhead Locator]---------------------------- MH_Digit: @ MOVE?FF32 _Divisor, BARGB2 ; put divisor in BARG GOSUB fpdiv ; do the divide @ MOVE?FF32 AARGB2, _AARG_SAVE ; save AARG for modulus GOSUB FtoIA ; get integer MH(Idx) = Aint + AddChar ; The Character Bint = Aint ; copy integer result to BARG GOSUB ItoFB ; convert it to float @ MOVE?FF32 _AARG_SAVE, AARGB2 ; restore previous AARG GOSUB fpsub ; subtract integer @ MOVE?FF32 _Divisor, BARGB2 ; multiply times original divisor GOSUB fpmul ; AARG now contains the remainder RETURN ;--------------------------------------------------------------------------- ; Month routine ShowMonth: LCDOut $fe,$80+9,DEC2 d," " GOSUB Month LCDOut " ","20",DEC2 y RETURN Month: Idx2 = (m - 1) * 3 FOR X = Idx2 TO Idx2 + 2 LOOKUP X,["JanFebMarAprMayJunJulAugSepOctNovDec"],Char LCDOUT Char NEXT X RETURN ;-------------------------------------------------------------------------- ; British Summer Time ;-------------------------------------------------------------------------- BST: IF m = 3 AND d = 30 THEN Plusone IF m >= 03 and m <= 10 THEN Plusone RETURN Plusone: IF m = 10 and d = 26 then UTC IF m >=10 and m <3 then UTC hh = hh + 1 IF hh = 25 THEN hh = 0 marker2 = 1 RETURN UTC: marker2 = 0 RETURN ;-------------------------------------------------------------------------- ; PLL control voltage read result via Average routine ;-------------------------------------------------------------------------- PLL: ' Measure GPSDO PLL control voltage for TCXO - Approx 1.65v for lock ADCON0.2 = 1 ' Start conversion NotDone: pause 1 IF ADCON0.2 = 1 Then NotDone value =((ADRESH * 256)+(ADRESL)) gosub Average ' Calculate Voltage to 2 decimal places volt = value * 5/1024 voltd1 = ( value * 5//1024) * 10/1024 voltd2 = ((value *5 //1024) * 10//1024) * 10/1024 RETURN ;-------------------------------------------------------------------------- lock: IF (volt=1) AND (voltd1 =6) AND (voltd2 =<9) THEN LCDOUT $FE,$C0+9,"Lock " ENDIF RETURN ;--------------------------------------------------------------------------- ClockClear: ;Returning from Big Digit Clock, need to clear screen LCDOut $FE, 1 ;Clear Screen marker = 0 ;set marker to full info display GOTO GPS ;-------------------------------------------------------------------------- Clock: ;Display medium character time clock 'Set up the digits (http://www.darreltaylor.com/files/CustChar.htm) LCDOUT $FE,$40,$03,$03,$03,$03,$03,$03,$03,$03 ' Cust Char #0 LCDOUT $FE,$48,$0E,$1F,$1B,$1B,$1B,$1B,$1B,$1B ' Cust Char #1 LCDOUT $FE,$50,$1F,$1F,$18,$18,$18,$18,$1F,$1F ' Cust Char #2 LCDOUT $FE,$58,$03,$03,$03,$03,$03,$03,$1F,$1F ' Cust Char #3 LCDOUT $FE,$60,$0E,$1F,$1B,$1B,$1B,$1B,$1F,$0E ' Cust Char #4 LCDOUT $FE,$68,$1B,$1B,$1B,$1B,$1B,$1B,$1F,$0E ' Cust Char #5 LCDOUT $FE,$70,$1F,$1F,$03,$03,$03,$03,$1F,$1F ' Cust Char #6 LCDOUT $FE,$78,$1E,$1F,$03,$03,$03,$03,$03,$03 ' Cust Char #7 nDig=ss dig 0 : nPos=7 : gosub displaydigit nDig=ss dig 1 : nPos=6 : gosub displaydigit npos=5 : gosub colon ndig=mm dig 0 : npos=4 : gosub displaydigit ndig=mm dig 1 : npos=3 : gosub displaydigit npos=2 : gosub colon ndig=hh dig 0 : npos=1 : gosub displaydigit ndig=hh dig 1 : npos=0 : gosub displaydigit LCDOUT $FE,$C0+9,"False Data " ;displays IF fix = "A" THEN LCDOUT $FE,$C0+9,"Fix ",#volt, ".", # voltd1,# voltd2,"v" ;overwrites No Data GOSUB lock ;checks for pll lock if Fix valid ENDIF LCDOUT $fe,$94," G8VLQ ",STR MH\10," " ;STR is 10 digit Maidenhead Locator LCDOut $fe,$d4,DEC2 latdeg,$DF,DEC2 latmin,"'",DEC latsecs DIG 3,DEC latsecs DIG 2,_ NS," ",DEC2 londeg,$DF,DEC2 lonmin,"'",DEC lonsecs DIG 3,DEC lonsecs DIG 2,EW ;$DF is degree symbol, some LCD displays have it in different location @ INT_RETURN ;RETURN displaydigit: if ndig=0 then gosub zero if ndig=1 then gosub one if ndig=2 then gosub two if ndig=3 then gosub three if ndig=4 then gosub four if ndig=5 then gosub five if ndig=6 then gosub six if ndig=7 then gosub seven if ndig=8 then gosub eight if ndig=9 then gosub nine return Zero: LCDOUT $FE,$80+nPos,1 LCDOUT $FE,$C0+nPos,5 return One: LCDOUT $FE,$80+nPos,0 LCDOUT $FE,$C0+nPos,0 return Two: LCDOUT $FE,$80+nPos,7 LCDOUT $FE,$C0+nPos,2 return Three: LCDOUT $FE,$80+nPos,6 LCDOUT $FE,$C0+nPos,3 return Four: LCDOUT $FE,$80+nPos,5 LCDOUT $FE,$C0+nPos,0 return Five: LCDOUT $FE,$80+nPos,2 LCDOUT $FE,$C0+nPos,3 return Six: LCDOUT $FE,$80+nPos,2 LCDOUT $FE,$C0+nPos,5 return Seven: LCDOUT $FE,$80+nPos,7 LCDOUT $FE,$C0+nPos,0 return Eight: LCDOUT $FE,$80+nPos,4 LCDOUT $FE,$C0+nPos,5 return Nine: LCDOUT $FE,$80+nPos,4 LCDOUT $FE,$C0+nPos,3 return colon: lcdout $fe,$80+nPos,$A5 lcdout $FE,$C0+nPos,$A5 return ;--------------------------------------------------------------------------- BigClockClear: LCDOut $FE, 1 ;Clear original full data screen marker = 1 ;set marker for fullscreen clock loop 'Set up the digits (http://www.darreltaylor.com/files/CustChar.htm) 'THICK DIGITS LCDOUT $FE,$40,$07,$07,$07,$07,$07,$07,$07,$07 ' Cust Char #0 LCDOUT $FE,$48,$1C,$1C,$1C,$1C,$1C,$1C,$1C,$1C ' Cust Char #1 LCDOUT $FE,$50,$0F,$1F,$1F,$1E,$1C,$1C,$1C,$1C ' Cust Char #2 LCDOUT $FE,$58,$1E,$1F,$1F,$0F,$07,$07,$07,$07 ' Cust Char #3 LCDOUT $FE,$60,$1C,$1C,$1C,$1C,$1E,$1F,$1F,$0F ' Cust Char #4 LCDOUT $FE,$68,$07,$07,$07,$07,$0F,$1F,$1F,$1E ' Cust Char #5 LCDOUT $FE,$70,$1F,$1F,$1F,$00,$00,$00,$00,$00 ' Cust Char #6 LCDOUT $FE,$78,$00,$00,$00,$00,$00,$1F,$1F,$1F ' Cust Char #7 ;############################################################################################# GPS2: HSerIn Timeout,Clock,[wait("$GPRMC"),wait(","),DEC2 hh,DEC2 mm,DEC2 ss] ;############################################################################################## BUTTON Pbutton,0,100,0,butt,1,ClockClear ;button press to change back to full info display BigClock: ;Display Big Digit fullscreen clock nDig=ss dig 0 : nPos=17 : gosub displaydigit1 nDig=ss dig 1 : nPos=14 : gosub displaydigit1 npos=13 : gosub colon ndig=mm dig 0 : npos=10 : gosub displaydigit1 ndig=mm dig 1 : npos=7 : gosub displaydigit1 npos=6 : gosub colon1 ndig=hh dig 0 : npos=3 : gosub displaydigit1 ndig=hh dig 1 : npos=0 : gosub displaydigit1 GOTO GPS2 displaydigit1: if ndig=0 then gosub Zero1 if ndig=1 then gosub One1 if ndig=2 then gosub Two1 if ndig=3 then gosub Three1 if ndig=4 then gosub Four1 if ndig=5 then gosub Five1 if ndig=6 then gosub Six1 if ndig=7 then gosub Seven1 if ndig=8 then gosub Eight1 if ndig=9 then gosub Nine1 return Zero1: LCDOUT $FE,$80+nPos,2 LCDOUT $FE,$81+nPos,3 ;note added 1 to position for right side of character LCDOUT $FE,$C0+nPos,1 LCDOUT $FE,$C1+nPos,0 ;note added 1 LCDOUT $FE,$94+nPos,1 LCDOUT $FE,$95+nPos,0 ;note added 1 LCDOUT $FE,$D4+nPos,4 LCDOUT $FE,$D5+nPos,5 ;note added 1 return One1: LCDOUT $FE,$80+nPos," " LCDOUT $FE,$81+nPos,0 LCDOUT $FE,$C0+nPos," " LCDOUT $FE,$C1+nPos,0 LCDOUT $FE,$94+nPos," " LCDOUT $FE,$95+nPos,0 LCDOUT $FE,$D4+nPos," " LCDOUT $FE,$D5+nPos,0 return Two1: LCDOUT $FE,$80+nPos,6 LCDOUT $FE,$81+nPos,3 LCDOUT $FE,$C0+nPos,7 LCDOUT $FE,$C1+nPos,5 LCDOUT $FE,$94+nPos,1 LCDOUT $FE,$95+nPos," " LCDOUT $FE,$D4+nPos,4 LCDOUT $FE,$D5+nPos,7 return Three1: LCDOUT $FE,$80+nPos,6 LCDOUT $FE,$81+nPos,3 LCDOUT $FE,$C0+nPos,7 LCDOUT $FE,$C1+nPos,5 LCDOUT $FE,$94+nPos," " LCDOUT $FE,$95+nPos,3 LCDOUT $FE,$D4+nPos,7 LCDOUT $FE,$D5+nPos,5 return Four1: LCDOUT $FE,$80+nPos,1 LCDOUT $FE,$81+nPos," " LCDOUT $FE,$C0+nPos,4 LCDOUT $FE,$C1+nPos,7 LCDOUT $FE,$94+nPos," " LCDOUT $FE,$95+nPos,1 LCDOUT $FE,$D4+nPos," " LCDOUT $FE,$D5+nPos,1 return Five1: LCDOUT $FE,$80+nPos,2 LCDOUT $FE,$81+nPos,6 LCDOUT $FE,$C0+nPos,1 LCDOUT $FE,$C1+nPos," " LCDOUT $FE,$94+nPos,6 LCDOUT $FE,$95+nPos,3 LCDOUT $FE,$D4+nPos,7 LCDOUT $FE,$D5+nPos,5 return Six1: LCDOUT $FE,$80+nPos,2 LCDOUT $FE,$81+nPos,6 LCDOUT $FE,$C0+nPos,1 LCDOUT $FE,$C1+nPos," " LCDOUT $FE,$94+nPos,2 LCDOUT $FE,$95+nPos,3 LCDOUT $FE,$D4+nPos,4 LCDOUT $FE,$D5+nPos,5 return Seven1: LCDOUT $FE,$80+nPos,6 LCDOUT $FE,$81+nPos,3 LCDOUT $FE,$C0+nPos," " LCDOUT $FE,$C1+nPos,0 LCDOUT $FE,$94+nPos," " LCDOUT $FE,$95+nPos,0 LCDOUT $FE,$D4+nPos," " LCDOUT $FE,$D5+nPos,0 return Eight1: LCDOUT $FE,$80+nPos,2 LCDOUT $FE,$81+nPos,3 LCDOUT $FE,$C0+nPos,4 LCDOUT $FE,$C1+nPos,5 LCDOUT $FE,$94+nPos,2 LCDOUT $FE,$95+nPos,3 LCDOUT $FE,$D4+nPos,4 LCDOUT $FE,$D5+nPos,5 return Nine1: LCDOUT $FE,$80+nPos,2 LCDOUT $FE,$81+nPos,3 LCDOUT $FE,$C0+nPos,4 LCDOUT $FE,$C1+nPos,5 LCDOUT $FE,$94+nPos," " LCDOUT $FE,$95+nPos,0 LCDOUT $FE,$D4+nPos,7 LCDOUT $FE,$D5+nPos,5 return colon1: lcdout $fe,$C0+nPos,$A5 lcdout $FE,$94+nPos,$A5 return
Last edited by tasmod; - 28th April 2014 at 13:07.
Rob.
The moment after you press "Post" is the moment you actually see the typso
Hi Darrel,
Hmmm, looking at the various timings I don't see how this can be done.
The NMEA string is output at the same point, the epoch of the PPS pulse, so the code is executing the string read when it also needs to start to display the 'advanced' time.
As I see it at the moment, the code reads the gps string, then parses it, saving each piece to the assigned variable and runs the subroutines before initiating the display.
As a test, I added two seconds to the seconds variable. Then comparing against a radio time signal it was almost the same. I say almost as it is not quite two seconds out in code execution.
I suppose I could add a suitable pause value and bring it inline but I would have to test the offset, if any, over a period of operation. This assumes code execution always takes the same time to execute.
Any ideas would be welcome.
Rob.
The moment after you press "Post" is the moment you actually see the typso
Hi Rob,
I haven't been following this thread in detail so I apolgize if I'm suggesting something that's already been covered or isn't doable for whatever reason.
Looking at the code you posted, and as you mentioned, you spend quite a bit of time in the ISR. I have two questions/suggestions.
A) Why do you need to reload the custom characters each time? Wouldn't it be better to load them once at startup?
B) Can't you simply set a flag in the ISR (ie UpdateDisplay = 1) which you then poll in the main loop? If the flag is set you update the display and reset the flag.
Obviously there must be enough clock cycles between interrupts to do whatever needs to be done - no matter "where" it's being done (inside or out of the ISR).
Doing (B) above you basically can't have the HSERIN statement within the main loop as it will "block" the processor for up to TimeOut ms (2000 in the code as posted). What you'd need to do is either introduce UART interrupt or simply poll the UART RX interrupt flag within the mainloop (provided the mainloop is "tight" enough to not overflow the UART receive buffer (2 bytes).
Yes and no. It doesn't read, then parses it. HSERIN is parsing the string as the bytes comes in, one by one. If it didn't do that you'd have to have a recieve buffer as big as the complete NMEA string. But again, the code in your ISR takes considerable amount of time and it's quite possible that if an interrupt occurs in the middle of the HSERIN statment (quite possible) the ISR is stealing too much time so the the receive buffer (2 bytes) overruns and HSERIN "gets lost".As I see it at the moment, the code reads the gps string, then parses it,
At 4800 baud each byte is a about 2ms long so if your ISR takes more than 4ms to execute it will most definitely cause issues for the HSERIN. Seeing all those LCDOUT statements within the ISR and the subroutines it calls makes me think your ISR runs way up into the tens of ms.
/Henrik.
Last edited by HenrikOlsson; - 29th April 2014 at 21:00.
Hi Henrik,
Quite a bit to digest there. Good food for thought. Thanks.
I missed the fact that the custom characters for the medium digits was constantly loading in the loop. I've moved that to the beginning now out of the loop, it is loaded at start up.
The BigDigit clock did only load it's characters once then entered it's own loop, so that's taken care of.
The main problem as I see it is that the gps string start occurs at the same time as the 'seconds' rise point. In the gps module the start of the rise of the PPS also triggers the NMEA string output. In other words the seconds epoch occurs for both. I don't know if it's possible to receive the string and trigger the display code at the same time. I was just trying to get to a more accurate time.
The time is very close now anyway allowing for code run timing. I could add a small pause to bring it closer I suppose.
Rob.
The moment after you press "Post" is the moment you actually see the typso
Hi Rob,
More thoughts.....
Since, if I'm not mistaken, the time is parsed from the NMEA string using the PPS signal to initiate a display update will update the display with the time information from the last received string which is basically one second "old". I think that the best you can do really is to simply grab and parse the string and then update the display.
If you're receiving the full 82byte NMEA string that will take ~170ms, add the actual display update code to that - you'll be a couple of hundred ms off.
/Henrik.
Hi Henrik,
I've been doing some more reading regarding the NMEA string from the Rockwell datasheets. (19 pages in one 142 in other !)
I've discovered two choice bits.
(1.) The string is always after the event, so is 1 second late as you said.
(2.) Standard laid down for time this way is up to +/- .9 seconds regardless of (1.) above.
Rockwell do a binary protocol at 9600 baud which is 'message' driven. So you can actually poll for time separately with far more accuracy but it would require a complete code rewrite.
I'm trying to keep code tight in the BigClock sub which only reads the h, m, s, part of string. This is at beginning of the string anyway. I update in reverse to display, s m h.
At the moment I've added 2 seconds before display and with the other code changes, it's as near as I can see visually using the PPS LED. It is almost on the PPS event. That is near enough for me. Checking against MSF radio time signal using Spectrum Lab software, it's very close.
Visually humans can discern a 250ms difference, so as I can hardly see any difference, it should be closer than 250ms diff.
I could load the output into SpecLab to compare both signals I suppose. I may eventually do that anyway as I'm curious to what the code timing is.
I have the frequency lock part spot on, so it would be nice to get the time part as well, but I don't think its possible.
For my sins, in my other life I am an official timekeeper, timing to hundredths of a second. I can see '100ths differences there ok
Amazing really how many times a day I see exactly the same time to the hundreth of a second, two competitors achieve.
Another idea, but I suspect will gain nothing is :-
Read string full time once at start up.
Display
loop:
Then read only seconds.
Increment software clock s m h
update display
loop
String read would be very quick. Approx 20ms.
EDIT:
Just realised that at 20ms I would have read h m s anyway, so pseudo code above is pointless.
Last edited by tasmod; - 1st May 2014 at 11:58.
Rob.
The moment after you press "Post" is the moment you actually see the typso
Dear all,
first of all i would like to congrats the work have been done in this post.
I would also like to inform you once again that im not a programmer. So my knowledge at programming is really low.
I try to setup as a hobby a gps and project the info to ulcd that i have many years at my small lab.
Here is the code up to now:
What i would like to do is to display:Code:@ ERRORLEVEL -306 ; this command prevents the compiler to give you a notice of ; crossing page boundary - make sure bits are set PORTB = 0 input portb.0 ; -----[ Variables ]------- PWRLED var PORTb.1 ; this shows that the initialization is finished LCD var PORTb.2 ; to LCD operation GPS_TX var PORTb.0 ; info from GPS GPS_RX var PORTb.4 ; COMMANDS TO GPS, this feature is not Testled var PORTb.5 ;ill try to use this when GPS module find signal pause 2000 ' -----[ Variables ]------------------------------------------------------- ' $GPRMC,090045.000,A,3823.6645,N,02353.3600,E,0.02,195.80,170518,,,A*62 ' $GNGGA,140405.000,3823.6010,N,02353.3054,E,1,9,0.88,0.8,M,35.9,M,,*40 hh var byte 'hours mm var byte 'minutes ss var byte 'seconds sss var word 'milisecs degrees VAR BYTE 'latitude/longitude degrees minutes VAR BYTE 'latitude/Longitude minutes minutesD VAR word 'latitude/LONGITUDE DECIMAL MINUTES dir VAR BYTE ' direction (latitude: 0 = N, 1 = S / longitude: 0 = E, 1 = W) degrees2 VAR BYTE 'latitude/longitude degrees minutes2 VAR BYTE 'latitude/Longitude minutes minutesD2 VAR word 'latitude/LONGITUDE DECIMAL MINUTES dir2 var byte ;direction (latitude: 0 = N, 1 = S / longitude: 0 = E, 1 = W) SatNo VAR BYTE 'number of satellites connected knots var word 'speed over ground knots2 var byte 'speed over ground course var word 'course course2 var byte 'course day var byte 'day month var byte 'month year var byte 'year i var word GNRMC var word GNGGA var WORD FIX var word Modefix var byte horizon var byte precision var byte meter var byte METERS var byte Meters2 var byte ' ----------------- [ Initialization ]---------------------- serout2 LCD,32,[$55] ' uOLED Initialize pause 2000 serout2 lcd,32,[$56,$01] pause 1000 serout2 lcd,32,[$45] pause 500 serout2 lcd,32,[$55] pause 500 serout2 lcd,32,[$45] pause 500 serout2 lcd,32,[$73,$00,$03,$11,$ff,$ff," Leonardo Bilalis",$00] pause 200 serout2 lcd,32,[$73,$02,$06,$10,$ff," Copyright 2018",$00] pause 3000 serout2 lcd,32,[$45] pause 1000 serout2 lcd,32,[$73,$02,$06,$10,$ff,$ff," GPS.........",$00] pause 500 serout2 lcd,32,[$45] pause 200 HIGH pwrled '-------------------- [MAIN] ------------------------------ Main: ;$GPRMC,090045.000,A,3823.6645,N,02353.3600,E,0.02,195.80,170518,,,A*62 serin2 gps_tx,84,[wait("$GNRMC"),_ ;we wait for $GNRMC wait(","),dec2 hh,dec2 mm,dec2 ss,wait("."),dec3 sss,_ ;we wait for 090045.000 wait(","),fix,_ ;we wait for A wait(","),dec2 degrees,dec2 minutes,wait("."),dec4 minutesd,_ ;we wait for 3823.6645 wait(","),dir,_ ;we wait for N wait(","),dec3 degrees2,dec2 minutes2,wait("."),dec4 minutesd2,_;we wait for 02353.3600 wait(","),dir2,_ ;we wait for E wait(","),dec knots,wait("."),dec2 knots2,_ ;we wait for 0.02 wait(","),dec3 course,wait("."),_ ;we wait for 195.80 wait(","),dec2 day,dec2 month,dec2 year] ;we wait for 170518 pause 100 ;$GNGGA,140405.000,3823.6010,N,02353.3054,E,1,9,0.88,0.8,M,35.9,M,,*40 serin2 gps_tx,84,[wait("$GNGGA"),_ wait(","),dec2 hh,dec2 mm,dec2 ss,wait("."),dec3 sss,_ wait(","),dec2 degrees,dec2 minutes,wait("."),dec4 minutesd,_ wait(","),dir,_ wait(","),dec3 degrees2,dec2 minutes2,wait("."),dec4 minutesd2,_ wait(","),dir2,_ wait(","),modefix,_ wait(","),dec2 satno,_ wait(","),dec3 horizon,dec precision,_ wait(","),meter,dec2 METERS,dec Meters2] pause 100 serout2 lcd,32,[$73,$03,$00,$00,$ff,$ff,"Protocol:",dec5 GNRMC,$00] ; THIS IS NOT WORKING pause 200 serout2 lcd,32,[$73,$00,$02,$00,$ff,$ff,"Date:",dec2 day,dec2 month,dec2 year,$00] ; THIS IS NOT WORKING pause 200 serout2 lcd,32,[$73,$00,$04,$00,$ff,$ff,"TIME: ",dec2 hh+3," :",dec2 mm," :",dec2 ss,$00] pause 200 serout2 lcd,32,[$73,$00,$06,$00,$ff,$ff,"Satellites:",dec2 satno," ","Fixed:",fix,$00] pause 200 serout2 lcd,32,[$73,$00,$08,$00,$ff,$ff,"Lat : ",dec2 degrees,dec2 minutes,".",dec4 minutesd," ",dir,$00] pause 200 serout2 lcd,32,[$73,$00,$0A,$00,$ff,$ff,"Lon : ",dec3 degrees2,dec2 minutes2,".",dec4 minutesd2," ",dir2,$00] pause 200 serout2 lcd,32,[$73,$00,$0C,$00,$ff,$ff,"GND SPEED : ",dec knots*1852/1000,".",dec2 knots2,$00] pause 200 serout2 lcd,32,[$73,$00,$0E,$00,$ff,$ff,"Meters : ",dec2 METERS,dec Meters2,$00] ; THIS IS NOT WORKING pause 5000 serout2 lcd,32,[$45] pause 100 goto main if fix = "V" then notfix notfix: serout2 lcd,32,[$73,$00,$03,$11,$ff,$ff," Waiting for GPS",$00] pause 100 serout2 lcd,32,[$73,$02,$06,$10,$ff," Copyright 2018",$00] pause 1000 serout2 lcd,32,[$45] pause 200 goto main '-------------------- [ CLEAR ] ----------------------------- Clearlcd: serout2 lcd,32,[$45] pause 500 RETURN
Protocol : GNRMC
DATE :
TIME :
Satellites:
LAT :
LON :
GND SPEED:
METERS:
I have the following problem.
1. Cannot display the DATE. Something is wrong at my code and there is not proper display of the date.
2. I have put a loop for display all the factors, because i need to clear the LCD every time something is change. So please could you help me understand how could i manage to display the factors and only change on the fly the ones really going like Time, LAT, LON, GND SPEED, SATs etc.
3. The Protocol command is not working
4. The speed is not working properly, i think i need to do better the conversion
5. The meters are not displaying, there is a wrong value in there.
6. I need to convert the measurements from the NMEA message LAT and LON to google numbers.
Please check what i have done till now in order for me to understand what it is needed.
I have updated a little bit the code so when there is a no data at portb.0 to have a notice.
but still i need to fix the following. Is there any advise?
1. Cannot display the DATE. Something is wrong at my code and there is not proper display of the date.
2. I have put a loop for display all the factors, because i need to clear the LCD every time something is change. So please could you help me understand how could i manage to display the factors and only change on the fly the ones really going like Time, LAT, LON, GND SPEED, SATs etc.
3. The Protocol command is not working
4. The speed is not working properly, i think i need to do better the conversion
5. The meters are not displaying, there is a wrong value in there.
6. I need to convert the measurements from the NMEA message LAT and LON to google numbers.
Code:'* Author : LEONARDO BILALIS * '* Notice : Copyright (c) 2018 [LEONARDOS BILALIS] * '* : All Rights Reserved * '* Date : 12/5/2018 * '* Version : 1.0 * '* Notes : This is an GPS with ulcd * '* : * '**************************************************************** @ ERRORLEVEL -306 ; this command prevents the compiler to give you a notice of ; crossing page boundary - make sure bits are set ;& __config _HS_OSC & _WDT_ON & _LVP_OFF & _CP_OFF Include "MODEDEFS.BAS" DEFINE OSC 8 OSCCON=%01111000 '8 Mhz CMCON = 7 'turn comparators off ANSEL = 0 'All digital PORTB = 0 'make low all ports at B range input portb.0 'make input portb.0 '----------------------------------------------------------------------------/ ' [ PIC Variables ] / '--------------------------------------------------------------------------/ PWRLED var PORTb.1 ; this shows that the initialization is finished LCD var PORTb.2 ; to LCD operation GPS_TX var PORTb.0 ; info from GPS GPS_RX var PORTb.4 ; COMMANDS TO GPS Testled var PORTb.5 dots var byte dots=8 countremain var byte ; we use a countremain to check the incoming from portb.0 pause 1000 ' --------------------[ GPS Variables for NMEA sentenses ]---------------------/ ' / ' $GPRMC,090045.000,A,3823.6645,N,02353.3600,E,0.02,195.80,170518,,,A*62 / ' $GNGGA,140405.000,3823.6010,N,02353.3054,E,1,9,0.88,0.8,M,35.9,M,,*40 / ' / '-------------------------------------------------------------------------/ hh var byte 'hours mm var byte 'minutes ss var byte 'seconds sss var word 'milisecs degrees VAR BYTE 'latitude/longitude degrees minutes VAR BYTE 'latitude/Longitude minutes minutesD VAR word 'latitude/LONGITUDE DECIMAL MINUTES dir VAR BYTE ' direction (latitude: 0 = N, 1 = S / longitude: 0 = E, 1 = W) degrees2 VAR BYTE 'latitude/longitude degrees minutes2 VAR BYTE 'latitude/Longitude minutes minutesD2 VAR word 'latitude/LONGITUDE DECIMAL MINUTES dir2 var byte ;direction (latitude: 0 = N, 1 = S / longitude: 0 = E, 1 = W) SatNo VAR BYTE 'number of satellites connected knots var word 'speed over ground knots2 var byte 'speed over ground course var word 'course course2 var byte 'course day var byte 'day month var byte 'month year var byte 'year i var word GNRMC var word 'protocol GNGGA var WORD 'protocol FIX var word 'fix sat V/A Modefix var byte 'mode fix 1 or 2 or 3 depens horizon var byte precision var byte meter var byte METERS var byte Meters2 var byte ' -------------------------------------------------------------------------/ ' [ LCD Initialization ] / '------------------------------------------------------------------------/ serout2 LCD,32,[$55] ' uOLED Initialize pause 2000 serout2 lcd,32,[$56,$01] pause 1000 serout2 lcd,32,[$45] ' clear the lcd pause 500 serout2 lcd,32,[$55] pause 500 serout2 lcd,32,[$45] ' clesr the lcd pause 500 serout2 lcd,32,[$73,$00,$03,$11,$ff,$ff," Leonardo Bilalis",$00] pause 200 serout2 lcd,32,[$73,$02,$06,$10,$ff," Copyright 2018",$00] pause 3000 serout2 lcd,32,[$45] pause 1000 serout2 lcd,32,[$73,$02,$06,$10,$ff,$ff," GPS.........",$00] pause 500 serout2 lcd,32,[$45] pause 200 '----------------------------------------------------------------------/ ' [ After the lcd initialization we power the Led at PIC ] / '--------------------------------------------------------------------/ HIGH pwrled '-------------------------------------------------------------------/ ' [MAIN Program] / '-----------------------------------------------------------------/ Main: ;gosub clearlcd serin2 gps_tx,84,[countremain] ; we check what is coming from the port if countremain = 0 then lostcable ; if nothing is coming the we check the cable ;gosub clearlcd '-------------------------------------------------------------------------------/ ' / ' [ Example NMEA Sentense of GNRMC ] / ' [$GNRMC,090045.000,A,3823.6645,N,02353.3600,E,0.02,195.80,170518,,,A*62] / ' / '--------------------------------------------------------------------------/ serin2 gps_tx,84,[wait("$GNRMC"),_ ;we wait for $GNRMC wait(","),dec2 hh,dec2 mm,dec2 ss,wait("."),dec3 sss,_ ;we wait for 090045.000 wait(","),fix,_ ;we wait for A wait(","),dec2 degrees,dec2 minutes,wait("."),dec4 minutesd,_ ;we wait for 3823.6645 wait(","),dir,_ ;we wait for N wait(","),dec3 degrees2,dec2 minutes2,wait("."),dec4 minutesd2,_;we wait for 02353.3600 wait(","),dir2,_ ;we wait for E wait(","),dec knots,wait("."),dec2 knots2,_ ;we wait for 0.02 wait(","),dec3 course,wait("."),_ ;we wait for 195.80 wait(","),dec2 day,dec2 month,dec2 year] ;we wait for 170518 pause 100 '------------------------------------------------------------------------------/ ' / ' [ Example NMEA Sentense of GNGGA ] / ' [$GNGGA,140405.000,3823.6010,N,02353.3054,E,1,9,0.88,0.8,M,35.9,M,,*40 / ' / '-------------------------------------------------------------------------/ serin2 gps_tx,84,[wait("$GNGGA"),_ wait(","),dec2 hh,dec2 mm,dec2 ss,wait("."),dec3 sss,_ wait(","),dec2 degrees,dec2 minutes,wait("."),dec4 minutesd,_ wait(","),dir,_ wait(","),dec3 degrees2,dec2 minutes2,wait("."),dec4 minutesd2,_ wait(","),dir2,_ wait(","),modefix,_ wait(","),dec2 satno,_ wait(","),dec3 horizon,dec precision,_ wait(","),meter,dec2 METERS,dec Meters2] pause 100 '---------------------------------------------------------------------------------/ ' Here if the GPS module havent been fixed to any satellite will jump to notfix / '-------------------------------------------------------------------------------/ if fix = "V" then notfix pause 100 '-----------------------------------------------------------------------------/ ' [ Return from notfix ] / ' [ We clear any character on the display ] / '--------------------------------------------------------------------------/ gosub clearlcd ;serout2 lcd,32,[$45] ;pause 500 '--------------------------------------------------------------------------/ ' here is where the code dispays the stored info from the NMEA sentenses / '------------------------------------------------------------------------/ serout2 lcd,32,[$73,$03,$00,$00,$ff,$ff,"Protocol:",dec5 GNRMC,$00] pause 100 serout2 lcd,32,[$73,$00,$02,$00,$ff,$ff,"Date:",dec2 day,dec2 month,dec2 year,$00] pause 100 serout2 lcd,32,[$73,$00,$04,$00,$ff,$ff,"TIME: ",dec2 hh+3," :",dec2 mm," :",dec2 ss,$00] pause 100 serout2 lcd,32,[$73,$00,$06,$00,$ff,$ff,"Satellites:",dec2 satno," ","Fixed:",fix,$00] pause 100 serout2 lcd,32,[$73,$00,$08,$00,$ff,$ff,"Lat : ",dec2 degrees,dec2 minutes,".",dec4 minutesd," ",dir,$00] pause 100 serout2 lcd,32,[$73,$00,$0A,$00,$ff,$ff,"Lon : ",dec3 degrees2,dec2 minutes2,".",dec4 minutesd2," ",dir2,$00] pause 100 ;serout2 lcd,32,[$73,$00,$0C,$00,$ff,$ff,"GND SPEED : ",(dec knots,".",dec2 knots2)*/1.852,$00] ;pause 200 serout2 lcd,32,[$73,$00,$0E,$00,$ff,$ff,"Meters : ",dec2 METERS,dec Meters2,$00] pause 3000 serout2 lcd,32,[$45] ' clears the LCD pause 100 goto main '-----------------------------------------------------------------------------/ ' [ SUB ROUTINES ] / '---------------------------------------------------------------------------/ notfix: ' Still looking for fixed signal serout2 lcd,32,[$73,$00,$03,$11,$ff,$ff," Waiting for GPS",$00] pause 100 serout2 lcd,32,[$73,$03,$06,$10,$ff," Time:",dec2 hh+3," :",dec2 mm," :",dec2 ss,$00] pause 1000 serout2 lcd,32,[$73,$03,$08,$10,$ff,rep "."\dots,$00] pause 200 serout2 lcd,32,[$45] ' clears the LCD pause 100 goto main 'returns to main lostcable: serout2 lcd,32,[$73,$00,$03,$11,$ff,$ff," Connection lost",$00] pause 100 serout2 lcd,32,[$73,$01,$06,$10,$ff," Please check cable",$00] pause 2000 serout2 lcd,32,[$45] ' clears the LCD pause 100 goto main '---------------------------------------------------------------------------/ ' [ CLEAR LCD ] / '-------------------------------------------------------------------------/ Clearlcd: serout2 lcd,32,[$45] pause 100 RETURN
Last edited by astanapane; - 20th May 2018 at 18:38.
first off , what has your post got to do with maidenhead ? why not start a new relevant post instead of confusing this one
secondly posting figures as pictures makes life difficult for anyone inclined to assist
in you google numbers query (which is really deg ,min, sec conversion to decimal degrees )
how did you get 38 + 2/60 + 3.49/3600 = 38.034297
my calculator says 38.0343027 ps (in 32 bit float result is 38.0343018, with 64 bit float 38.0343028)done on pic24f using xc16
you will have fun trying to get math accurate to 10 significant digits on that chip [even 32 bit floats struggle]
your best bet is nbit math
the decimal portion can be :-
mins *1000000/6 + sec *1000/36
parsing the nmea sentences is well covered but you may be interested in this
http://support.melabs.com/forum/picb...strtok-usercmd
a strtok function for pbp
parsing strings with spaghetti code will always by a shortcut to madness
Last edited by richard; - 21st May 2018 at 11:13.
Warning I'm not a teacher
Hi richard,
1) i did post in here because i was planning to do that conversion as well on next step. But i cant simply display the date, so my knowledge wont be able to do any further
2) pictures i believe always help.
3) you are right on the calculation 38.0343027. I did something wrong in there.
4) if Parsing NMEA is ok then why Date is not displaying right? I will check once again what i have done on the code.
5) i will check the link and the strtok. But i find easier the way i did it because i understand it.
as i said im not a programmer. This code might be simple for you, but is too much for me. I try to do things stwp by step on this code. There are lots of bugs and mistakes which at the moment cant solve.
i found a small mistake on the first parsing code. i have forgot a sentence which may cause the problem displaying date.
Will keep you update.
i though i found the mistake on the first code for parsing
i did complete the sentenseCode:' / ' [ Example NMEA Sentense of GNRMC ] / ' [$GNRMC,090045.000,A,3823.6645,N,02353.3600,E,0.02,195.80,170518,,,A*62] / ' / '--------------------------------------------------------------------------/ serin2 gps_tx,84,[wait("$GNRMC"),_ ;we wait for $GNRMC wait(","),dec2 hh,dec2 mm,dec2 ss,wait("."),dec3 sss,_ ;we wait for 090045.000 wait(","),fix,_ ;we wait for A wait(","),dec2 degrees,dec2 minutes,wait("."),dec4 minutesd,_ ;we wait for 3823.6645 wait(","),dir,_ ;we wait for N wait(","),dec3 degrees2,dec2 minutes2,wait("."),dec4 minutesd2,_;we wait for 02353.3600 wait(","),dir2,_ ;we wait for E wait(","),dec knots,wait("."),dec2 knots2,_ ;we wait for 0.02 wait(","),dec3 course,wait("."),_ ;we wait for 195.80 wait(","),dec2 day,dec2 month,dec2 year] ;we wait for 170518 pause 100
but still next line which is the date is not dispayed right.Code:wait(","),dec3 course,wait("."),dec2 course2,_ ;we wait for 195.80
ok the date is displayed. But sometimes it looks like that missing the date code and displays 00/here a 2 digit number/00, then it comes back to the right date.
this is how I would go about parsing nmea, for what you are doing there is little point in storing all the data just to display it
only store what is needed for calculations or enhanced display.
I would also read in the entire nmea sentence using $ ast the start marker and * as the end marker.
when you have a complete sentence send it off for parsing if its the correct sentence type
Code:'**************************************************************** '* Name : NOKIA_DEMO.PBP * '* Author : richard * '* Notice : * '* : * '* Date : 16/5/2018 * '* Version : mssp1 version with bigtxt * '* Notes : * '* :FOR pic 16F1847@32MHZ NOKIA * '**************************************************************** #CONFIG ; 16FF1847. __config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _BOREN_OFF __config _CONFIG2, _PLLEN_OFF & _LVP_OFF #ENDCONFIG define OSC 32 ; --- *** Oscillator *** --------------------------------------------------- OSCCON = %11110000 ;32 MHz, ANSELb = 0 ANSELA = 0 TRISA=%10010000 TRISB=%11101011 ch var byte BUFF VAR BYTE [16] ;DEFINES FOR DISPLAY use font7x5_16.bas or font7x5_18.bas for pic18 #DEFINE PIC16 1 #define use_mssp 1 lcdheight con 5 ; 6 PAGES lcdwidth con 83 ; 84 PIXELS WIDE ' LCD_CLK var LATB.4 ' SCK1 pin needs to be set as dig o/p ' LCD_DIN var LATB.2 ' SDO1 pin needs to be set as dig o/p LCD_RST var LATA.4 LCD_DC var LATA.3 LCD_CE var LATA.6 LCD_LIGHT var LATA.0 nmea var byte[80] h var byte m var byte s var byte Include "nokia_ds.INC" ' bring it in include "font7x5_16.bas" @ #DEFINE TOKEN_DESTROY 1 include "strtok.pbpmod" '========================== MAIN Routine ============================== gosub lcd_init LCDCLR ARRAYWRITE BUFF,["READY",0] LCDSTR 5,0,BUFF PAUSE 1000 LCDCLR looper: 'start=$ end=* arraywrite nmea,["GNRMC,090045.000,A,3823.6645,N,02353.3600,E,0.02,195.80,170518,,,A",0] ;STRLEN nmea strtok nmea,0,"," LCDSTR 0,0,nmea ;sentence type strtok nmea ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),dec2 h,dec2 m,dec2 s] arraywrite buff,[dec2 h,":",dec2 m,":",dec2 s,0] LCDSTR 36,0,BUFF strtok nmea ;fix strtok nmea ;fix arraywrite buff,["lon",0] LCDSTR 0,1,BUFF ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),str buff\16] LCDSTR 20,1,buff strtok nmea ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),str buff\16] LCDSTR 77,1,buff strtok nmea arraywrite buff,["lt",0] LCDSTR 0,2,BUFF ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),str buff\16] LCDSTR 13,2,buff strtok nmea ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),str buff\16] LCDSTR 77,2,buff strtok nmea arraywrite buff,["speed",0] LCDSTR 0,3,BUFF ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),str buff\16] LCDSTR 36,3,buff strtok nmea arraywrite buff,["hdg",0] LCDSTR 0,4,BUFF ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),str buff\16] LCDSTR 36,4,buff strtok nmea ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),dec2 h,dec2 m,dec2 s] arraywrite buff,[dec2 h,"/",dec2 m,"/",dec2 s,0] LCDSTR 36,5,BUFF END
Warning I'm not a teacher
and to emphasize the advantage of an algorithmic approach over spaghetti code
Code:'**************************************************************** '* Name : NOKIA_DEMO.PBP * '* Author : richard * '* Notice : * '* : * '* Date : 16/5/2018 * '* Version : mssp1 version with bigtxt * '* Notes : * '* :FOR pic 16F1847@32MHZ NOKIA * '**************************************************************** #CONFIG ; 16FF1847. __config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _BOREN_OFF __config _CONFIG2, _PLLEN_OFF & _LVP_OFF #ENDCONFIG define OSC 32 ; --- *** Oscillator *** --------------------------------------------------- OSCCON = %11110000 ;32 MHz, ANSELb = 0 ANSELA = 0 TRISA=%10010000 TRISB=%11101011 ch var byte BUFF VAR BYTE [16] ;DEFINES FOR DISPLAY use font7x5_16.bas or font7x5_18.bas for pic18 #DEFINE PIC16 1 #define use_mssp 1 lcdheight con 5 ; 6 PAGES lcdwidth con 83 ; 84 PIXELS WIDE ' LCD_CLK var LATB.4 ' SCK1 pin needs to be set as dig o/p ' LCD_DIN var LATB.2 ' SDO1 pin needs to be set as dig o/p LCD_RST var LATA.4 LCD_DC var LATA.3 LCD_CE var LATA.6 LCD_LIGHT var LATA.0 nmea var byte[80] h var byte m var byte s var byte Include "nokia_ds.INC" ' bring it in include "font7x5_16.bas" @ #DEFINE TOKEN_DESTROY 1 include "strtok.pbpmod" '========================== MAIN Routine ============================== gosub lcd_init LCDCLR ARRAYWRITE BUFF,["READY",0] LCDSTR 5,0,BUFF PAUSE 1000 LCDCLR looper: 'start=$ end=* arraywrite nmea,["GNRMC,090045.000,A,3823.6645,N,02353.3600,E,0.02,195.80,170518,,,A",0] strtok nmea,0,"," ARRAYREAD nmea, 5, GNGGA,[wait("GNRMC")] GOSUB SH_MSG GOSUB SH_TIME strtok nmea ;fix GOSUB SH_LON GOSUB SH_LAT arraywrite buff,["speed",0] LCDSTR 0,3,BUFF ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),str buff\16] LCDSTR 36,3,buff strtok nmea arraywrite buff,["hdg",0] LCDSTR 0,4,BUFF ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),str buff\16] LCDSTR 36,4,buff strtok nmea ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),dec2 h,dec2 m,dec2 s] arraywrite buff,[dec2 h,"/",dec2 m,"/",dec2 s,0] LCDSTR 36,5,BUFF PAUSE 1000 GNGGA: arraywrite nmea,["GNGGA,140405.000,3823.6010,N,02353.3054,E,1,9,0.88,0.8,M,35.9,M,,",0] strtok nmea,0,"," ARRAYREAD nmea, 5, XXX,[wait("GNGGA")] GOSUB SH_MSG GOSUB SH_TIME GOSUB SH_LON GOSUB SH_LAT strtok nmea strtok nmea strtok nmea strtok nmea strtok nmea arraywrite buff,["M",0] LCDSTR 28,5,BUFF ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),str buff\16] LCDSTR 0,5,buff PAUSE 1000 GOTO LOOPER XXX: LCDCLR arraywrite buff,["Oops",0] LCDSTR 0,1,BUFF end SH_MSG: LCDSTR 0,0,nmea ;sentence type strtok nmea RETURN SH_TIME: ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),dec2 h,dec2 m,dec2 s] arraywrite buff,[dec2 h,":",dec2 m,":",dec2 s,0] LCDSTR 36,0,BUFF strtok nmea RETURN SH_LON: arraywrite buff,["lon",0] LCDSTR 0,1,BUFF ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),str buff\16] LCDSTR 20,1,buff strtok nmea ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),str buff\16] LCDSTR 77,1,buff strtok nmea RETURN SH_LAT: arraywrite buff,["lt",0] LCDSTR 0,2,BUFF ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),str buff\16] LCDSTR 13,2,buff strtok nmea ARRAYREAD nmea ,[SKIP (STRTOK_INX-STRTOK_LEN),str buff\16] LCDSTR 77,2,buff strtok nmea RETURN
Warning I'm not a teacher
Hi richard,
really appreciate your help. I will print out your post and code, because i need to understand it first.
Im a person that i understand something when i make notes and then i test my notes to see if i got it. Maybe this seems a bit stupid to others, but for me at the end works.
Thanks a lot once again.
Yesterday night i figured out that i need to correct TIME 24 hour, as im located on South of Europe --> Greece and we are +3 from UTC. So if it is 22:00 at UTC the time on display is +3....and shows 25.
Then i need to say also that as we are +3 from UTC, when the time at UTC is 21:00 here will be 00:00, so the code must also change the date. (at them moment DATE follows the UTC time)
Up to now i know what i have done with the code, even if it is wrong and even if there are lots of bugs. I'm happy at least i understand what i have done.
Hopefully the following days i will have good news.
Last edited by astanapane; - 22nd May 2018 at 14:06.
this is what i get up to now on the display. But is not stable.
Date is loosing data sometimes and presents zeros.
My code refresh the display in order to get newer update on time, Sats, coordinates. Because i havent found the way to have always on the data and just refresh the digits need, for example the seconds.
i keep working on it.
i'm not surprised , given that :-this is what i get up to now on the display. But is not stable.
not all nmea fields are filled in for every message
not all nmea fields are fixed length
I can't think of a more difficult way to approach this task than what you are trying to do.
I can't think of a more difficult to debug approach for this task than what you are trying to do
here is a snap of mine hooked to actual data, it has no trouble keeping up with the 4 or 5 messages
per second that the gps spits out
managed to snap the pic as the message type was updated so it a bit vague as to what its type is/was
and the lat/lon are bogus who would trust the internet these days
Last edited by richard; - 23rd May 2018 at 08:38. Reason: ps the solder on pin8 looks a bit dodgy
Warning I'm not a teacher
Im from mobile so i will Post a line of the code for the following question when i will be on computer.
I read the Data from the GPS, especially for the time and date.....
Serin2.....
Then i display the needed info......
Serout2......
What is the command to use inside the Serout2 in order to jump to a LABEL and Correct the UTC?
It will be useful if i understand the command inside the Serout2 that give me the access to jump to a LABEL.
One more question. I see most of You are using the HSERIN2, HSEROUT2,
And You Richard on your code are using the arrayread arraywrite.
I need to check the manual and see what is the difference between those.
ok i'm stack.
i place my code up to now. I dont want anyone to write a code for me, i just want from you to give me direction to solve my following problem.
I know i have many mistakes and maybe i aproach the code in a wrong way, in a difficult direction.
So one of my problems i would like to solve, is to give the right time, in 24H.
I have in mind that i need to use interrupts.
Is there any solution at the moment to use the SEROUT2 command
and jump at a label ???Code:serout2 lcd,32,[$73,$00,$04,$00,$FF,$E0," TIME: ",dec2 hh+3," :",dec2 mm," :",dec2 ss,$00] pause 100
I would like first to solve time issue, even if i have to refresh/clear the display.....then my next problem to solve is to keep the data on the screen and replace only the numbers or characters needed to be change.Code:Plusthree: hh = hh + 3 IF hh = 25 THEN hh = 0 RETURN
Following is the code up to now.
Code:'* Author : LEONARDO BILALIS * '* Notice : Copyright (c) 2017 [LEONARDOS BILALIS] * '* : All Rights Reserved * '* Date : 24/5/2018 * '* Version : 1.0 * '* Notes : This is a GPS * '* : * '**************************************************************** @ ERRORLEVEL -306 ; this command prevents the compiler to give you a notice of ; crossing page boundary - make sure bits are set @ __config _CONFIG1, _HS_OSC & _WDT_OFF & _LVP_OFF & _CP_OFF Include "MODEDEFS.BAS" DEFINE OSC 8 OSCCON=%01111000 '8 Mhz CMCON = 7 'turn comparators off ANSEL = 0 'All digital PORTB = 0 'make low all ports at B range input portb.0 'make input portb.0 '-----------------------------------------------------------------------------/ ' [ ULCD 1'44 4D System ] / '---------------------------------------------------------------------------/ ' "o" degree character is manual created for degree value '----------------------------------------------------------------------------/ ' [ PIC Variables ] / '--------------------------------------------------------------------------/ PWRLED var PORTb.1 ; this shows that the initialization is finished LCD var PORTb.2 ; to LCD operation GPS_TX var PORTb.0 ; info from GPS GPS_RX var PORTb.4 ; COMMANDS TO GPS Testled var PORTb.5 dots var byte dots = 22 countremain var byte ; we use a countremain to check the incoming from portb.0 pause 1000 ' --------------------[ GPS Variables for NMEA sentenses ]---------------------/ ' / ' $GPRMC,090045.000,A,3823.6645,N,02353.3600,E,0.02,195.80,170518,,,A*62 / ' $GNGGA,140405.000,3823.6010,N,02353.3054,E,1,9,0.88,0.8,M,35.9,M,,*40 / ' / '-------------------------------------------------------------------------/ Timeout con 2000 hh var byte 'hours mm var byte 'minutes ss var byte 'seconds sss var word 'milisecs degrees VAR BYTE 'latitude/longitude degrees minutes VAR BYTE 'latitude/Longitude minutes minutesD VAR word 'latitude/LONGITUDE DECIMAL MINUTES dir VAR BYTE ' direction (latitude: 0 = N, 1 = S / longitude: 0 = E, 1 = W) degrees2 VAR BYTE 'latitude/longitude degrees minutes2 VAR BYTE 'latitude/Longitude minutes minutesD2 VAR word 'latitude/LONGITUDE DECIMAL MINUTES dir2 var byte ;direction (latitude: 0 = N, 1 = S / longitude: 0 = E, 1 = W) SatNo VAR BYTE 'number of satellites connected knots var word 'speed over ground knots2 var byte 'speed over ground course var word 'course course2 var byte 'course day var byte 'day month var byte 'month year var byte 'year i var word GNRMC var word 'protocol GNGGA var WORD 'protocol FIX var word 'fix sat V/A Modefix var byte 'mode fix 1 or 2 or 3 depens horizon var byte precision var byte meter var byte METERS var byte Meters2 var byte marker2 var byte 'UTC OR GRT (GREEK TIME) ' -------------------------------------------------------------------------/ ' [ LCD Initialization ] / '------------------------------------------------------------------------/ serout2 LCD,32,[$55] ' uOLED Initialize pause 2000 serout2 lcd,32,[$56,$01] pause 1000 serout2 lcd,32,[$45] ' clear the lcd pause 500 serout2 lcd,32,[$55] pause 500 serout2 lcd,32,[$45] ' clesr the lcd pause 500 serout2 lcd,32,[$73,$00,$03,$11,$ff,$ff," Leonardo Bilalis",$00] pause 200 serout2 lcd,32,[$73,$02,$06,$10,$ff," Copyright 2018",$00] pause 3000 serout2 lcd,32,[$45] pause 1000 serout2 lcd,32,[$73,$02,$06,$10,$ff,$ff," GPS.........",$00] pause 500 serout2 lcd,32,[$45] pause 200 '----------------------------------------------------------------------/ ' [ After the lcd initialization we power the Led at PIC ] / '--------------------------------------------------------------------/ HIGH pwrled '----------------------sent a centence to gps------------------------ ;serout gps_rx,84,[$PMTK_103*30] pause 100 '-------------------------------------------------------------------/ ' [MAIN Program] / '-----------------------------------------------------------------/ Main: ;gosub clearlcd serin2 gps_tx,84,[countremain] ; we check what is coming from the port if countremain = 0 then lostcable ; if nothing is coming the we check the cable ;gosub clearlcd '-------------------------------------------------------------------------------/ ' / ' [ Example NMEA Sentense of GNRMC ] / ' [$GNRMC,090045.000,A,3823.6645,N,02353.3600,E,0.02,195.80,170518,,,A*62] / ' / '--------------------------------------------------------------------------/ serin2 gps_tx,84,[wait("$GNRMC"),_ ;we wait for $GNRMC wait(","),dec2 hh,dec2 mm,dec2 ss,wait("."),dec3 sss,_ ;we wait for 090045.000 which is the time when we got the info wait(","),fix,_ ;we wait for A wait(","),dec2 degrees,dec2 minutes,wait("."),dec4 minutesd,_ ;we wait for 3823.6645 wait(","),dir,_ ;we wait for N wait(","),dec3 degrees2,dec2 minutes2,wait("."),dec4 minutesd2,_;we wait for 02353.3600 wait(","),dir2,_ ;we wait for E wait(","),dec1 knots,wait("."),dec2 knots2,_ ;we wait for 0.02 wait(","),dec3 course,wait("."),dec2 course2,_ ;we wait for 195.80 wait(","),dec2 day,dec2 month,dec2 year] ;we wait for 170518 pause 500 '------------------------------------------------------------------------------/ ' / ' [ Example NMEA Sentense of GNGGA ] / ' [$GNGGA,140405.000,3823.6010,N,02353.3054,E,1,9,0.88,0.8,M,35.9,M,,*40 / ' / '-------------------------------------------------------------------------/ serin2 gps_tx,84,[wait("$GNGGA"),_ ;we wait for GNGGA wait(","),dec2 hh,dec2 mm,dec2 ss,wait("."),dec3 sss,_ ;we wait for 140405.000 which is the time when we got info wait(","),dec2 degrees,dec2 minutes,wait("."),dec4 minutesd,_ ;we wait for 3823.6010 longitude wait(","),dir,_ ;we wait for the N/S wait(","),dec3 degrees2,dec2 minutes2,wait("."),dec4 minutesd2,_;we wait for 02353.3054 latitude wait(","),dir2,_ ;we wait for E/W wait(","),modefix,_ ;we wait for modefix 1,2 or 3 check gps manual for NMEA wait(","),dec2 satno,_ ;we wait for the number of fixed satellites, this is impoetant info wait(","),dec3 horizon,dec precision,_ ;we wait for horizon wait(","),meter,dec2 METERS,dec Meters2] ;we wait for the meters pause 100 '---------------------------------------------------------------------------------/ ' Here if the GPS module havent been fixed to any satellite will jump to notfix / '-------------------------------------------------------------------------------/ if fix = "V" then notfix pause 100 '-----------------------------------------------------------------------------/ ' [ Return from notfix ] / ' [ We clear any character on the display ] / '--------------------------------------------------------------------------/ gosub clearlcd ;serout2 lcd,32,[$45] ;pause 500 '--------------------------------------------------------------------------/ ' here is where the code dispays the stored info from the NMEA sentenses / '------------------------------------------------------------------------/ serout2 lcd,32,[$73,$03,$00,$00,$FF,$FF,"Protocol:","NMEA",$00] pause 100 serout2 lcd,32,[$73,$01,$02,$01,$07,$E0,"Date:",dec2 day,"/",dec2 month,"/",dec2 year,$00] pause 100 serout2 lcd,32,[$73,$00,$04,$00,$FF,$E0," TIME: ",dec2 hh+3," :",dec2 mm," :",dec2 ss,$00] pause 100 serout2 lcd,32,[$73,$00,$07,$00,$FF,$FF," Satellites",$00] pause 100 serout2 lcd,32,[$73,$03,$09,$11,$07,$FF,dec2 satno,$00] pause 100 serout2 lcd,32,[$73,$00,$07,$00,$FF,$FF," Fixed",$00] pause 100 serout2 lcd,32,[$73,$0D,$09,$11,$07,$FF,fix,$00] pause 100 serout2 lcd,32,[$73,$00,$0B,$00,$ff,$ff,"Lat : ",dec2 degrees,"*",dec2 minutes,"'",dec4 minutesd," ",dir,$00] pause 100 serout2 lcd,32,[$73,$00,$0D,$00,$ff,$ff,"Lon : ",dec3 degrees2,"*",dec2 minutes2,"'",dec4 minutesd2," ",dir2,$00] pause 100 ;serout2 lcd,32,[$73,$00,$0C,$00,$ff,$ff,"GND SPEED : ",(dec knots,".",dec2 knots2)*/1.852,$00] ;pause 200 ;serout2 lcd,32,[$73,$00,$0E,$00,$ff,$ff,"Meters : ",dec2 METERS,dec Meters2,$00] pause 5000 serout2 lcd,32,[$45] ' clears the LCD pause 100 goto main '-----------------------------------------------------------------------------/ ' [ SUB ROUTINES ] / '---------------------------------------------------------------------------/ notfix: ' Still looking for fixed signal serout2 lcd,32,[$73,$00,$03,$11,$ff,$ff," Waiting for GPS",$00] pause 100 serout2 lcd,32,[$73,$03,$06,$10,$ff," Time:",dec2 hh+3," :",dec2 mm," :",dec2 ss,$00] pause 1000 serout2 lcd,32,[$73,$00,$08,$10,$ff,rep "." \22,$00] pause 200 serout2 lcd,32,[$45] ' clears the LCD pause 100 goto main 'returns to main lostcable: serout2 lcd,32,[$73,$00,$03,$11,$ff,$ff," Connection lost",$00] pause 100 serout2 lcd,32,[$73,$01,$06,$10,$ff," Please check cable",$00] pause 2000 serout2 lcd,32,[$45] ' clears the LCD pause 100 goto main '-------------------------------------------------------------------------/ ' GREEK TIME and Correcrion / '-----------------------------------------------------------------------/ ' at the moment this is not connected to any part of the code Plusthree: hh = hh + 3 IF hh = 25 THEN hh = 0 RETURN '---------------------------------------------------------------------------/ ' [ CLEAR LCD ] / '-------------------------------------------------------------------------/ Clearlcd: serout2 lcd,32,[$45] pause 500 RETURN
Last edited by astanapane; - 25th May 2018 at 20:56.
I have found that inline math for lcdout cmd on a pic16 turns to crap, serout2 may have the same issues
you probably need to do the math first then print result
i would do it this way
hh=hh+3 ;utc+3
hh=hh//24 ;REALLY SHOULD ADD A DAY TO DATE TOO IF day changes
serout2 lcd,32,[$73,$00,$04,$00,$FF,$E0," TIME: ",dec2 hh," :",dec2 mm," :",dec2 ss,$00]
pause 100
Warning I'm not a teacher
Hi Richard,
Thanks for the reply. I will try that.
Bookmarks