nRF24 / RF24

OSI Layer 2 driver for nRF24L01 on Arduino & Raspberry Pi/Linux Devices
https://nrf24.github.io/RF24
GNU General Public License v2.0
2.19k stars 1.01k forks source link

NRF24L01+PA+RNA with STM32 #606

Closed mjepronk closed 3 years ago

mjepronk commented 3 years ago

Hi! Thanks for making this library. I have a question, I don't seem to be able to get this library to work with the following setup:

Hardware:

Wiring:

(NRF24 -> STM32)

Software:

The output of radio.printDetails() is:

STATUS           = 0x02 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=1 TX_FULL=0
RX_ADDR_P0-1     = 0xf9f9f9f9f9 0xf1f1f1f1f1
RX_ADDR_P2-5     = 0xf1 0xf1 0xf0 0xf1
TX_ADDR          = 0xf9f9f9f9f9
RX_PW_P0-6       = 0x80 0x80 0x80 0x80 0x80 0x80
EN_AA            = 0x8f
EN_RXADDR        = 0x81
RF_CH            = 0x80
RF_SETUP         = 0xfd
CONFIG           = 0x82
DYNPD/FEATURE    = 0x8f 0x81
Data Rate        = 1MBPS
Model            = nRF24L01
CRC Length       = 8 bits
PA Power         = PA_HIGH

...which actually surprises me, because I set the following in my sketch:


RF24 radio(PB0, PA4);

const byte address[][5] = { 0xF0,0xF0,0xF0,0xF0,0xE1 , 0xF0,0xF0,0xF0,0xF0,0xD2 };

// [snip]

void setup(void)
  // [snip]

  //
  // Setup and configure rf radio
  //
  radio.begin();
  radio.setChannel(0);
  //radio.setPALevel(RF24_PA_LOW);
  radio.setPALevel(RF24_PA_MIN);
  radio.setDataRate(RF24_250KBPS);
  //radio.setAutoAck(0);
  radio.setRetries(5, 15);
  radio.setCRCLength(RF24_CRC_8);
  radio.enableDynamicPayloads();
  radio.printDetails();

// [snip]

Is there an explanation why my settings are ignored? Please let me know if I need to provide more details.

Wires I've checked a dozen times, they seem to be fine...

I'm not sure if it works apart from the wrong printDetails, because I can't get the settings to match with my Raspberry Pi (which uses the Python version of this library, Python 3.7 and pyRF24 v1.3.3). I've noticed that if I connect the same module to the Raspberry Pi / Python, the model is shown as nRF24L01+ instead of nRF24L01.

mjepronk commented 3 years ago

I've noticed that Arduino IDE gives a warning that RF24 library is not supported with the stm32 architecture. But I saw somewhere else that it should work anyaway, am I mistaken?

Avamander commented 3 years ago

But I saw somewhere else that it should work anyaway, am I mistaken?

We have manually whitelisted architectures where we can confirm they're working with the correct setup. stm32 has not yet been fully confirmed as compatible, but it might.

Avamander commented 3 years ago

Is there an explanation why my settings are ignored? Please let me know if I need to provide more details.

The non-zero status seems to indicate communications, but errors in it.

Check these things:

  1. Are wires used very long and/or thin?
  2. Do you have a lot of noise in the environment?
  3. Do the SPI pins lack the required pull-ups or pull-downs?
  4. Is the SPI mode correct? There have been issues with certain boards having different defaults.

If you have a signal analyzer and/or an oscilloscope, comparing a working setup and a broken one will probably reveal the issue rather quickly.

mjepronk commented 3 years ago

Hi Avamander,

Thank you for your fast response.

  1. My wires are about 30cm AliExpress quality...
  2. There is my own Wifi, that's about it
  3. I'm not sure I understand your question
  4. I am not initializing SPI whatsoever, I didn't find any examples that did this. Could you point me to some example code?

Sadly, I do not have a logic analyzer or oscilloscope...

TMRh20 commented 3 years ago

I'm guessing this is another issue related to the SPI_HAS_TRANSACTION detection problem https://github.com/nRF24/RF24/issues/508 and the clock divider is being set incorrectly for STM32 devices

To try the fix see https://github.com/nRF24/RF24/commit/da16f57a1b3d2d1c15628ab1e935e09c6dd06d26

Basically just need to move a few lines of code to the bottom of RF24_config.h

mjepronk commented 3 years ago

OK, I've installed latest master, and it picked up my settings now! Thank you @TMRh20 ! I still have one issue, when I specify my "pipes" (communication addresses as in the pingpair_dyn sketch) as follows:

const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

printDetails prints them in reverse order (notice d2 and e1 are at the beginning of the addresses now):

RX_ADDR_P0-1     = 0xd2f0f0f0f0 0xe1f0f0f0f0

Is this expected?

mjepronk commented 3 years ago

Aah nevermind, the constants should have the ul or UL suffix.

I think this might be a bug in some sample sketches, for example examples/pingpair_dyn/pingpair_dyn.ino...

