nRF24 / CircuitPython_nRF24L01

CircuitPython driver library for the nRF24L01 transceiver.
http://circuitpython-nrf24l01.rtfd.io/
MIT License
46 stars 11 forks source link

Compatibility issue to Arduino RF24 ? #26

Closed bitboy85 closed 3 years ago

bitboy85 commented 3 years ago

I'm trying to connect a Pi Pico to an arduino nano using nrf24l01 module.

I'm using the most recent versions of the libraries and i only uploaded the basic example on both devices. So if the arduino is set to the transmitter and the pi to reciever, all packets are lost. The pi recieves nothing. If the pi is transmitter and the arduino reciever, some/most packets shows up, but the ack is missing.

i've just installed a 100nF C on both modules. The arduino one has an additional 10uF attached. This seems to fix the lost packets if the pi sends them. But the other way and ack packets are still not working.

grafik

2bndy5 commented 3 years ago

But the other way and ack packets are still not working.

What type of radio module are you using? Are you using a PA/LNA module?

100nF + 10uF seems small. I usually use 100uF capacitor. Are you using an adapter board for the nRF24 modules?

2bndy5 commented 3 years ago

Did you uncomment the lines for compatibility with the RF24 arduino lib? Each compatible example had a set of lines commented out

bitboy85 commented 3 years ago

If i uncomment the lines, transmitting from the pi to the arduino stops working.

I've added additional 330uF. Makes no difference.

What makes me wonder: I've used those modules with arduino <-> teensy with the nrflite library and it was working without any caps.

I have this power adapter, but i'm not using it. Its the version without antenna.

2bndy5 commented 3 years ago

it was working without any caps

the capacitance used largely depends on the power regulating circuit on the MCU board.

If i uncomment the lines, transmitting from the pi to the arduino stops working.

That doesn't make sense. Those lines are there specifically for this task. Just to be clear, you are running the _simpletest.py on the RPi and the RF24 lib's gettingStarted.ino on the arduino, right?

I'm guessing you made no other alterations to the mentioned examples' code.

bitboy85 commented 3 years ago

If i uncomment the lines, transmitting from the pi to the arduino stops working.

That doesn't make sense. Those lines are there specifically for this task. Just to be clear, you are running the _simpletest.py on the RPi and the RF24 lib's gettingStarted.ino on the arduino, right?

Exactly. I only changed the pins. And because pico pi doesn't support board.spi i used this: https://learn.adafruit.com/getting-started-with-raspberry-pi-pico-circuitpython/pinouts

So, after updateing the CP firmware to 6.2 stable, i've resoldered everything. At least in very rare cases, the pi is able to recieve something. Just for the record, the 3 lines are commented. grafik

AAAND finally after adding another cap on the pi side it seems that receiving is quite stable. transmitting and receiving the ack is still a bit unstable. Mayadding more caps. I've now around 200uF.

Still enabling those 3 lines stops transmitting to work. grafik

2bndy5 commented 3 years ago

OH! you're using the RPi Pico board. Last I tried this lib on my Feather RP2040, I was successful using CircuitPython v6.2.0 (stable) which now ships with a faster version of the adafruit_bus_device.SPIDevice (so you don't need to copy the adafruit_bus_device lib into your "lib" folder when using v6.2.0+). but that was using my dev branch testing.

p.s. we are working on Pico SDK support over at the RF24 repo (nRF24/RF24#727). We have uf2 files uploaded as workflow artifacts on each commit. (you could also give those example a try - but that's bleeding edge stuff)

2bndy5 commented 3 years ago

reposting my advice from another thread:

heads-up: The RT6150B-33GQW used on the pico boards is a switching regulator, so its highly efficient (~0.01 uA consumption) but very noisy; meaning an additional capacitor is more of an unwritten law with switching regulators. Luckily, my Feather RP2040 uses a typical BJT based voltage regulator.

For what its worth I use an adapter board (which regulates the VUSB down to 3V for me).

2bndy5 commented 3 years ago

default SPI pins (according to SDK) are:

#define PICO_DEFAULT_SPI 0 // as in `spi0`
#define PICO_DEFAULT_SPI_SCK_PIN 18
#define PICO_DEFAULT_SPI_TX_PIN 19
#define PICO_DEFAULT_SPI_RX_PIN 16
#define PICO_DEFAULT_SPI_CSN_PIN 17
2bndy5 commented 3 years ago

I can't reproduce this on my Feather RP2040. I had to un-comment the lines to get the _simpletest.py OTA compatible with RF24's gettingStarted.ino example.

board.SPI() works fine on my Feather RP2040. If you can't use board.SPI(), then use

import board
import busio

spi = busio.SPI(clock=board.GP2, MOSI=board.GP3, MISO=board.GP4)

You also have to change the ce & csn pins in the example. did you do that?

from digitalio import DigitalInOut

ce = DigitalInOut(board.GP5)
csn = DigitalInOut(board.GP6)
bitboy85 commented 3 years ago

Sry for late response. I added a 1117 3.3 voltage regulator and a 100uF cap on the pico pi side. I guess without an additional regulator around 400uF might work stable.

But those 3 lines need to be commented out for transmitting to work. Receiving always works.

# change these (digital output) pins accordingly
ce = digitalio.DigitalInOut(board.GP15)
csn = digitalio.DigitalInOut(board.GP13)

# using board.SPI() automatically selects the MCU's
spi = busio.SPI(clock=board.GP10, MOSI=board.GP11, MISO=board.GP12)   # init spi bus object
2bndy5 commented 3 years ago

But those 3 lines need to be commented out for transmitting to work. Receiving always works.

Hmm, that's just not right. Try un-commenting only the dynamic_payloads and payload_size lines (leave the allow_ask_no_ack line commented out). If that helps, then you might have a counterfeit radio. The NO_ACK bit was cloned functionally backwards on the chinese Si24R1 (which is why so many recommend disabling auto-ack all together).

bitboy85 commented 3 years ago

nrf.dynamic_payloads = False is not working. grafik

grafik

2bndy5 commented 3 years ago

Interesting. I'm glad you solved it, but could you post the output of nrf.printDetails(True)?

Preferably, I need to see what dynamic_payloads attribute returns before and after setting the attribute to a new value.

print("BEFORE")
nrf.printDetails()
nrf.dynamic_payloads = False
print("AFTER")
nrf.printDetails()

Alternatively, you can use nrf.set_dynamic_payloads(0) instead of nrf.dynamic_payloads = False call.

2bndy5 commented 3 years ago

The only problem I can see in that function is this line when disabling dynamic_payloads. Try taking out that if self._dyn_pl: line and decrease the indent (once) for the 2 lines after the old if self._dyn_pl: line.

bitboy85 commented 3 years ago

Here is the output

BEFORE
Is a plus variant_________True
Channel___________________76 ~ 2.476 GHz
RF Data Rate______________1 Mbps
RF Power Amplifier________-12 dbm
RF Low Noise Amplifier____Enabled
CRC bytes_________________2
Address length____________5 bytes
TX Payload lengths________4 bytes
Auto retry delay__________1500 microseconds
Auto retry attempts_______3 maximum
Re-use TX FIFO____________False
Packets lost on current channel_____________________0
Retry attempts made for last transmission___________3
IRQ on Data Ready___Enabled    Data Ready___________False
IRQ on Data Fail____Enabled    Data Failed__________False
IRQ on Data Sent____Enabled    Data Sent____________False
TX FIFO full__________False    TX FIFO empty________True
RX FIFO full__________False    RX FIFO empty________True
Ask no ACK_________Disabled    Custom ACK Payload___Disabled
Dynamic Payloads____Enabled    Auto Acknowledgment__Enabled
Primary Mode_____________TX    Power Mode___________Off
AFTER
Is a plus variant_________True
Channel___________________76 ~ 2.476 GHz
RF Data Rate______________1 Mbps
RF Power Amplifier________-12 dbm
RF Low Noise Amplifier____Enabled
CRC bytes_________________2
Address length____________5 bytes
TX Payload lengths________4 bytes
Auto retry delay__________1500 microseconds
Auto retry attempts_______3 maximum
Re-use TX FIFO____________False
Packets lost on current channel_____________________0
Retry attempts made for last transmission___________3
IRQ on Data Ready___Enabled    Data Ready___________False
IRQ on Data Fail____Enabled    Data Failed__________False
IRQ on Data Sent____Enabled    Data Sent____________False
TX FIFO full__________False    TX FIFO empty________True
RX FIFO full__________False    RX FIFO empty________True
Ask no ACK_________Disabled    Custom ACK Payload___Disabled
Dynamic Payloads___Disabled    Auto Acknowledgment__Enabled
Primary Mode_____________TX    Power Mode___________Off

using nrf.set_dynamic_payloads(0) also breaks transmitting.

Patching rf24.py makes no difference.

Is there anything special to have dynamic_payload disabled?

2bndy5 commented 3 years ago

if it works when dynamic_payloads are enabled, then the other program must have it enabled also. Dynamic payloads feature isn't meant to work with static payloads.

Is there anything special to have dynamic_payload disabled?

The fix in that commit I tagged you on should have removed any doubt that the proper registers' bits are set.

print("BEFORE: 0x1c={} 0x1d={}".format(
    hex(nrf._reg_read(0x1C)),  # register for feature in RX
    hex(nrf._reg_read(0x1D))  # register for feature in TX
))
nrf.dynamic_payloads = False
print("AFTER: 0x1c={} 0x1d={}".format(
    hex(nrf._reg_read(0x1C)),  # register for feature in RX
    hex(nrf._reg_read(0x1D))  # register for feature in TX
))
greenyleaf commented 11 months ago

Hi. Read the above replies. And in the example code, there are 3 lines said to uncomment for compatibility with Arduino rf24, one of which is only for the Chinese altered board. The Python example code enables the dynamic payload feature on default, and the Arduino end disables that. Somewhere in the doc said that the received payload has to be all read, or the communication will fail, it must be the cause.

2bndy5 commented 11 months ago

there are 3 lines said to uncomment for compatibility with Arduino rf24, one of which is only for the Chinese altered board.

Technically, the allow_ask_no_ack has undesirable effects on Si24R1 clones. allow_ask_no_ack in CircuitPython is equivalent to Arduino RF24::enable_dynamic_ack which is disabled in Arduino by default.

Somewhere in the doc said that the received payload has to be all read, or the communication will fail, it must be the cause.

Not sure what you are referring to. I don't really know what this means.

Basically the setting must match on both ends. If using Arduino RF24 defaults, then disable dynamic_payloads on CircuitPython end. The payload_size must also match on both ends when dynamic_payloads is disabled.