Maths question, combing two 16 bit data streams into a 32 bit stream?

Permabanned
Joined
28 Nov 2003
Posts
10,695
Location
Shropshire
My ecu outputs seven decimal place GPS coordinates as two 16 bit channels and the data reading software then combines them using maths to give a degree based GPS coordinate to generate a track map.

Below are two samples, one raw data from the ecu as two 16 bit channels, the other the GPS coordinate in degrees after the software has done the maths wizardry. Can anyone work out what it's doing to the raw date to combine them to make the correct coordinate please? I can't....

ECU output: GPS Latitude HW : 8015
GPS Latitude LW : -13983

Maths gives : Coordinate 52.8870988 degrees latitude

########################

ECU output : GPS Longitude HW : -364
GPS Longitude LW : 14387

Maths gives : Coordinate -2.6401195 degrees longitude

########################

All I can say is the hardware won't allow transmission of 32 bit data on the serial port, so they somehow split it up into two sets of 16 bit, then rejoin it in the software using maths. The end result is degrees, minutes and seconds to seven decimal places. I am collecting the data from the CAN BUS of the Motec ecu, and logging it in a none Motec data logger. The data logger's software has powerful maths functions, so once I can see how Motec split and rejoin the data streams I should be able to duplicate it in the other software. They also split the GPS time data stream into two 16 bit channels, this may be easier, example below, (the time format does not take into account British Summer Time offset, by the way).

GPS Time HW : 1614
GPS Time LW : -8040

GPS Time (combined) : 105832.600


Actual time was 10.58 AM and 32.600 seconds.

Thanks. I think HW is "high word", and LW is "low word", and combing the two 16 bit streams correctly is the key.
 
It would be easier to ignore the decimal values that are being passed through and concentrate on the bit values.

Unless it's doing something unusual in the conversion process then all that's happening is that two arrays of 16 bits are being concatanated into one array of 32 bits.

Also "using maths" is not a very helpful description of the process. That's equivalent to saying "using words he described something" and expecting us to know exactly what he described :)
 
Unless it's doing something unusual in the conversion process then all that's happening is that two arrays of 16 bits are being concatanated into one array of 32 bits.
this is what I'd expect, it should be easy to see if you've got them in bit format as the 32-bit one will just be the two 16-bit ones end on end.
 
As said above, you might convert the floating point to an array of words and send those words individually.

You might also decide to split them up by taking advantage of how data gets truncated (note: floating point data often acts very differently to this!) when converted to smaller datatypes and use the left and right shift operators (depending on system) to shift the data 16-bits when necessary. Then convert those to 16-bit words. I wrote a more lengthy explanation of that process but I feel like I'd be making a fool of myself if I posted it and it turned out it was wrong. Also I imagine it's not very portability friendly. :p
 
I can't work out what the maths operation is. Here's what the most obvious thing would be:

-Interpret negatives as their binary 2's complement equivalents.
-Concatenate the two 16 bit words into a 32 bit word
-See how much of the 32 bit range this fills, and interpret as a value in degrees between -90 and 90.

For the latitude using this method I get +2.2 degrees which is clearly wrong. Anyone else got a better idea?
 
I also don't understand why the ECU would send stuff in this fashion. A CAN packet has a payload of 8 bytes which is more than enough to send the 32 bit latitude/longitude values in a single transmission.
 
ECU output: GPS Latitude HW : 8015
GPS Latitude LW : -13983

Maths gives : Coordinate 52.8870988 degrees latitude

8015*2^16 (shift left 16 bits)
+ -13983 (add on the second word)
/ 10^7 (7 decimal place fixed point)
=52.5

Pretty close!

ECU output : GPS Longitude HW : -364
GPS Longitude LW : 14387

Maths gives : Coordinate -2.6401195 degrees longitude

-364*2^16 (shift left 16 bits)
+ 14387 (add on the second word)
/ 10^7 (7 decimal place fixed point)
=-2.384

Again pretty close.

It's just putting together the 16-bit words. It looks like both words are 2's complement - it doesn't work if you assume it is two halves of a 32-bit 2's complement word.

Rob.
 
I think grumpysculler is the winner. The HW and LW labels are misleading as it's just a sum with no concatenation involved. The answer is then interpreted as a fixed-point value.

/edit:no I guess HW and LW do make sense, the HW is just the most significant of the two values.
 
Last edited:
If it's not doing something equivalent to:

Code:
float longitude;
short* s = (s*)&longitude;
s[0] = HW;
s[1] = LW;

(Possibly with HW and LW reversed) I'll eat my hat. It'd be insane to do anything else.
 
8015*2^16 (shift left 16 bits)
+ -13983 (add on the second word)
/ 10^7 (7 decimal place fixed point)
=52.5

Pretty close!



-364*2^16 (shift left 16 bits)
+ 14387 (add on the second word)
/ 10^7 (7 decimal place fixed point)
=-2.384

Again pretty close.

It's just putting together the 16-bit words. It looks like both words are 2's complement - it doesn't work if you assume it is two halves of a 32-bit 2's complement word.

Rob.

just did the same thing before reading on and realising someone else got there first :(

with something like this it is often easier to think of it in hex.

8015 = 1F4F
-13983 = C961

now all you need to do is put the two together, since 8015 is the HW (highest word) it goes first

1F4F C961

Now just convert back to decimal and you get 524798305, assuming its a float then it could be 52.4798305

Strange its not the same as the example.
 
Really appreciate the trouble you guys have gone to for this, thanks. I too don't see why the match isn't exact though. The GPS receiver / antenna was stationary. It's all quite complex though, as I am logging data from the Motec ecu internally within it, and using its dedicated software with pre compiled maths to show the raw and modified data. I am also logging data from the Motec ecu via CAN on a logger of a different make, and the raw coordinates, whilst very similar, are not the same. For example

LON HW -364
LON LW 14664

LAT HW 8015
LAT LW -13996

Which, considering they are both supposedly reading the same data streams is even odder :) I have e-mailed Motec's support for help, but you know how touchy big companies get about sharing data ;)

How would I write the maths as a script? It's at times like this my lack of attention at maths shows it for the regretful lack of dedication my maths teacher described it to be at the time :(

Again, thanks!!
 
Really appreciate the trouble you guys have gone to for this, thanks. I too don't see why the match isn't exact though.

Could be the difference in values you've highlighted or there could be some sort of smoothing going on. Or it could be gremlins...
How would I write the maths as a script? It's at times like this my lack of attention at maths shows it for the regretful lack of dedication my maths teacher described it to be at the time :(

The maths is pretty simple and you've got the algorithm above. If you want a script, you will need to specify a language. If you can do basic programming, either of the two approaches above should be pretty easy to implement...
 
Really appreciate the trouble you guys have gone to for this, thanks. I too don't see why the match isn't exact though.

Probably because that's not what it's doing. At the very least it won't be a decimal fixed point, it'll be binary so it'll be a bit shift.

And I still think that's not what it's doing.
 
Actually, pretty close is a relative term, the difference between the Motec maths and that that's been posted is one is in Shropshire, the other is in the North Sea :) The GPS receiver makers claim an accuracy if three metres, so I think the maths is differing somehow. It's a PITA, if I could afford Motec's own logger this would all be done automagically, but I can't, so it gets a bit involved :)
 
Back
Top Bottom