Page 1 of 1

RF24 stm32<>arduino problems

Posted: Mon Jul 10, 2017 4:14 am
by bdbell
I have a wireless RF24 network of sensors and relays for home automation and environmental information from around my house. This system has been working well for years...until I recently upgraded my outdoor setup with a PM 2.5-10 laser sensor. The problem I am having is that I can no longer pass float values between the arduino sensor node and the base unit - which has a STM32. I am sure that the problem really is in recent changes to Arduino core and not STM32 - because the base unit is still receiving float values properly from the sensors that I have not modified - only the outdoor and base unit have had new code uploaded. I have tried to go back to previous versions with no luck - so I am a bit stumped. The RF24 (and RF24Network) libs I am using I know have been working well for years (attached). I can pass floats between 2 arduino's or 2 stm32's with the same libs...but not stm32<>arduino. And I have tried all RF24 libraries mentioned in these forums, some not working, others same results. This all worked fine just a few weeks ago.... :?

Re: RF24 stm32<>arduino problems

Posted: Mon Jul 10, 2017 9:24 am
by stevestrong
You should check the data which is transmitted over rf24.
Can you pass uint8/uint16 values?
Endianess checked?

Re: RF24 stm32<>arduino problems

Posted: Mon Jul 10, 2017 2:10 pm
by bdbell
I have checked the data received, and when using stm32>arduino or arduino>stm32 I get garbage data from any other data type I have tried other than uint16_t or uint32_t - something like this;


the first 3 values are correct - temperature, battery, humidity - but then the pressure value which should be ~1006.xx there - it seems to also screw up the values after that. These are not actual values using uint16_t/uint32_t - just an example.

I have been able to get this working - by using all the uint16_t values first, and the last value of the pressure - uint32_t - so my payload is like this;

struct payload_t
uint16_t nodenum;
uint16_t whttodo;
uint16_t tempxR;
uint16_t battxR;
uint16_t humxR;
uint16_t lightxR;
uint16_t airqxAR;
uint16_t airqxBR;
uint32_t pressxR;

this seems to be working and giving me proper values, but if I move the uint32_t value up in the list it screws up all the values after it so obviously there is still something wrong with the amount of data being sent. I have already spent too many days screwing with this so I will live with it for now - but I sure wish I could figure out why float values are no longer working....

Re: RF24 stm32<>arduino problems

Posted: Mon Jul 10, 2017 2:22 pm
by stevestrong
Possible issue can be caused by using memcpy/strcpy or multi-byte write/print processes on structures as a whole.

The size of the structure in the memory is not the same for AVR (8 bit aligned memory) and STM32 (mostly 32 bit aligned memory).
Alignment means, that 2 byte variable must be placed on memory addresses which can be divided by 2 (last bit = 0), 4 byte wide variables must be placed on memory addresses which can be divided by 4 (last two bits = 0).
On STM32, when the members of a structure are not all word (4 bytes/ 32 bit) aligned, then dummy (padding) bytes are introduced between two consecutive structure members in the memory by the linker.
In this case the additional bytes can cause the misinterpretation on the other side when using different architecture on Rx and Tx side.

In your example, moving the uint32_t member up in the second place means that after the first uint16_t member there will be 2 dummy bytes inserted in the memory (to fill up the space till the next 32 bit aligned address because the 32 bit wide variable need an address dividable by 4). That is why it will not work anymore if you send the whole structure in multi-byte manner. However, if the second member is also a 16 bit variable, then this would fit fine into the 2 byte space till the next 32 bit aligned address.

The whole thing would work regardless of alignment if you send each structure member separately, because then the linker takes each member from its correct memory location.

You can check the misalignment by monitoring the sizeof(payload_t). This will not always give you the expected result (sum of individual element sizes).

Re: RF24 stm32<>arduino problems

Posted: Mon Jul 10, 2017 5:13 pm
by zmemw16
isn't there a payload size limit 32bytes?
i see his is inside that, but there might be an overhead added on?

also float is a 32bit, unsigned32 covers that, and then a cast to float should work ?