Is there a way to convert a Float to 32 bits/4 bytes and back again?

Hi Guys,

I was wondering if it is possible to convert a float to 4 bytes AK 32 bits.
I need to divide it in into 8 bits chunks to use if for other purposes.

Now, I always thought that I could mask it off with an "&" to grab the needed bits, but it seems as if the 32 bits bytes are not actually 32 bits.
I mean, If I print the float on the serial monitor, I do not get the expected 32 bits

Serial.print ( VAR, BIN);
(Nore if I print it as HEX, for that matter)

I guess it might have something to do with the float, not being actually 32 bits... Things I do not understand quite.
Then again... I tried it with "double" but that seems to react similar.

You can do it with pointers. What are you trying to do?

You can look at the whole thread but, the relevant part starts here.

memcpy

void setup() {
Serial.begin(9600);
float x=0.1;
unsigned char b[4]={0};
memcpy(b,&x,4);
for(int i=0; i<4; i++)
Serial.println(b[i],BIN);
}

As mentioned you can use pointers to do what you want, like this:

float f;
uint8_t *ptrToFloat;

ptrToFloat = (uint8_t *)&f;

ptrToFloat[0] is now the first byte, ptrToFloat[1], ptrToFloat[2] and ptrToFloat[3] the others.

or you can memcpy() the float into a 4 byte buffer and work with the copy.

float f;
uint8_t data[4];

memcpy(data, &f, sizeof(data));

However, the bigger question is why do you think you need to do thi? I (we?) suspect you may be trying to solve a problem the wrong way.

Help is appreciated, Guys...
I have an altitude sensor that gives me a nice value as a float.
I want to register the height and flight trajectory of a missile so it takes quite a few measurement points.
The data is to be saved into an External EEPROM which only accepts 8 bits of data.
So my goal is to divide the float into 4 8 bit chunks and to save those 4 bytes.
Eventually, I can retrieve that data and convert it back to a Float once again and plot the flight (Height) trajectory.
I've looked into EEPROM.put and -get, but those options do not seem to work on external EEPROMs.

[edit]
I've visited the mentioned link and It seems I wasn't far off.

      byte data[4];
        data[0] = phrase[j] >> 8;
        data[1] = phrase[j] >> 16;
        data[2] = phrase[j] >> 24;

I had something similar, but I started off with a "Double", but the shifts were not accepted.
If I'm correct, the byte data[4] is an array of 4 bytes?

I’d be inclined to store raw data on the flight device, and do all the processing afterwards.

I’ve looked into EEPROM.put and -get, but those options do not seem to work on external EEPROMs.

But they could be made to.

marco_c:
As mentioned you can use pointers to do what you want, like this:

Although popular, this is not valid C++. ‘Type-punning’ is undefined behavior in C++, and using it means that your program can end up doing just about anything, ranging from working exactly the way you expected it to, all the way to having large sections of code just thrown away by the compiler, or just crashing randomly.

This kind of pointer conversion is the same as using ‘reinterpret_cast’ in C++, and there are many rules about how it can be used:
https://en.cppreference.com/w/cpp/language/reinterpret_cast

The actual pointer conversion is legal, but referencing the target object afterwards is NOT.

Use memcpy instead.

If it is for an external eeprom, you can try this library: GitHub - sparkfun/SparkFun_External_EEPROM_Arduino_Library: An Arduino library for the easy control of external I2C EEPROMs.

It supports get() and put() which allows direct storage of various data types (but probably excluding String).

If you collect several data items per measurement: x coordinates, y coordinates, altitude etc., maybe define a struct and write to the eeprom in a single operation.

marco_c:
or you can memcpy() the float into a 4 byte buffer and work with the copy.

float f;

uint8_t data[4];

memcpy(data, &f, sizeof(data));

That was a tip I needed.
I have a short list of routines that writes variables to a header array\buffer that is part of a LoRa payload to be sent.
To write a uint32_t to the header buffer I was doing this;

void arrayWriteuint32(uint32_t buffdata)
{
  uint8_t index, val;
  union
  {
    uint8_t b[4];
    uint32_t f;
  } data;
  data.f = buffdata;
  for (index = 0; index < 4; index++)
  {
    val = data.b[index];
    _arrayaddress[_arraylcn++] = val;                                      //write the data
  }
}

Where _arrayaddress is a pointer to the header buffer and _arraylcn is the relative position in that buffer. It worked.
I reduced the write to;

void arrayWriteuint32(uint32_t tempdata)
{
  memcpy ((_arrayaddress + _arraylcn), &tempdata, 4);
  _arraylcn = _arraylcn + 4;  
}

Which also appears to work.

TheMemberFormerlyKnownAsAWOL:
I'd be inclined to store raw data on the flight device, and do all the processing afterwards.

But the raw data received from the BMP180 is a Float value, therefore I need to stash that 32 bits of data into the EEPROM. :wink:

6v6gt:
If it is for an external eeprom, you can try this library: GitHub - sparkfun/SparkFun_External_EEPROM_Arduino_Library: An Arduino library for the easy control of external I2C EEPROMs.

It supports get() and put() which allows direct storage of various data types (but probably excluding String).

If you collect several data items per measurement: x coordinates, y coordinates, altitude etc., maybe define a struct and write to the eeprom in a single operation.

Nice one! I'll look into that!
Also, a nice feature to register the coordinates into the EEPROM, but If everything goes according to plan, the X and Y coordinates will not change. It would mean I've got a bigger problem of a rocket, going rogue. :o

@Srnet,
I'm not that much into arrays yet. But I will look into your solution for your mentioned problem.
Maybe it helps me out somewhat.

But the raw data received from the BMP180 is a Float value

No.

I HAD ANOTHER TOPIC RUNNING, WHICH SLOWLY EVOLVED TO THE SAME DISCUSSION. I REDIRECTED THAT ONE TO THIS ONE.

OK... I have a 24LC256 wired up by i2c which works. I have loaded quite a few sketch examples successfully, though they only contained byte-sized variables.
And the thing is I need to write and read Floats, which contains 4 bytes.

So one tipped me for this site:
https://learn.sparkfun.com/tutorials/reading-and-writing-serial-eeproms?_ga=2.209849238.2085324980.1612820786-1668522854.1596373743

I guessed this would work out fine, but I could not get it to work.

TheMemberFormerlyKnownAsAWOL:
No.

I still had to comment on this one. :slight_smile:
TMFKAA, I had to think that one over. I have 2 libraries for the BMP180 pressure measuring device, but they both give data back in Float size.
Of course, there might be ways to fetch the data from the BMP, but that is way out of my league.
So I have to stick to those floats to be stashed into that EEPROM in a way I can retrieve it later.

Also reply #7.

I just had a look at the BMP280’s datasheet (it’s obsolete, BTW, and not recommended for new builds), and all the information for temperature and pressure (apart from the fixed device calibration data) is read out from addresses 0xf7 to 0xfc, or just six bytes, so two bytes per reading fewer than if you stored the pressure and temperature results as floats, and there’s no processing overhead - you just hose 'em out of the sensor, and into the log memory

If you go for the BM280, you get raw temperature, pressure and humidity in just eight bytes.

Thank you so much for this info, TMFKAA...
I barely understand all the regular Arduino tasks, so I had to stick to the libraries that supposedly do things for me.
But yeah... If they'd make it harder to comprehend, digging into the device itself is not a bad suggestion.
Understanding all might be the next obstacle.

I'll look into the datasheet of the BPM180 (you mentioned 280, being obsolete. I guess that was an error?)

Sorry, typo, that was supposed to read “If you go for the BME280, you get raw temperature, pressure and humidity in just eight bytes”.

BMP180 is sooo last decade.

oh yeah...
Those things explode after some period of time and they are completely useless as soon as something new arives. >:(

I'm certain I'm not diving into the base of some device or sensor if there are library's available.
I get a float sized number and I'll try to stick that into my EEPROM.
Some help is appriciated. But there is no need to learn the French language if I'm only in France for the holydays.

…but knowing the basics makes the whole experience so much better, and who knows, you may learn something new.