C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old March 5th, 2010, 07:25 AM
andy101 andy101 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2004
Location: UK
Posts: 196 andy101 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 10 h 57 m 49 sec
Reputation Power: 9
Data Type Casting

I am working on a Windows platform with VS 2005 C++, but the problem relates to c/c++ in general.
I have been trying to interface with a GPS software program which uses a message made up to an 20 word array of unsigned shorts;

e.g.
unsigned short messageData[20];

I have been trying to use data from a home GPS system which includes Lat and Long and heading.; these have been converted from strings to floats.

e.g.

float lat, long, heading;

My problem is that as I know the scaling factors for the lat, long and heading in the messageData buffer;

e.g.
For lat & long
LSB = 8.377E-08; Twos complement - 32 bits Max/ Min -180 to +180; top bit is the sign

For Heading
LSB 0.00549306; Twos complement - 16 bits Max/ Min -180 to +180; top bit is the sign

Setting the heading:-
Code:
unsigned short heading = (unsigned short)(newHeading/0.00549306);
messageData[10] = heading;

Getting the heading:-

Code:
bool negative;
unsigned short currentField = messageData[10];
if(currentField & 0x8000) 
{
	// Set the negative flag
	negative = true;
}
else
	negative = false;
float heading = (currentField & 0x7FFF) * g_nScalings[wordPos];
if(negative)
	heading = -(180 - heading);
But this does not work as I expected; am I missing something?

As for the 32 bit latitude, I was going to this:-

Setting the Latitude:-
Code:
union
{
	int lat_long;
	unsigned short buff[2];
}convert;

unsigned short highWord, lowWord;
int newData = (int)(fEngValue/8.377E-08);

convert.lat_long = newData;
highWord = convert.buff[1];
lowWord = convert.buff[0];
I need to get and set data in the message that is of type unsigned short and use in my program as scaled floats.

Any suggestions please as the above code produces the wrong results; it may be a casting problem.

Andy.

Reply With Quote
  #2  
Old March 5th, 2010, 02:26 PM
LittleGrin LittleGrin is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Oct 2007
Posts: 921 LittleGrin User rank is Colonel (50000 - 60000 Reputation Level)LittleGrin User rank is Colonel (50000 - 60000 Reputation Level)LittleGrin User rank is Colonel (50000 - 60000 Reputation Level)LittleGrin User rank is Colonel (50000 - 60000 Reputation Level)LittleGrin User rank is Colonel (50000 - 60000 Reputation Level)LittleGrin User rank is Colonel (50000 - 60000 Reputation Level)LittleGrin User rank is Colonel (50000 - 60000 Reputation Level)LittleGrin User rank is Colonel (50000 - 60000 Reputation Level)LittleGrin User rank is Colonel (50000 - 60000 Reputation Level)LittleGrin User rank is Colonel (50000 - 60000 Reputation Level)LittleGrin User rank is Colonel (50000 - 60000 Reputation Level)LittleGrin User rank is Colonel (50000 - 60000 Reputation Level) 
Time spent in forums: 1 Week 11 h 50 m 18 sec
Reputation Power: 535
Your problem is that you are assuming specific representations of integral and floating point types.

It is not a C/C++ problem : C/C++ makes virtually no guarantees about how floating point types are layed out at the byte level, and almost no guarantee of how integral types are layed out (eg endianness). If your code makes such assumptions - which your code does, by doing bit fiddling - then you need to ensure the assumptions are valid.
__________________
Right 98% of the time, and don't care about the other 3%.

“It has been said that the great scientific disciplines are examples of giants standing on the shoulders of other giants. It has also been said that the software industry is an example of midgets standing on the toes of other midgets.” (Alan Cooper)

Reply With Quote
  #3  
Old March 5th, 2010, 03:42 PM
andy101 andy101 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2004
Location: UK
Posts: 196 andy101 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 10 h 57 m 49 sec
Reputation Power: 9
Quote:
Originally Posted by LittleGrin
Your problem is that you are assuming specific representations of integral and floating point types.

It is not a C/C++ problem : C/C++ makes virtually no guarantees about how floating point types are layed out at the byte level, and almost no guarantee of how integral types are layed out (eg endianness). If your code makes such assumptions - which your code does, by doing bit fiddling - then you need to ensure the assumptions are valid.

Thanks, just to recap and get things right in my mind; if a heading value is represented as an unsigned short (16 bits) with bit 1 = 0.000030517578125; so the range is -1 to + 1 and if we multiple by 180 we get -180 to +180 degrees

Now for a test I set heading to 3.45 then the following occures.

3.45/0.000030517578125 = 1B999 in Hex; but as we can only store 16 bits the debugger shows B999 as the value.

Now when I come to decode that vaue via:-

B999 * 0.000030517578125 = 1.44998169 which is wrong and if x 180 to get into degrees then get 260.99.

I am confused!?!

Reply With Quote
  #4  
Old March 5th, 2010, 03:57 PM
jwdonahue's Avatar
jwdonahue jwdonahue is offline
Bellevue WA, USA
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: May 2004
Location: Bellevue Washington, USA
Posts: 3,398 jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level)jwdonahue User rank is Lieutenant General (80000 - 90000 Reputation Level) 
Time spent in forums: 3 Weeks 5 Days 6 h 48 m 17 sec
Reputation Power: 886
Quote:
Originally Posted by any101
I am confused!?