(And I managed to successfully run pingpair_dyn between the Raspberry Pi and the STM32 now!)

TMRh20 commented 3 years ago

Hmm, not sure about the constants, LL suffix works fine on all Arduino devices I've tested as well as 32-bit devices like RPi, Due, etc, so I would have thought the behaviour would be the same here...

mjepronk commented 3 years ago

@TMRh20 I'm not claiming of knowing better, I just started Arduino programming, so take everything I say with a large grain of salt, but the docs have this to say: https://www.arduino.cc/reference/en/language/variables/constants/integerconstants/#_notes_and_warnings

Since this variable is declared as uint64_t, I think we should use the UL or ul suffix. The LL suffix isn't mentioned at all in the Arduino Reference as far as I see.

At least on STM32 it didn't work correctly without this suffix, I have no other MCU's to test.

bananu7 commented 3 years ago

I just got my blue pill to work with it.

The issue was also due to the SPI transactions not being enabled. I fixed this by adding the RF24 define by hand.

I was using 1.3.5 which PIO installed by default.

TMRh20 commented 3 years ago

@mjepronk I did a little testing with the U&L formatters, and here is what I've found:

  1. The suffix(es) can be combined ie: L == Long (4bytes), LL == LongLong (4bytes + 4bytes)
  2. I ran a test on a few different devices, here are my results:

Code:

Arduino:
  Serial.print("Sizes: ");
  Serial.print(sizeof(5));
  Serial.print(":");
  Serial.print(sizeof(5L));
  Serial.print(":");
  Serial.print(sizeof(5U));
  Serial.print(":");
  Serial.print(sizeof(5UL));
  Serial.print(":");
  Serial.print(sizeof(5LL));
  Serial.print(":");
  Serial.println(sizeof(5ULL));

RPi: printf("Sizes: %d %d %d %d %d %d \n",sizeof(5),sizeof(5L),sizeof(5U),sizeof(5UL),sizeof(5LL),sizeof(5ULL));

Output:

Sizes: 2:4:2:4:8:8 -- Mega 2560 (8-bit)
Sizes: 4:4:4:4:8:8 -- Due (32-bit)
Sizes: 4 4 4 4 8 8 -- RPi (32-bit)

As you can see, the only values that are 64-bits are the ones using the LL and ULL formatters.

Could you run this test on your device and post the results?

TMRh20 commented 3 years ago

Interestingly enough, it looks like the system detects the length of the variable automatically if it exceeds the defaults or the designated formatter. I think this behaviour has changed, since I think I remember testing this all a long time ago with different results.

For example, on Arduino Mega:

  Serial.print("Sizes: ");
  Serial.print(sizeof(0xBBCCDDEEFF));
  Serial.print(":");
  Serial.print(sizeof(0xBBCCDDEEFFL));
  Serial.print(":");
  Serial.print(sizeof(0xBBCCDDEEFFU));

  Serial.print("Sizes2: ");
  Serial.print(sizeof((uint16_t)0xBBCCDDEEFF));
  Serial.print(":");
  Serial.print(sizeof((uint32_t)0xBBCCDDEEFF));
  Serial.print(":");
  Serial.println(sizeof((uint64_t)0xBBCCDDEEFF));

Output:
Sizes: 8:8:8
Sizes2: 2:4:8

As demonstrated here, the L and undesignated formatting does NOT restrict the size of the variables in the Arduino platform, but it will increase them when using a smaller variable.

Again wondering if there is any difference in behaviour on your device?

mjepronk commented 3 years ago

I've run the two code samples, on the STM32F1 (Black Pill) the output is:

Sizes: 4:4:4:4:8:8
Sizes: 8:8:8
Sizes2: 2:4:8
TMRh20 commented 3 years ago

Ok, so that behaviour seems to be consistent. I guess my only suggestion would be to try the example specifying ULL instead of LL. The input variable needs to be 64-bits, even if the address length is shorter than 5-bytes, so last resort would be to specify (uint64_t) for all the variables.

I should also note that this functionality is kind of considered deprecated, as most of the examples now use an array instead of uint64_t variable. RF24 Doc Link

mjepronk commented 3 years ago

I will try next week, as this week I don't have access to my MCU...

TMRh20 commented 3 years ago

@bananu7 Just put out release 1.3.6 to fix this 2 days ago, so it should be available in Arduino Lib manager and PIO now.

mjepronk commented 3 years ago

@TMRh20 I just wanted to report back that using the ULL suffix works fine on the STM32.

Thank you @TMRh20 @Avamander for your help and your work on this library!

TMRh20 commented 3 years ago

Well I'm not sure how or why the byte order is getting re-arranged with LL, or why STM32 is different than everything else so far. The address is basically just fed right into the radio via SPI, byte by byte, so I think the MCU has to be re-ordering the data for some reason.

In any case, I'll make a note of this issue, and see about updating the examples unless this turns out to be a bug or issue with STM platform/mcu.

Thanks for the info & testing.