Calculations in 14m2 or 20m2

nerdegutta

Senior Member
Hi.

First post, so be gentle.

I need help with some calculations. I got this number:

58.217088

b0 = 5, b1 = 8, b2 = 2, b3=1 and so on.

I want to trunc the 58.
Multiply the remainder with 0,6
And add 58 back, something like this:

58.217088 - 58 = 0,217088
0,217088 * 0,6 = 0,361813
58+0,361813 = 58,361813

How can I do this with my 14M2, or 20M2?

Yes, the numbers are from the $GPGGA NMEA sentence, and are Latitude.

Thank you for your time.


-nerdegutta
 

PaulRB

Senior Member
0,217088 * 0,6 = 0,361813
-nerdegutta
Hi and welcome to the forum.

I don't understand the above, should the answer not be 0.130253 ?

or did you mean to say

0,361813 * 0,6 = 0,217088 ?

Assuming one or the other...

Multiplying by 0.6 is the same as multiplying by 6, then dividing by 10. Dividing by 10 is the same as moving all the digits one place to the right.

So you could take each digit in turn, starting with the least significant. Multiply it by 6. Then divide by 10, but also calculate the remainder (see % or // operators). Over-write the original byte with the remainder and carry the tens to the next-least-significant digit, and so on.

Once all digits have been multiplied by 6, shift them all one place to the right and put the carry from the last multiplication into the most significant byte.

Paul
 
Last edited:

MartinM57

Moderator
Have to be really careful here, as alluded to in my thread about the GPS010 example1.bas program from Rev-Ed.

The 'raw' GPS sentence latitude for the quoted values will normally be 5821.7088 - 58 degrees, 21 minutes and 0.7088 of a minute - so when you read it in, you will get b0=5, b1=8 etc.

The (well one of the) challenge is then working out where the decimal should be - I suspect b4 will contain a "." but you have to confirm that. For example just north of the equator I suspect the sentence component would be 121.7088 (rather than 0121.7088?) so b3 would contain the "."

That makes coding more difficult (if you want to deal with latitudes less than 10) as you have to move the contents of the variables around to standard places (b0 = 10's of degrees; b1 = units of degrees etc)

And what happens at the RH end of the latitude values - what is the sentence component for 58 degrees 21 minutes exactly - 5821.0, 5821, 5821.000, something else? Need to be careful that if it is not always 4 decimal places that you don't end up with other bits of the sentence in your b variables

Why on earth didn't NMEA standardise on a fixed width "3.4" format for latitudes and "4.4" format for longitudes? Would make life much easier...
...and we haven't got to the maths yet :)
 

PaulRB

Senior Member
Ah. That's the same as multiplying by 10 and dividing by 6. Multiplying by 10 is the same as moving all digits one place left. Then divide the result by 6 one digit at a time, starting with the most significant (remember doing long division at school?)

But what if the result is >= 1? Do you want 58 to become 59?
 

nerdegutta

Senior Member
Have to be really careful here...
I know.


Why on earth didn't NMEA standardise on a fixed width "3.4" format for latitudes and "4.4" format for longitudes? Would make life much easier...
...and we haven't got to the maths yet :)
Um... Because they can?:rolleyes:

Ah. That's the same as multiplying by 10 and dividing by 6. Multiplying by 10 is the same as moving all digits one place left. Then divide the result by 6 one digit at a time, starting with the most significant (remember doing long division at school?)

But what if the result is >= 1? Do you want 58 to become 59?
No, We want it to be 58 - for now.

I'll be back.

Thanks for the replies guys.
 

nerdegutta

Senior Member
How can I combine/join variables?

I want
b3 = 2
b4 = 1
b5 = 7
b6 = 0
b7 = 8
b8 = 8

to be 217088 in one variable, or since w can only be 65535, 21708?

Or is there another/better way to do the calculations of a $GPGGA sentence?


-nerdegutta
 

srnet

Senior Member
From my Pongsat program, the ASCII of the GPS string has already been moved from scratchpad (background receive) into a RAM buffer.

var1,2,3,4,5,loopv1 are byte variables, wvar1 is a word variable

Code:
GPSminstoword:
'converts 5 ASCII number characters from RAM buffer starting at var1 into a word, returns value in word wvar1
	
loopv1 = var1 
	
	peek loopv1, var5, var4	, var3, var3, var2, var1 'NOTE: var3 done twice to ignore DP

	var5 = var5 - $30 	'strip off the ascii part
	var4 = var4 - $30 	'strip off the ascii part
	var3 = var3 - $30 	'strip off the ascii part
	var2 = var2 - $30 	'strip off the ascii part
	var1 = var1 - $30 	'strip off the ascii part
			
	Wvar1 = var5 * 10 + var4 * 10 + var3 * 10 + var2 * 10 + var1 'max value here should be 59999
			 		
return
 

PaulRB

Senior Member
w8 = b3 * 10 + b4 * 10 + b5 * 10 + b6 * 10 + b7

but that doesn't neccessarily make the calculations much easier, and a 16 bit variable can't even hold all 5 digit numbers.

Edit: I'll shut up now, srnet has already done all this...
 

nerdegutta

Senior Member
From my Pongsat program, the ASCII of the GPS string has already been moved from scratchpad (background receive) into a RAM buffer.

var1,2,3,4,5,loopv1 are byte variables, wvar1 is a word variable

Code:
GPSminstoword:
'converts 5 ASCII number characters from RAM buffer starting at var1 into a word, returns value in word wvar1
	
loopv1 = var1 
	
	peek loopv1, var5, var4	, var3, var3, var2, var1 'NOTE: var3 done twice to ignore DP

	var5 = var5 - $30 	'strip off the ascii part
	var4 = var4 - $30 	'strip off the ascii part
	var3 = var3 - $30 	'strip off the ascii part
	var2 = var2 - $30 	'strip off the ascii part
	var1 = var1 - $30 	'strip off the ascii part
			
	Wvar1 = var5 * 10 + var4 * 10 + var3 * 10 + var2 * 10 + var1 'max value here should be 59999
			 		
return
Thanks, but I don't think the 14M2 has a scratchpad. Does it? I thought I read somewhere that only the X2 has scratchpad.
(Can I find the program somewhere?)

w8 = b3 * 10 + b4 * 10 + b5 * 10 + b6 * 10 + b7

but that doesn't neccessarily make the calculations much easier, and a 16 bit variable can't even hold all 5 digit numbers.

Edit: I'll shut up now, srnet has already done all this...
Thanks, and don't shut up. Keep it coming.:)
 

srnet

Senior Member
Is the last decimal digit needed for the calculation (whatever that is) ?

If you drop the last digit, the GPS co-ordinate is still in units of 1.85M, even at the equator. Manually round the last digit, and you are within 1M.

Do you need co-ordinates with so much precision ?

It would help if we are told what the application is.
 

nerdegutta

Senior Member
Is the last decimal digit needed for the calculation (whatever that is) ?

If you drop the last digit, the GPS co-ordinate is still in units of 1.85M, even at the equator. Manually round the last digit, and you are within 1M.

Do you need co-ordinates with so much precision ?

It would help if we are told what the application is.
I got an EM-411 gps receiver, connected to a 14M2.
The 14M2 receives/extract the $GPGGA sentence, and stores the values in EEPROM. I know the EEPROM is limited and will not hold much data, but this is a proof of concept project for me. At a later stage I might add a 24LC512 IC.

So, when some data is stored in EEPROM, I connect the 14M2 to my computer. On the computer side I use HyperTerm, and save the receiving data as a *.gpx file. This file is loaded into Google Earth.

I got everything up and running, but when I first loaded the gpx file, Google Earth was way off. So after a bit of searching the net I realized that I had to calculate the values.

1 meter accuracy is more than enough. :)

-nerdegutta
 

srnet

Senior Member
You can use a 14M2 for this, but the 28X2 or 40X2 has a lot more space and the background receive.

The background receive makes using a GPS fairly easy, you let the background receive run for a few seconds then go looking in the scratchpad for the GPS strings. You can do all the calculations and manipulations direct on the data in the scratchpad, no need to use scarce variables.

If you worried about physical size, that snippet of program was taken from the Pongsat GPS balloon tracker, called a pongsat because it fits in a ping pong ball.

http://www.picaxeforum.co.uk/showthread.php?22369-Picaxe-pongsat
 

nerdegutta

Senior Member
You can use a 14M2 for this, but the 28X2 or 40X2 has a lot more space and the background receive.

The background receive makes using a GPS fairly easy, you let the background receive run for a few seconds then go looking in the scratchpad for the GPS strings. You can do all the calculations and manipulations direct on the data in the scratchpad, no need to use scarce variables.

If you worried about physical size, that snippet of program was taken from the Pongsat GPS balloon tracker, called a pongsat because it fits in a ping pong ball.

http://www.picaxeforum.co.uk/showthread.php?22369-Picaxe-pongsat
Thanks!

I want to use the 14M2, for now. Perhaps at a later time, I'll use the 28X2.

Thanks for the link.
 

nerdegutta

Senior Member
w8 = b3 * 10 + b4 * 10 + b5 * 10 + b6 * 10 + b7
Lets say:
Code:
b3 = 2
b4 = 1
b5 = 7
b6 = 0
b7 = 8
How does the IC calculate that?
Manual2 page 22.

Maths is performed strictly from left to right. Unlike some computers and
calculators, the PICAXE does not give * and / priority over + and -.
Like this:
w8 = b3 * 10 + b4 * 10 + b5 * 10 + b6 * 10 + b7

w8 = 2*10 + b4 * 10 + b5 * 10 + b6 * 10 + b7

w8 = 20 + 1 * 10 + b5 * 10 + b6 * 10 + b7
w8 = 21 *10 + b5 * 10 + b6 * 10 + b7

w8 = 210 + 7 * 10 + b6 * 10 + b7
w8 = 217 * 10 + b6 * 10 + b7

w8 = 2170 + b6 * 10 + b7
w8 = 2170 + 0 * 10 + b7

w8 = 2170 * 10 + b7
w8 = 21700 + 8

w8 = 21708

Did I get it?

And now I can w 9 = w8 / 6
w9 = 21708 / 6
w9 = 3618

Correct or not?

-nerdegutta
 

hippy

Ex-Staff (retired)
The 14M2 receives/extract the $GPGGA sentence, and stores the values in EEPROM.
You can store the raw data and then convert that when you come to send to the PC without having to worry about how much space the converted numbers would take up if they had been stored. All you need then is to optimise the storage of the raw data.

You can store coordinates in the form "dddmm.mmmmm,p" in two 16-bit words with 0.00002 accuracy. So just 8 bytes to hold one set of coordinates.

The "dddmm" can be stored using a straight decimal conversion which will be either 9000 or 18000 max. The N/S, E/W direction can be indicated by adding 20000 to the number (or not).

For ".mmmmm" the first four digits can be straight decimal converted giving 9999 max. The fifth digit can be divided by two, multiplied by 10000, then added, giving a maximum of 49999.

For example "6789.12345,N" could become two numbers 26789 and 21234.

Code:
' 17859.12345,E

b10 = "1"
b11 = "7"
b12 = "8"
b13 = "5"
b14 = "9"
b15 = "1"
b16 = "2"
b17 = "3"
b18 = "4"
b19 = "5"
b20 = "E"

' Display raw data

SerTxd( b10,b11,b12,b13,b14,".",b16,b15,b17,b18,b19,",",b20, CR, LF )

' Convert to two words

w0 = b10 * 10 + b11 * 10 + b12 * 10 + b13 * 10 + b14 - 9040

If b20 = "E" Then
  w0 = w0 + 20000
End If

w1 = b19 - "0" / 2 * 10 + b15 * 10 + b16 * 10 + b17 * 10 + b18 - 53328

' Display stored data

SerTxd( #w0, " ", #w1, CR, LF )

' Convert from two words and display

BinToAscii w1, b15,b11,b12,b13,b14
b15 = b15 - "0" * 2 + "0"

If w0 >= 20000 Then
  w0 = w0 - 20000
  SerTxd( #w0, ".", b11, b12, b13, b14, b15, ",E", CR, LF )
Else
  SerTxd( #w0, ".", b11, b12, b13, b14, b15, ",W", CR, LF )
End If
 

hippy

Ex-Staff (retired)
Also, converting a set of digits representing decimal minutes to decimal degrees is quite easy using long-hand division by 6.

The following can be extended for any number of digits after the decimal point and the maths can all be put into a loop using @ptr or @bptr to keep code size down.

Code:
'         mm.mmmmmmmm
Eeprom ( "59.12345678" )

Read 0,  b10 ' 5
Read 1,  b11 ' 9
Read 3,  b12 ' 1
Read 4,  b13 ' 2
Read 5,  b14 ' 3
Read 6,  b15 ' 4
Read 7,  b16 ' 5
Read 8,  b17 ' 6
Read 9,  b18 ' 7
Read 10, b19 ' 8

SerTxd ( b10,b11,".",b12,b13,b14,b15,b16,b17,b18,b19, " minutes = " )

b10=         -"0"+ b10
b10=b10//6*10-"0"+ b11 : b11 = b10/6+"0"
b10=b10//6*10-"0"+ b12 : b12 = b10/6+"0"
b10=b10//6*10-"0"+ b13 : b13 = b10/6+"0"
b10=b10//6*10-"0"+ b14 : b14 = b10/6+"0"
b10=b10//6*10-"0"+ b15 : b15 = b10/6+"0"
b10=b10//6*10-"0"+ b16 : b16 = b10/6+"0"
b10=b10//6*10-"0"+ b17 : b17 = b10/6+"0"
b10=b10//6*10-"0"+ b18 : b18 = b10/6+"0"
b10=b10//6*10-"0"+ b19 : b19 = b10/6+"0"

SerTxd ( "0.", b11,b12,b13,b14,b15,b16,b17,b18,b19, " degrees", CR, LF )
 

MartinM57

Moderator
Nice work Hippy - thanks

Looks like a useful update for GPS010 example1.bas. Would be nice if that program reported:
- exactly what was coming from the GPS010
- the above conversion to decimal degrees (using negative for Easterly/Southerly rather than artificially adding a big number) in a format that can be pasted straight into Google maps e.g. 51.312092,-2.41358 (you may recognise that place!)
- ...taking account of my and your points about decimal minutes > 65535 and the problem with detecting .0001, .001, .01, .1 etc

Are you volunteering? :) It would certainly add value to the software and potentially help to attract more sales when people see a canned, and working, example they can start with
 

hippy

Ex-Staff (retired)
As noted earlier, example1.bas is not that useful for handling decimal minutes of coordinates so it would be better to base code for that on example2.bas using background receive. We also need to avoid the simplest example code becoming so complicated that what it does demonstrate is no longer clear.

I probably will produce an example for reporting current coordinates in +/- decimal degrees because that is useful to have. No idea when I will be able to schedule doing that though.
 

hippy

Ex-Staff (retired)
Example code attached which converts the GPS 'dddmm.mmm,h' degrees plus decimal minutes co-ordinates into 'd.ddddd' decimal degrees, used by Google Maps etc. The 'DIGITS' constant defines how many digits after the decimal point.
 

Attachments

nerdegutta

Senior Member
Thanks.

I will now go through the code line by line, to see if I understand it. Looks like I'm going to learn a great deal, both about this BASIC and the programming logic. :)


... and I'll be placing an order for some X2 parts in the near future.:cool:


- nerdegutta
 
Top