Me too. Nothing you said makes any sense at all.
__________________
My worst nightmare was a pointless infinite loop.
Work in progress; don't poke the curmudgeon!
http://www.odonahue.com/

Reply With Quote
  #5  
Old March 5th, 2010, 04:06 PM
andy101 andy101 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2004
Location: UK
Posts: 196 andy101 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 10 h 57 m 49 sec
Reputation Power: 9
An array of type unsigned short contains data and one item:-

messageData[10] is the heading which needs to be processed with the following information:-

LSB (bit 0) = 0.000030517578125 sign bit is bit 15,so if we have 0111 1111 1111 1111 then thats 1 and if we have
1111 1111 1111 1111 that -1

If we have 0000 0000 1111 1111 = 255
Now we need to scale it by 0.000030517578125 which gives us 0.007781982421875.

To get the heading into degrees then X 180;
= 1.40075 degrees.

Does that helps?

Reply With Quote
  #6  
Old March 5th, 2010, 04:35 PM
dwise1_aol's Avatar
dwise1_aol dwise1_aol is offline
Contributing User
Dev Shed God 2nd Plane (6000 - 6499 posts)
 
Join Date: Jan 2003
Location: USA
Posts: 6,252 dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 2 Weeks 5 Days 19 h 13 m 3 sec
Reputation Power: 1985
I think you should get back to the original points that LG raised about your opening post.

What is the precise specification of the format of the data messages that you are getting from the GPS receiver? Superficially, the message just appears to be a stream of bytes, one after the other. But what does each and every byte in that stream represent?

LG specifically mentioned endianness. That's a description of the byte-order of multi-byte values. Intel is little-endian because the first byte is the LSB (least-significant byte). Some processors, TCP/IP, and some serial protocols are big-endian, meaning that the first byte is the MSB. If a little-endian platform reads in a big-endian data stream and ignores the issue of endianness, then it can very easily reverse the order of the bytes in multi-byte data and thus end up with garbled data.

So again, what is the specification of the format of that data stream you're receiving from the GPS receiver? And precisely how are you reading it in?

Until you've answered those questions satisfactorily, worrying about floating-point formats is pointless. You could be doing everything else exactly correctly, but if you're garbling your data upon input, then your results are still going to be garbled.


PS
A basic electronics hardware troubleshooting technique might help you.

You have a system in which a signal is input, gets processed by a series of subsystems, and produces an output. You have an input, but no output, so you know that something's wrong. How you do narrow down which subsystem contains the fault?

Test the outputs of the subsystems and see if you're getting the signal you expect. When you've found the subsystem that gets a proper input but doesn't produce the proper output, then you've isolated the fault to that subsystem.

Test for valid data at each point in your process.
You read the data stream -- is that data stream what you expect it to be?
You convert that data stream into variable values (eg, that array of short ints) -- do those variables contain what you expect them to contain?
etc.

If you can step through the code with a debugger, it would really help you in this troubleshooting. Even if you need to use printf's to dump variable values, that would still be far better than trying to guess.

Last edited by dwise1_aol : March 5th, 2010 at 04:47 PM.

Reply With Quote
  #7  
Old March 6th, 2010, 07:59 AM
dwise1_aol's Avatar
dwise1_aol dwise1_aol is offline
Contributing User
Dev Shed God 2nd Plane (6000 - 6499 posts)
 
Join Date: Jan 2003
Location: USA
Posts: 6,252 dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level)dwise1_aol User rank is General 15th Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 2 Weeks 5 Days 19 h 13 m 3 sec
Reputation Power: 1985
Here's an example of the effect of endianness.

Let's say that you have a single-precision IEEE 754 floating-point value of 100.0 being read in: 0x42C80000. The four bytes (2 short ints) that represent that value would appear in memory in one of two ways depending on the endianness of your system:
Big -- bytes(0x42, 0xC8, 0x00, 0x00), short(0x42C8, 0x0000)
Little -- bytes(0x00, 0x00, 0xC8, 0x42), short(0x42C8, 0x0000)

As you can see, the order of the bytes in little-endianness (eg, Intel, therefore Windows and most Linux boxes) is reversed from what it is in big-endianness (the most likely order in your receiver's serial protocol).

Now, if you store each byte of that 100.0f into memory in the same order in which you receive it, then your program will not interpret it as 0x42C80000 as you expect, but rather as 0x0000C842, which would be 0.0.

Reply With Quote
  #8  
Old March 7th, 2010, 06:17 AM
andy101 andy101 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2004
Location: UK
Posts: 196 andy101 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 10 h 57 m 49 sec
Reputation Power: 9
Thanks for the info, yes I agree. This is what I am planing to do:-

Code:
union
{
	int lat_long;
	unsigned short buff[2];
}convert;

unsigned short highWord, lowWord;
int newData = (int)(fEngValue/4.65661287307739E-10);

convert.lat_long = newData;
highWord = convert.buff[1];
lowWord = convert.buff[0];
// Swap the words over (low to high; high to low)
newData = SwapWords(highWord, lowWord);


Now bit 0 of the 32 bit word means 4.65661287307739E-10 and if you multiple by 180 you get units of degrees.

This is were the problem is!

Reply With Quote
  #9  
Old March 8th, 2010, 05:56 AM
Delmar Delmar is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Feb 2010
Posts: 16 Delmar User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 24 m 35 sec
Reputation Power: 0
Thank u

Thanks to all for your sharing.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > Data Type Casting

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap