NRF24L01 with a Pi Pico
NRF24L01 with a Pi Pico
I recently bought some nRF24s with the intention of talking to some Pi Picos in micropython. I did some digging and found the drivers
https://github.com/micropython/micropyt ... s/nrf24l01
and
https://github.com/peterhinch/micropython-radio/
but if I'm honest I don't really know how to use them very well. I have a basic program running the first drivers but I'm getting a "send failed" - the pin assigments are correct so I'm unsure what's causing this.
Does anyone have any code examples on how to use these libraries? The examples provided seem to all be for the PyBoard, esp32 or micro:bit, so I'm a little confused.
Sorry for the kinda basic question, I'm still quite new to this sort of stuff and I've never used SPI before. Thanks in advance!
https://github.com/micropython/micropyt ... s/nrf24l01
and
https://github.com/peterhinch/micropython-radio/
but if I'm honest I don't really know how to use them very well. I have a basic program running the first drivers but I'm getting a "send failed" - the pin assigments are correct so I'm unsure what's causing this.
Does anyone have any code examples on how to use these libraries? The examples provided seem to all be for the PyBoard, esp32 or micro:bit, so I'm a little confused.
Sorry for the kinda basic question, I'm still quite new to this sort of stuff and I've never used SPI before. Thanks in advance!
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: NRF24L01 with a Pi Pico
I suggest you tell us exactly how these are wired up and what test program you're running. You need to have a unit running as receiver before starting the transmitter: unlike many radios the NRF24l01, when transmitting, automatically checks for successful reception.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
-
- Posts: 5
- Joined: Fri Feb 26, 2021 11:26 pm
- Location: Scotland
Re: NRF24L01 with a Pi Pico
OK I managed to get this working between an ESP32 & a Pico with code in the links you provided (I didn't try a Pico to Pico) but it should work.
In nrf24l01_test.py change the references from usys to sys. For the Esp32 & Pico the module is sys (this is a bit confusing as the author changed from sys to usys, change it back).
Next wire the Pico to the nrf module as shown in the Python SDK section 3.7. SPI.
Note confusingly where it says Pin it actually means GPIO. I used.
CE to GPIO14
CSN to GPIO15
MISO to GPIO4
MOSI to GPIO7
SCK to GPIO6
Connect GND & 3V3OUT to the nrf device.
Modify the sys.platform check at the start of the test program
Note the use of "spi":0,
You must keep all the parameters the same for the master & slave (channel, speed, pipes etc) or the devices wont communicate. Make one device a slave & the other a master by
adding slave() & master on the last line of nrf24l01_test.py
I have used these devices with Arduino's & Rpi the results aren't great, they are difficult to wire, fairly unreliable, can only send up-to 32 bits (the more bits you send in a packet the worse they are) and have a very limited range, even outdoors expect < 10meters. There is also a reported problem of poor power supply regulation, I soldered a 4.7uF across the power pins . So good luck.
In nrf24l01_test.py change the references from usys to sys. For the Esp32 & Pico the module is sys (this is a bit confusing as the author changed from sys to usys, change it back).
Next wire the Pico to the nrf module as shown in the Python SDK section 3.7. SPI.
Note confusingly where it says Pin it actually means GPIO. I used.
CE to GPIO14
CSN to GPIO15
MISO to GPIO4
MOSI to GPIO7
SCK to GPIO6
Connect GND & 3V3OUT to the nrf device.
Modify the sys.platform check at the start of the test program
Note the use of "spi":0,
Code: Select all
elif sys.platform == "rp2":
cfg = {"spi": 0, "miso": 4, "mosi": 7, "sck": 6, "csn": 15, "ce": 14}
else:
raise ValueError("Unsupported platform {}".format(sys.platform))
adding slave() & master on the last line of nrf24l01_test.py
I have used these devices with Arduino's & Rpi the results aren't great, they are difficult to wire, fairly unreliable, can only send up-to 32 bits (the more bits you send in a packet the worse they are) and have a very limited range, even outdoors expect < 10meters. There is also a reported problem of poor power supply regulation, I soldered a 4.7uF across the power pins . So good luck.
-
- Posts: 5
- Joined: Fri Feb 26, 2021 11:26 pm
- Location: Scotland
Re: NRF24L01 with a Pi Pico
Just a quick update. I didn't fully check the setup last night. Between two Esp32 it works fine. However for Esp32 & Pico, with Pico as the Master & Esp32 as Slave I get 5/16 passes,with the Master/Slave swapped it doesn't work at all.
I may take a further look, but have previously spent many frustrating hours & IMHO you're better off using a microcontroller with a 'proper' wifi module, which are easier to use, have more flexibility (mqtt support) and more reliable. You could connect an Esp-01 to a Pico but you're better off simply using an Esp32 or waiting for the Adafruit/Arduino Rp2040 wifi variants when they appear. If as you say you haven't used SPI before these devices are not ones to start with.
I did get it working reliably with the Pico as Master by using an external power supply for the nrf24l01 rather than the Pico 3V3, Pico as a slave still not working. Probably leave it there as I have all but given up using these devices for any projects.
I may take a further look, but have previously spent many frustrating hours & IMHO you're better off using a microcontroller with a 'proper' wifi module, which are easier to use, have more flexibility (mqtt support) and more reliable. You could connect an Esp-01 to a Pico but you're better off simply using an Esp32 or waiting for the Adafruit/Arduino Rp2040 wifi variants when they appear. If as you say you haven't used SPI before these devices are not ones to start with.
I did get it working reliably with the Pico as Master by using an external power supply for the nrf24l01 rather than the Pico 3V3, Pico as a slave still not working. Probably leave it there as I have all but given up using these devices for any projects.
Last edited by thetestdoctor on Tue Mar 02, 2021 1:58 pm, edited 1 time in total.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: NRF24L01 with a Pi Pico
The range varies greatly with the quality of manufacture. I have disarded Chinese units that could barely manage 2 meters in the same room. Good ones (e.g. from Adafruit) have a similar range to WiFi: a great deal better than 10 metres out of doors. I have a project with four Pyboards communicating with these radios. The system has been running 24/7 for several years.thetestdoctor wrote: ↑Mon Mar 01, 2021 9:30 pm...
I have used these devices with Arduino's & Rpi the results aren't great, they are difficult to wire, fairly unreliable, can only send up-to 32 bits (the more bits you send in a packet the worse they are) and have a very limited range, even outdoors expect < 10meters. There is also a reported problem of poor power supply regulation, I soldered a 4.7uF across the power pins . So good luck.
In projects like this one, they are energy efficient: the Pyboards wake from deep sleep, use the radio to exchange messages, and go back to sleep. I'm pretty sure that connecting to, and using, a WiFi network would take substantially more energy. However, whether I'd use them in a new project is debatable.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: NRF24L01 with a Pi Pico
Thank you so much for the help! I'll look into the alternatives you mentioned and try those instead.
-
- Posts: 5
- Joined: Fri Feb 26, 2021 11:26 pm
- Location: Scotland
Re: NRF24L01 with a Pi Pico
I brought a batch of 5, blew one up the other 4 must be as you say discarded Chinese ones, BTW I was being generous when I said 10m it was probably 2-3m in the garden. Point taken about low power usage & new projects. My experience has been hours of frustration with them.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: NRF24L01 with a Pi Pico
If you decide to use these, do pay a bit more for quality hardware. It will save a lot of wasted time. I incorrectly mentioned Adafruit: they don't make these. The units I use are from Sparkfun: https://www.sparkfun.com/products/691 and https://www.sparkfun.com/products/705.
The other factor to bear in mind is that WiFi, though superficially easy, isn't if you care about reliability. No radio communication is. The signal can be lost by moving out of range, or it can be obliterated by interference. See my notes on the subject. With @kevinkk525 I developed a resilient MQTT solution which copes with WiFi and broker outages. It is considerably more involved than the official solutions, which are rather fragile.
The other factor to bear in mind is that WiFi, though superficially easy, isn't if you care about reliability. No radio communication is. The signal can be lost by moving out of range, or it can be obliterated by interference. See my notes on the subject. With @kevinkk525 I developed a resilient MQTT solution which copes with WiFi and broker outages. It is considerably more involved than the official solutions, which are rather fragile.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: NRF24L01 with a Pi Pico
Hi all,
I need some help to get a pico-pico communicate with the NRF24L01.
The connections are:
CE to GPIO14
CSN to GPIO15
MISO to GPIO4
MOSI to GPIO7
SCK to GPIO6
as mentioned above.
The code i use for master:
The code for slave:
simplified versions of the nrf24l01test.py file.
I always get an OS error.
I also tried the nrf24l01test.py without any changes to channel or payload_size. I get a failed, response timed out message
Is there something obvious that i am missing? Any help?
Thanks.
I need some help to get a pico-pico communicate with the NRF24L01.
The connections are:
CE to GPIO14
CSN to GPIO15
MISO to GPIO4
MOSI to GPIO7
SCK to GPIO6
as mentioned above.
The code i use for master:
Code: Select all
"""Test for nrf24l01 module. Portable between MicroPython targets."""
import sys
import ustruct as struct
import utime
from machine import Pin, SPI
from nrf24l01 import NRF24L01
from micropython import const
if sys.platform == "pyboard":
cfg = {"spi": 2, "miso": "Y7", "mosi": "Y8", "sck": "Y6", "csn": "Y5", "ce": "Y4"}
elif sys.platform == "esp8266": # Hardware SPI
cfg = {"spi": 1, "miso": 12, "mosi": 13, "sck": 14, "csn": 4, "ce": 5}
elif sys.platform == "esp32": # Software SPI
cfg = {"spi": -1, "miso": 32, "mosi": 33, "sck": 25, "csn": 26, "ce": 27}
elif sys.platform == "rp2":
cfg = {"spi": 0, "miso": 4, "mosi": 7, "sck": 6, "csn": 15, "ce": 14}
else:
raise ValueError("Unsupported platform {}".format(usys.platform))
# Addresses are in little-endian format. They correspond to big-endian
# 0xf0f0f0f0e1, 0xf0f0f0f0d2
pipes = (b"\xe1\xf0\xf0\xf0\xf0", b"\xd2\xf0\xf0\xf0\xf0")
pin = machine.Pin(25, machine.Pin.OUT)
def master():
csn = Pin(cfg["csn"], mode=Pin.OUT, value=1)
ce = Pin(cfg["ce"], mode=Pin.OUT, value=0)
if cfg["spi"] == -1:
spi = SPI(-1, sck=Pin(cfg["sck"]), mosi=Pin(cfg["mosi"]), miso=Pin(cfg["miso"]))
nrf = NRF24L01(spi, csn, ce, payload_size=8)
else:
nrf = NRF24L01(SPI(cfg["spi"]), csn, ce, channel=100, payload_size=32)
nrf.stop_listening()
nrf.open_tx_pipe(pipes[0])
print("NRF24L01 master mode, sending ...")
while True:
millis = utime.ticks_ms()
print("sending ", millis)
pin.value(1)
try:
nrf.send(struct.pack("i", millis))
except OSError:
print("OS error")
pass
pin.value(0)
# delay then loop
utime.sleep_ms(500)
print("NRF24L01 test module loaded")
print("NRF24L01 pinout for test:")
print(" CE on", cfg["ce"])
print(" CSN on", cfg["csn"])
print(" SCK on", cfg["sck"])
print(" MISO on", cfg["miso"])
print(" MOSI on", cfg["mosi"])
print("run nrf24l01test.slave() on slave, then nrf24l01test.master() on master")
print("This is master")
while True:
master()
Code: Select all
"""Test for nrf24l01 module. Portable between MicroPython targets."""
import sys
import ustruct as struct
import utime
from machine import Pin, SPI
from nrf24l01 import NRF24L01
from micropython import const
if sys.platform == "pyboard":
cfg = {"spi": 2, "miso": "Y7", "mosi": "Y8", "sck": "Y6", "csn": "Y5", "ce": "Y4"}
elif sys.platform == "esp8266": # Hardware SPI
cfg = {"spi": 1, "miso": 12, "mosi": 13, "sck": 14, "csn": 4, "ce": 5}
elif sys.platform == "esp32": # Software SPI
cfg = {"spi": -1, "miso": 32, "mosi": 33, "sck": 25, "csn": 26, "ce": 27}
elif sys.platform == "rp2":
cfg = {"spi": 0, "miso": 4, "mosi": 7, "sck": 6, "csn": 15, "ce": 14}
else:
raise ValueError("Unsupported platform {}".format(usys.platform))
pin = machine.Pin(25, machine.Pin.OUT)
# Addresses are in little-endian format. They correspond to big-endian
# 0xf0f0f0f0e1, 0xf0f0f0f0d2
pipes = (b"\xe1\xf0\xf0\xf0\xf0", b"\xd2\xf0\xf0\xf0\xf0")
def slave():
csn = Pin(cfg["csn"], mode=Pin.OUT, value=1)
ce = Pin(cfg["ce"], mode=Pin.OUT, value=0)
if cfg["spi"] == -1:
spi = SPI(-1, sck=Pin(cfg["sck"]), mosi=Pin(cfg["mosi"]), miso=Pin(cfg["miso"]))
nrf = NRF24L01(spi, csn, ce, payload_size=8)
else:
nrf = NRF24L01(SPI(cfg["spi"]), csn, ce, channel=100, payload_size=32)
nrf.open_rx_pipe(1, pipes[0])
nrf.start_listening()
print("NRF24L01 slave mode, waiting for packets... (ctrl-C to stop)")
pin.value(1)
while True:
utime.sleep_ms(const(250))
print("Still waiting")
if nrf.any():
while nrf.any():
buf = nrf.recv()
millis = struct.unpack("i", buf)
print("received", millis)
pin.value(0)
print("NRF24L01 test module loaded")
print("NRF24L01 pinout for test:")
print(" CE on", cfg["ce"])
print(" CSN on", cfg["csn"])
print(" SCK on", cfg["sck"])
print(" MISO on", cfg["miso"])
print(" MOSI on", cfg["mosi"])
print("run nrf24l01test.slave() on slave, then nrf24l01test.master() on master")
print("This is slave")
while True:
slave()
I always get an OS error.
I also tried the nrf24l01test.py without any changes to channel or payload_size. I get a failed, response timed out message
Is there something obvious that i am missing? Any help?
Thanks.
Re: NRF24L01 with a Pi Pico
OSError on which device and code line?