This tutorial will focus on Arduino-Arduino communication through the serial ports. And then print to the Serial Monitor what it received so that the user can check it. Be manipulated by splitting strings or getting floats from the character arrays.
Active2 months ago
I'm trying to save GPS coordinates to an EEPROM.
In this example I feed it the latitude of 56060066 as the argument float x
I'm expecting to receive the following four bytes from the serial print:
Instead I'm getting these:
I've tried changing all sorts of parameters, but can't seem to find the problem. Can anyone spot the issue?
blargblarg
4 Answers
If you were to enable the display of warnings you would most likely see it complain about 'dereferencing type-punned pointer will break strict-aliasing rules' which is what you are doing here.
Basically you are trying to cast an array of four 8-bit values which can have any alignment they like (byte alignment) to a 32-bit float value which needs 4-byte alignment. And the two just don't mesh.
Instead you need to work the other way around - cast a type that has smaller alignment requirements over the type that has larger requirements.
So instead of getting 4 bytes and trying to fill them as a float you get a float and read it as 4 bytes:
Then you can access b[0] to b[3] quite happily.
Another way to do it is with a union:
Also, in your code, you only allocated enough room for 3 bytes, not 4...
Majenko♦Majenko74.9k44 gold badges3939 silver badges8585 bronze badges
You are getting exactly what you said you want. 4 bytes representing the number in float format.
What you are expecting to get, is 4 bytes representing the number in big-endian integer format.
Using Majenkos solution for casting, you need to change the types and reverse the
I also used
gre_gorgre_gorfor
loop for big-endinaness.I also used
int32_t
because the size of the int
is 16-bit (2-byte) on the Arduino Uno (and other ATMega based boards) and on the Arduino Due it's 32-bit (4-byte). Its better to define the exact int
in this case.1,52944 gold badges1414 silver badges2626 bronze badges
This mucking around with casts and arrays is far too complex.
See: Reading and Writing Data Structures to EEPROM
The library EEPROMAnything.h will accomplish this.
EEPROMAnything.h
The library just consists of this file. Save into your 'libraries' folder under the folder name
EEPROMAnything
.Example code
Output from above
Note you don't get exactly the same number back. This is because of the precision of 4-bytes floats.
After re-reading the question I see you are using I2C EEPROM. That changes the answer a bit, but you can see an adaptation of that library for I2C here. The general idea is the same though.
i2c_eeprom_write_byte(0x57, addr, myFloat.bytes[i]); // Write byte to EEPROM
Your code seems to be writing all of the bytes to the same address, I don't know how that could work.
Nick Gammon♦Nick Gammon29.3k88 gold badges4949 silver badges104104 bronze badges
![Array Array](http://www.martyncurrey.com/wp-content/uploads/2018/05/Arduino_Serial_001.jpg)
72122 gold badges44 silver badges1919 bronze badges
Nisit WattanasriNisit Wattanasri