View previous topic :: View next topic |
Author |
Message |
cvargcal
Joined: 17 Feb 2015 Posts: 134
|
Send GPS data as hex |
Posted: Sun Mar 24, 2019 2:12 am |
|
|
Hi, I have this problem:
I need send gps for example 6.1639,-74.5858 by lora
I send that way
Code: | float lat=6.1639;
float log=-74.5858;
port=45;
id=01;
fprintf(lora,"mac tx cnf %u %x%lx%lx\r\n",port,id,Lat,Log); delay_ms(1000); // Id,Lat,Log |
in server:
01 ac 3d 45 81 d2 2b 97 85
How I send lat and log? maybe one idea is send part int and part float but and the sign? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9215 Location: Greensville,Ontario
|
|
Posted: Sun Mar 24, 2019 5:04 am |
|
|
I'd try...
fprintf(lora, "lat=%f8.5",lat);
it's in the manual...
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Sun Mar 24, 2019 6:52 am |
|
|
I'd say send as a signed integer.
So if you have :
float lat=6.1639;
float log=-74.5858;
Then multiply by 1000000, and store as a signed int32. This can then be sent
as hex.
You'd actually be sending a simple integer value of microdegrees. |
|
|
cvargcal
Joined: 17 Feb 2015 Posts: 134
|
|
Posted: Sun Mar 24, 2019 8:09 am |
|
|
Thans for the answer,
I can not use %f, because the module lora not let.
The data should be sen as hex.
I will try send a int32.
thanks |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Sun Mar 24, 2019 8:17 am |
|
|
I think cvargcal might be talking about how he needs to send float in binary representation...
Maybe something like this?
Code: | union Data {
int8 i8[4];
float f;
} data; |
Then,
Code: | data.f = Lat;
for (int i = 0; i < 4; ++i)
{
fprintf(lora, "%x", data.i8[i]);
}
|
|
|
|
cvargcal
Joined: 17 Feb 2015 Posts: 134
|
|
Posted: Sun Mar 24, 2019 8:33 am |
|
|
dluu13 wrote: | I think cvargcal might be talking about how he needs to send float in binary representation...
Maybe something like this?
Code: | union Data {
int8 i8[4];
float f;
} data; |
Then,
Code: | data.f = Lat;
for (int i = 0; i < 4; ++i)
{
fprintf(lora, "%x", data.i8[i]);
}
|
|
yes just that, I tried but, how I send the negative value? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Sun Mar 24, 2019 8:34 am |
|
|
You don't. You are then sending raw hex. The numbers you are sending _encode_ the negative value, but there is no 'negative' there. Just four
bytes 00 to FF.
The only issue you may have is that this is in Microchip float format, not
IEEE float format. If you loaded these bytes into (for example) a PC, they
would need conversion either in the PIC or the PC into IEEE format.
There is an include file with the compiler to do this conversion. |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Sun Mar 24, 2019 8:37 am |
|
|
cvargcal wrote: | dluu13 wrote: | I think cvargcal might be talking about how he needs to send float in binary representation...
Maybe something like this?
Code: | union Data {
int8 i8[4];
float f;
} data; |
Then,
Code: | data.f = Lat;
for (int i = 0; i < 4; ++i)
{
fprintf(lora, "%c", data.i8[i]);
}
|
|
yes just that, I tried but, how I send the negative value? |
I just noticed a mistake... I think you should send %c instead of %x |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Sun Mar 24, 2019 9:59 am |
|
|
No, he wants to send in hex.
Hwever %02x would be better, since this then ensures that eight hex
characters will be sent no matter what the numbers actually are. |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Sun Mar 24, 2019 10:10 am |
|
|
Ohh, in that case stay with %x.
Check out this site. I used a similar site to get a basic understanding of how float works. I still don't get it, but at least there's a basic impression...
http://www.binaryconvert.com/convert_float.html |
|
|
cvargcal
Joined: 17 Feb 2015 Posts: 134
|
|
Posted: Sun Mar 24, 2019 12:09 pm |
|
|
Thank for the answer.
I get the solution. I share the code.
Code: | int32 f_PICtoIEEE(float f)
{
int16 c[2];
memcpy((int8*)c , ((int8*)&f)+3, 1);
memcpy((int8*)c+1, ((int8*)&f)+2, 1);
memcpy((int8*)c+2, ((int8*)&f)+1, 1);
memcpy((int8*)c+3, ((int8*)&f) , 1);
c[1] = ((c[1] >> 1) & 0x7F80) + (c[1] & 0x7F) + ((c[1] & 0x80) << 8);
return ((int32)c[1] << 16) | c[0];
}
float f_IEEEtoPIC(int32 f)
{
float ret;
int16 temp;
memcpy(&temp, ((int8*)&f)+2, 2);
temp = ((temp << 1) & 0xFF00) + (temp & 0xFF);
if(bit_test(f, 31)) // Test the sign bit
temp |= 0x0080;
else
temp &= 0xFF7F;
memcpy(((int8*)&ret)+3, ((int8*)&f) , 1);
memcpy(((int8*)&ret)+2, ((int8*)&f)+1 , 1);
memcpy(((int8*)&ret)+1, ((int8*)&temp) , 1);
memcpy(((int8*)&ret) , ((int8*)&temp)+1, 1);
return ret;
} |
Code: | void main() {
while(1) {
fprintf( lora, "Example test..\n\r" );
float32 f=0.1234;
int32 ieeeValue;
float32 myFloat;
ieeeValue = f_PICtoIEEE(f);
myFloat = f_IEEEtoPIC(ieeeValue);
fprintf( lora, "Float: %0.4f\n\r", myFloat );
fprintf( lora, "HEX IEEE: %LX\n\r", ieeeValue );
fprintf( lora, "\n\r\n\r GPS..\n\r\n\r" );
float32 lat=6.3456;
float32 log=-75.5666;
int32 lat_ieee;
int32 log_ieee;
// Values IEEE
lat_ieee = f_PICtoIEEE( lat);
log_ieee = f_PICtoIEEE( log);
fprintf( lora, "HEX IEEE: %LX\n\r", lat_ieee ); // 40CB0F28
fprintf( lora, "HEX IEEE: %LX\n\r", log_ieee ); // C2972219
break; //
}
} |
Here can check the result
https://babbage.cs.qc.cuny.edu/ieee-754.old/32bit.html
https://www.h-schmidt.net/FloatConverter/IEEE754.html
http://www.ignogantes.net/envio-de-datos-en-punto-flotante-desde-el-pic-al-computador-y-viceversa/
Out
Quote: | Example test..
Float: 0.1234
HEX IEEE: 3DFCB924
GPS..
HEX IEEE: 40CB0F28
HEX IEEE: C2972219 |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Sun Mar 24, 2019 12:51 pm |
|
|
Good.
I thought the need to switch to IEEE, would be the primary part of the
problem. |
|
|
|