Hi,
I'm trying to use 2 Arduino Nano RP2040 Connect boards to transmit and receive data wirelessly with NRF24L01+ chips.
Arduino: link
NRF24L01+ chips: link
I'm using this CircuitPython library, I drag the "circuitpython_nrf24l01" folder onto the root of my CIRCUITPY drive. My code.py file is roughly the library's "examples/nrf24l01_simple_test.py" (hardcoding if I'm using it in transmit or receive mode)...
"""
Simple example of using the RF24 class.
"""
import time
import struct
import board
import digitalio
# if running this on a ATSAMD21 M0 based board
# from circuitpython_nrf24l01.rf24_lite import RF24
from circuitpython_nrf24l01.rf24 import RF24
# change these (digital output) pins accordingly
ce = digitalio.DigitalInOut(board.D4)
csn = digitalio.DigitalInOut(board.D5)
# using board.SPI() automatically selects the MCU's
# available SPI pins, board.SCK, board.MOSI, board.MISO
spi = board.SPI() # init spi bus object
# we'll be using the dynamic payload size feature (enabled by default)
# initialize the nRF24L01 on the spi bus object
nrf = RF24(spi, csn, ce)
# set the Power Amplifier level to -12 dBm since this test example is
# usually run with nRF24L01 transceivers in close proximity
nrf.pa_level = -12
# addresses needs to be in a buffer protocol object (bytearray)
address = [b"1Node", b"2Node"]
# to use different addresses on a pair of radios, we need a variable to
# uniquely identify which address this radio will use to transmit
# 0 uses address[0] to transmit, 1 uses address[1] to transmit
# radio_number = bool(
# int(input("Which radio is this? Enter '0' or '1'. Defaults to '0' ") or 0)
# )
radio_number = 0
# set TX address of RX node into the TX pipe
nrf.open_tx_pipe(address[radio_number]) # always uses pipe 0
# set RX address of TX node into an RX pipe
nrf.open_rx_pipe(1, address[not radio_number]) # using pipe 1
# using the python keyword global is bad practice. Instead we'll use a 1 item
# list to store our float number for the payloads sent
payload = [0.0]
# uncomment the following 3 lines for compatibility with TMRh20 library
# nrf.allow_ask_no_ack = False
# nrf.dynamic_payloads = False
# nrf.payload_length = 4
def transmit_data(count=1000):
"""Transmits an incrementing integer every second"""
nrf.listen = False # ensures the nRF24L01 is in TX mode
while count:
# use struct.pack to packetize your data
# into a usable payload
buffer = struct.pack("<f", payload[0])
# "<f" means a single little endian (4 byte) float value.
start_timer = time.monotonic_ns() # start timer
result = nrf.send(buffer)
end_timer = time.monotonic_ns() # end timer
if not result:
print("send() failed or timed out")
else:
print(
"Transmission successful! Time to Transmit: "
"{} us. Sent: {}".format(
(end_timer - start_timer) / 1000, payload[0]
)
)
payload[0] += 0.01
time.sleep(1)
count -= 1
def receive_data(timeout=1000):
"""Polls the radio and prints the received value. This method expires
after 6 seconds of no received transmission"""
nrf.listen = True # put radio into RX mode and power up
start = time.monotonic()
while (time.monotonic() - start) < timeout:
if nrf.available():
# grab information about the received payload
payload_size, pipe_number = (nrf.any(), nrf.pipe)
# fetch 1 payload from RX FIFO
buffer = nrf.read() # also clears nrf.irq_dr status flag
# expecting a little endian float, thus the format string "<f"
# buffer[:4] truncates padded 0s if dynamic payloads are disabled
payload[0] = struct.unpack("<f", buffer[:4])[0]
# print details about the received packet
print(
"Received {} bytes on pipe {}: {}".format(
payload_size, pipe_number, payload[0]
)
)
start = time.monotonic()
# recommended behavior is to keep in TX mode while idle
nrf.listen = False # put the nRF24L01 is in TX mode
if __name__ == "__main__":
try:
transmit_data()
# receive_data()
except KeyboardInterrupt:
print(" Keyboard Interrupt detected. Powering down radio...")
nrf.power = False
else:
print(" Run slave() on receiver\n Run master() on transmitter")
The transmitter keeps giving the error "send() failed or timed out"
My debugging....
-
I've tested my RF24 chips on regular Arduino Uno R3 boards, and they talk just fine using the official RF24 library
-
I've attached the Fritzing diagram for the regular Arduino Uno boards
-
here's the Arduino Uno R3 transmitter's code:
/*
* Arduino Wireless Communication Tutorial
* Example 1 - Transmitter Code
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN
const byte address[6] = "00001";
void setup() {
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
}
void loop() {
const char text[] = "Hello World";
radio.write(&text, sizeof(text));
delay(1000);
}
- here's the Arduino Uno R3 receiver's code:
/*
* Arduino Wireless Communication Tutorial
* Example 1 - Receiver Code
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN
const byte address[6] = "00001";
void setup() {
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
}
void loop() {
if (radio.available()) {
char text[32] = "";
radio.read(&text, sizeof(text));
Serial.println(text);
}
}
I'd really appreciate any help in getting this to work on my new Arduino Nano RP2040 Connect boards!! I really want to make them into remote controllers for my robotics project!
Thank you,
Ryan
Fritzing for Arduino Uno:
Fritzing for Arduino Nano RP2040 Connect: