how to change GPS characters into numbers

mary rose

New Member
I want to change the hour time from a GPS module which is in separate characters into a number. For example 12 o'clock is an ascii character for '1' followed by an ascii character for '2'. I want to change the 2 characters and merge into 1 variable number '12' so I can simply then add or subtract to display different time zones.

main:
setfreq m16

serin c.4,T9600_16,("GGA"),b27,b0,b1,b2,b3,b4,b5


setfreq m4

serout c.1,N2400, (254,128,"UTC ",b0,b1,":",b2,b3,":",b4,b5," ")

goto main
 
Last edited:

AllyCat

Senior Member
Hi,

There have been previous posts on the forum concerning the parsing of GPS strings, so a search for "GPS" or "parse" might be productive, but....

The mathematical principle behind a number like "123" is that it represents a number formed of (1 * 100) + (2 * 10) + 3 . So you can convert the digit sequence b0 , b1 to a "real" number by using value = b0 * 10 + b1 , etc.

But first you need to convert each ASCII value into a digit. That can be done by subtracting 48 (because the ASCII value for zero is 48) , but this can be written more clearly by directly subtracting "0". Thus you can do your hours conversion with a single line such as hour = b0 - "0" * 10 + b1 - "0". For example, here's the test code that I tried in the simulator to check that I wasn't t misleading you :
Code:
symbol hour = w5
b0 = "2"
b1 = "3"
hour = b0 - "0" * 10 + b1 - "0"
sertxd(#hour)
That can be extended further but there are several potential "gotcha"s: You must remember that PICaxe maths always works strictly from left to right and also, not all GPS ASCII strings are parsed with a fixed (or constant) number of characters (so your program might need to scan for a ":" or "." character first).

Cheers, Alan.
 

mary rose

New Member
Hi,

There have been previous posts on the forum concerning the parsing of GPS strings, so a search for "GPS" or "parse" might be productive, but....

The mathematical principle behind a number like "123" is that it represents a number formed of (1 * 100) + (2 * 10) + 3 . So you can convert the digit sequence b0 , b1 to a "real" number by using value = b0 * 10 + b1 , etc.

But first you need to convert each ASCII value into a digit. That can be done by subtracting 48 (because the ASCII value for zero is 48) , but this can be written more clearly by directly subtracting "0". Thus you can do your hours conversion with a single line such as hour = b0 - "0" * 10 + b1 - "0". For example, here's the test code that I tried in the simulator to check that I wasn't t misleading you :
Code:
symbol hour = w5
b0 = "2"
b1 = "3"
hour = b0 - "0" * 10 + b1 - "0"
sertxd(#hour)
That can be extended further but there are several potential "gotcha"s: You must remember that PICaxe maths always works strictly from left to right and also, not all GPS ASCII strings are parsed with a fixed (or constant) number of characters (so your program might need to scan for a ":" or "." character first).

Cheers, Alan.
Thanks Alan. You've put me on the right track.
Cheers
Bob, ZL4CE
 

westaust55

Moderator
Untested (by me) for your GPS application however, try using the hash ( # ) symbol in front of your variable in the SERIN command.

so instead of

SERIN pin, baud (“GGA”), b27, b1, b2, b3, b4, b5
Where/if you are expecting say
B1 = “1”
B2 = “2”
B3 = “:”
B4 = “3” and
B5 = “5”

try

SERIN pin, baud, (“GGA”), b27, #b1,#b2

B1 should receive the “1” and “2” and contain 12 terminated by the “:” (a none numeric character)
Then B2 would contain the minutes,
subject to the minutes characters being followed by a non digit (0-9) character.

however if your time string does not have separators between the hours, minutes and seconds then this will not work.
 
Last edited:

marks

Senior Member
Hi mary rose,
you may be interested at this code snippet
just updated to work with a neo gps will rewrite post#1 when I get a chance
 

mary rose

New Member
thanks everyone, success! Exactly what I wanted

symbol hours = b6
symbol mins = b7
symbol secs = b8


serout c.1,n2400,(254,1)


main:
setfreq m16

serin c.4,T9600_16,("GGA"),b27,b0,b1,b2,b3,b4,b5

hours = b0 - "0" * 10 + b1 - "0"
mins = b2 - "0" * 10 + b3 - "0"
secs = b4 - "0" * 10 + b5 - "0"



debug
setfreq m4

serout c.1,N2400, (254,128," UTC ",#hours,":",#mins,":",#secs)


goto main
 

hippy

Technical Support
Staff member
hours = b0 - "0" * 10 + b1 - "0"

There is some mathematical trickery which can be used to improve that. Putting brackets around things to reflect real world maths rather than PICAXE maths ...

hours = ( ( b0 - "0" ) * 10 ) + b1 - "0"
hours = ( b0 * 10 ) - ( "0" * 10 ) + b1 - "0"
hours = ( b0 * 10 ) + b1 - "0" - ( "0" * 10 )
hours = ( b0 * 10 ) + b1 - ( "0" * 11 )
hours = ( b0 * 10 ) + b1 - ( 48 * 11 )
hours = ( b0 * 10 ) + b1 - 528

And that handily suits PICAXE left to right maths. The PICAXE supports 16-bit maths so there is no overflow, the result will be correct when the 'hour' byte value is set ...

hours = b0 * 10 + b1 - 528
mins = b2 * 10 + b3 - 528
secs = b4 * 10 + b5 - 528

Code:
b0 = "2" : b1 = "3"
b2 = b0 * 10 + b1 - 528
SerTxd( b0, b1, " = ", #b2, CR, LF )
 
Top