Connect Pi Pico to Arduino Nano via NRF24L01

I have been trying to connect a Pi Pico and a Arduino Nano using Nrf24l01 modules. For some reason I couldn't get the circuits to talk to each other. in both circuits the Nrf24l01 module initializes properly. additionally I was succesful in connecting two arduino boards (one UNO and one Nano) using the same Nrf24l01 modules. I looked online but couldn't find anyone who had tried doing this before.

for the Nano I am using the Nrf24l01 RadioHead library (the common lib didn't work for me) Here is the code for the Nano:

// nrf24_client.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple messageing client
// with the RH_NRF24 class. RH_NRF24 class does not provide for addressing or
// reliability, so you should only use RH_NRF24 if you do not need the higher
// level messaging abilities.
// It is designed to work with the other example nrf24_server.
// Tested on Uno with Sparkfun NRF25L01 module
// Tested on Anarduino Mini (http://www.anarduino.com/mini/) with RFM73 module
// Tested on Arduino Mega with Sparkfun WRL-00691 NRF25L01 module

#include <SPI.h>
#include <RH_NRF24.h>

//uint8_t address = 0xf0;//f0f0f0e1;
//byte address[] = { 0xf0, 0xf0, 0xf0, 0xf0, 0xe1 };

uint8_t tx_address[] = { 0xe1, 0xf0, 0xf0, 0xf0, 0xf0 };
uint8_t rx_address = 0xd2;

// Singleton instance of the radio driver
RH_NRF24 nrf24;
void setup() 
{
  Serial.begin(9600);
  while (!Serial) 
    ; // wait for serial port to connect. Needed for Leonardo only
  if (!nrf24.init())
    Serial.println("init failed");
  // Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm
  if (!nrf24.setChannel(120))
    Serial.println("setChannel failed");
  if (!nrf24.setRF(RH_NRF24::DataRate250kbps, RH_NRF24::TransmitPower0dBm))
    Serial.println("setRF failed");   

  //setting tx pipe address
  nrf24.setNetworkAddress(tx_address, 5);

  //setting rx pipe address 
  nrf24.setThisAddress(rx_address);
}


void loop()
{
  Serial.println("Sending to nrf24_server");
  // Send a message to nrf24_server
  uint8_t data[] = "A";
  nrf24.send(data, sizeof(data));
  
  nrf24.waitPacketSent();
  /*
  // Now wait for a reply
  uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);

  if (nrf24.waitAvailableTimeout(500))
  { 
    // Should be a reply message for us now   
    if (nrf24.recv(buf, &len))
    {
      Serial.print("got reply: ");
      Serial.println((char*)buf);
    }
    else
    {
      Serial.println("recv failed");
    }
  }
  else
  {
    Serial.println("No reply, is nrf24_server running?");
  }*/
  delay(400);
}

For the Pico I used the micropython nrf24l01.py library. Here is the main.py code:

from nrf24l01 import NRF24L01
from machine import SPI, Pin
from time import sleep
import struct

csn = Pin(14, mode=Pin.OUT, value=1) # Chip Select Not
ce = Pin(17, mode=Pin.OUT, value=0)  # Chip Enable
led = Pin(25, Pin.OUT)               # Onboard LED
spi = SPI(0, baudrate=10_000_000, polarity=0, phase=0, sck=Pin(6), mosi=Pin(7), miso=Pin(4))
payload_size = 4

#send_pipe = b"\xd2\xf0\xf0\xf0\xf0"
#receive_pipe = b"\xe1\xf0\xf0\xf0\xf0"
#tx pipe address
tx_pipe = b"\xd2\xf0\xf0\xf0\xf0"
#rx pipe address
rx_pipe = b"\xe1\xf0\xf0\xf0\xf0"

def setup():
    print("Initialising the nRF24L0+ Module")
    nrf = NRF24L01(spi, csn, ce, channel=46, payload_size=payload_size)
    nrf.open_tx_pipe(tx_pipe)
    nrf.open_rx_pipe(1, rx_pipe)
    nrf.start_listening()
    return nrf

def flash_led(times:int=None):
    ''' Flashed the built in LED the number of times defined in the times parameter '''
    for _ in range(times):
        led.value(1)
        sleep(0.01)
        led.value(0)
        sleep(0.01)

# main code loop
flash_led(10)
nrf = setup()

print("nRF24L01 Listening")
nrf.start_listening()
msg_string = ""

while True:
    msg = ""
    
    # Check for Messages
    if nrf.any():
        print("got somthing!")
        package = nrf.recv()          
        message = struct.unpack("s",package)
        msg = message[0].decode()
        flash_led(1)

        # Check for the new line character
        if (msg == "\n") and (len(msg_string) <= 20):
            print("full message",msg_string, msg)
            msg_string = ""
        else:
            if len(msg_string) <= 20:
                msg_string = msg_string + msg
            else:
                msg_string = ""


I would be very thankfull if someone could help me figure this out.

Thanks!

use proper lib for Nano too

  uint8_t data[] = "A";
  nrf24.send(&data, sizeof(data));

Update:
I managed to get it working!

I found a helpfull thread in the MicroPython Forum (Archive)

I modified Robin2's SimpleTx.ino example for the Arduino Uno (I switched to an Uno because its power is more reliable). (Also I got the common library working.)
Next I modified the micropython code from the forum for the Pi Pico.

I hope you find this helpful!


Here is the code:

arduino_tx.ino

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

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

//setting up nrf24l01 object
RF24 radio(CE_PIN, CSN_PIN);

char dataToSend[10] = "Message 0";
char txNum = '0';

bool rslt = false;

void setup() {
    Serial.begin(9600);

    Serial.println("Arduino TX Starting");

    if (!radio.begin()) {
      Serial.println("Radio not initialized!");
      while (!radio.begin()) {}
    }

    radio.setDataRate( RF24_250KBPS );
    radio.openWritingPipe(pipes[0]);
    radio.openReadingPipe(1,pipes[1]);
    radio.setPALevel(RF24_PA_HIGH);
    radio.setChannel(100);
    radio.powerUp();

    Serial.println("TX Ready...");
}

void loop() {
	  //sending message
    rslt = radio.write( &dataToSend, sizeof(dataToSend) );

    Serial.print("Data Sent - ");
    Serial.print(dataToSend);
    
    if (rslt) {
        Serial.println(" - Acknowledge received");
        updateMessage();
    }
    else {
        Serial.println(" - Tx failed");
    }

    //sleeping for 1 second
    delay(1000);
}

void updateMessage() {
	  //updating message so you can see that new data is beeing sent
    txNum += 1;
    if (txNum > '9') {
        txNum = '0';
    }
    dataToSend[8] = txNum;
}

pico_rx.py

import utime
from machine import Pin, SPI
from nrf24l01 import NRF24L01

#addresses
pipes = (b'\xe1\xf0\xf0\xf0\xf0', b'\xd2\xf0\xf0\xf0\xf0')

#turning on picos built-in LED to indicate that power is on
led = Pin(25, Pin.OUT)
led.value(1)

print('Pico RX Starting')

#setting up nrf24l01 object
spi = SPI(0, sck=Pin(6), mosi=Pin(7), miso=Pin(4))
csn = Pin(14, mode=Pin.OUT, value=1)
ce = Pin(17, mode=Pin.OUT, value=0)
nrf = NRF24L01(spi, csn, ce, channel=100, payload_size=32)

#opening listening pipe
nrf.open_tx_pipe(pipes[1])
nrf.open_rx_pipe(1, pipes[0])
nrf.start_listening()

print('RX Ready. Waiting for packets...')

while True:
    utime.sleep(1)
    
    #checking for a message on the nrf24l01
    if nrf.any():
        print('Received something!:')
        package = nrf.recv()
        msg = package.decode()[0:9]
        print(msg)

Hi there,

I have the exact same issue when sending data from Arduino UNO to a Raspberry Pi Pico, and I found your post here.

My Arduino is sending data, but the the Pico doesn't receive it. I tried to copy and paste your code and applied the same pins, but still Pico doesn't receive anything. Could you have a look at the library I'm using? I suspect I'm not using the same library you were using, thank you.

The nrf24l01 library I'm using: https://github.com/micropython/micropython-lib/blob/v1.21.0/micropython/drivers/radio/nrf24l01/nrf24l01.py

Arduino:
14:58:36.926 -> Data Sent - Message 0 - Tx failed
14:58:37.950 -> Data Sent - Message 0 - Tx failed
14:58:38.978 -> Data Sent - Message 0 - Tx failed
14:58:40.060 -> Data Sent - Message 0 - Tx failed
14:58:41.090 -> Data Sent - Message 0 - Tx failed

Pico:

%Run -c $EDITOR_CONTENT

MPY: soft reboot
Pico RX Starting
RX Ready. Waiting for packets...

Hi @eric20232023!

I am using the same library as you.

You might be having power issues. I'm not an expert, but that seems to be a common issue.

Good luck!

Many thanks for your reply. I was using the UNO's 5v power pinout and will try a dedicated power supply.

@eric20232023 here are some questions that might help:

  1. What were you using to power your arduino?
  2. Can your power source provide enough current?
  3. Are you using an adapter board?
  4. Do you have a capacitor soldered to the module board?
  5. What version of the module are you using? (On-board antenna or external)

Good luck!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.