NRF24L01, Pi Pico & Pro Micro

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
Post Reply
OrangeAndApples
Posts: 3
Joined: Sat Mar 06, 2021 11:21 pm

NRF24L01, Pi Pico & Pro Micro

Post by OrangeAndApples » Sun Mar 07, 2021 10:04 am

Hi,

I've been trying to get a Pro Micro and Pi Pico to communicate over radio using the NF24L01 (nrf) modules. Trouble is that the Pico reciever refuses to acknowledge anything has been sent. I was getting OS error with Micropython one, although that was just simply incorrect pins, fixing that cleared up any issues. Other than that the Pro Micro seemed to return good values for radio.printDetails().
Likely issue was pipes but I think I got my head around it, AAAAA = \x41\x41\x41\x41\x41(?)

Any ideas? Much appreciated.

MicroPython (Pico), RX:

Code: Select all

pipe = (b"\x41\x41\x41\x41\x41") # 'AAAAA' on the ardinuo

cfg = {"spi": 0, "miso": 4, "mosi": 7, "sck": 6, "csn": 0, "ce": 1}
csn = Pin(cfg["csn"], mode=Pin.OUT, value=1)
ce = Pin(cfg["ce"], mode=Pin.OUT, value=0)

def rx():    
    nrf = NRF24L01(SPI(cfg["spi"]), csn, ce, channel = 100, payload_size=32)

    nrf.open_rx_pipe(0, pipe)
    nrf.start_listening()

    print('readSensorLoop, waiting for packets... (ctrl-C to stop)')

    while True:
        utime.sleep(0.05)
        if nrf.any():
            print('received something!!')

rx()
Arduino (Pro Micro) TX

Code: Select all

//create an RF24 object
RF24 radio(8, 7); //CE, CSN pins
const byte address[5] = {'A','A','A','A','A'}; //5 byte address (40 bit hex values) (0-9..A-F) e.g. A == 0x41 or \x41

void setup()
{
  Serial.begin(19200); //This pipes to the serial monitor
  Serial.setTimeout(0.2); //Timeout if readUntil doesn't find escape character.
  radio.begin(); 
  radio.setChannel(100);
  radio.setPayloadSize(32);
  radio.setRetries(15,15);
  radio.openWritingPipe(address); //set the writing (pipe) address
  radio.stopListening(); //Set module as transmitter

}

void loop()
{

  //TRANSMIT
  serialIN = "THIS BETTER WORK";
  serialIN.toCharArray(txOUT,16);    
  RXLED1;
  radio.write(txOUT, sizeof(txOUT)); //Sends PPP,RRR,YYY,TTT text
  RXLED0;
  delay(1000);
}

OrangeAndApples
Posts: 3
Joined: Sat Mar 06, 2021 11:21 pm

Re: NRF24L01, Pi Pico & Pro Micro

Post by OrangeAndApples » Sun Mar 07, 2021 7:46 pm

I'm going to beat you all to the answer here... it was the data rate.

Things to check when using NRF, on any board.
- Channel(Freq)
- Address/Pipe
- Data rate

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: NRF24L01, Pi Pico & Pro Micro

Post by pythoncoder » Mon Mar 08, 2021 8:42 am

Given that you chose a symmetrical value for the Pipe data, I guess you've already sussed out that Arduino and MicroPython are big-endian and little-endian respectively.
Peter Hinch
Index to my micropython libraries.

OrangeAndApples
Posts: 3
Joined: Sat Mar 06, 2021 11:21 pm

Re: NRF24L01, Pi Pico & Pro Micro

Post by OrangeAndApples » Thu Mar 11, 2021 11:03 pm

Yes thank you, I was reading one of your previous posts on the matter.

Hit another slight issue. Trying to get two way comms, base (ProMicro) transmits data, rover (Pico) sends reply.

Pico can recieve data but seems to refuse to send, spitting out OS errors, hence Pro Micro receives nothing at the other end. What did I mess up here? Thanks!

Pipes

Code: Select all

base_address = (b"\x41\x41\x41\x41\x41") # 'AAAAA' on the arduino (base)
me_address = (b"\x42\x41\x41\x41\x41")  # 'AAAAB' on the arduino
...
nrf = NRF24L01(SPI(cfg["spi"]), csn, ce, channel = 100, payload_size=32)
nrf.open_tx_pipe(me_address) #Pico
nrf.open_rx_pipe(1, base_address) #ProMicro
Transmit function

Code: Select all

def tx(tx_data):
    tx_data = 12
    nrf.stop_listening()
    #tx_data =  str(tx_data).encode()
    print("sending:", tx_data)
    for x in range(1,50):
        try:
            nrf.send(struct.pack("i", tx_data)) #i = sending int, ii = sending 2xint ...)
            return()
        except OSError:
            print("No good")
            pass

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: NRF24L01, Pi Pico & Pro Micro

Post by pythoncoder » Fri Mar 12, 2021 9:19 am

Debugging radio code is tricky when you have the hardware in front of you; rather harder when you don't. I'm afraid I've never inter-operated with Arduino.

It is worth noting that the transmitter can throw an exception if the fault is in the receiver: as you probably know the NRF24L01+ automatically checks for successful reception. So you need to make sure that, at the time when you transmit, the receiver is listening otherwise the transmitter will throw.

You need to design a protocol to ensure this. My micropython-radio modules use a master/slave concept where the slave constantly listens, only transmitting in response to a request from the master. The master only listens when it has issued a request. There are more sophisticated approaches, but master/slave is the simplest.

This is the commonest cause of problems.
Peter Hinch
Index to my micropython libraries.

Post Reply