Apologies if this information is available elsewhere. I had look though the forum and docs but did not see it anywhere.
Does the MSB or LSB come first in data types on the Photon?
Apologies if this information is available elsewhere. I had look though the forum and docs but did not see it anywhere.
Does the MSB or LSB come first in data types on the Photon?
The STM32 family which are used on the Core and the Photon are little endian.
Thanks that is good to know.
Now onto the real question I’m trying to interface with a sensor that is big endian (MSB/LSB) but I am having some trouble reading the calibration and sensor data correctly.
I have been reading bytes like this. It works because endianness does not matter with a single byte.
float common[2];
byte buffer[8];
readEepromData(AdrGradScale, buffer, sizeof(byte));
_gradScale = buffer[0];
Serial.printf("_gradScale: %d\r\n", _gradScale);
I have been reading floats like this, it works but I don’t think it should because the endianness is different.
readEepromData(AdrPixCMin, buffer, sizeof(float) * 2);
memcpy((byte*)&common, buffer, sizeof(float) * 2);
float pixCMin = common[0];
float pixCMax = common[1];
Serial.printf("pixCMin: %f\r\n", pixCMin);
Serial.printf("pixCMax: %f\r\n", pixCMax);
I have been trying to read signed and unsigned int16 like this. It does not work because the endianness is different.
for(uint16_t i = 0; i < Pixel; ++i)
{
readEepromData(AdrTh1 + i * 2, buffer, sizeof(int16_t));
memcpy((byte*)&_thGrad[i], buffer, sizeof(int16_t));
Serial.printf("_thGrad: %d\r\n", _thGrad[i]);
}
So instead I tried this. It works but I was wondering if there is a better way to convert from MSB/LSB to LSB/MSB.
for(uint16_t i = 0; i < Pixel; ++i)
{
readEepromData(AdrTh1 + i * 2, buffer, sizeof(int16_t));
_thGrad[i] = buffer[1] | (buffer[0] << 8);
Serial.printf("_thGrad: %d\r\n", _thGrad[i]);
}
Have I understood endianess correctly? Any ideas why float works but int16 does not?
Thanks
I try to use unions for cleaner code, but it may add confusion. Here’s one I know works for Arduino.
union ip4
{
struct
{
uint8_t b[4];
} b;
struct
{
uint16_t w[2];
} w;
uint32_t l;
};
The idea is to access by long ( ip4.l ) or byte ( ip4.b.b[3] ) and let the compiler do the direct byte addressing rather than bit shifting. Most compilers will do the endien as well. So b[0] is the LSB but w[0] can be tricky. If I’m not mistaken, they’re in low/high order but need to be byte swapped in a conversion. You could set one up with 0x12345678 and print all the variations to make sure.
OK thanks, my understanding of using Union for this is that its not strictly allowed/supported. I will give it a try…
I also got in touch with the sensor supplier as its such a new sensor and there is always a chance that the data sheet MSB/LSB notation is incorrect.
I sure hope it’s supported. I think I’m completely wrong though. I used to do a lot of conversions, and recall needing macros for endien order.
Just a note about the union described. The use of structures in the unions are unnecessary. The 3 arrays below will exist in the same memory (aka &b[0]==&i[0]==&l[0]
and &b[2]==&i[1]
).
union Long2Int4Byte {
uint8_t b[4];
uint16_t i[2];
uint32_t l[1];
};