A port of the Mirf library for ESP-IDF.
The library provides basic control of the Nordic nRF24L01/nRF24L01+ RF modules.
I ported from here.
ESP-IDF V4.4/V5.x.
ESP-IDF V5.0 is required when using ESP32-C2.
ESP-IDF V5.1 is required when using ESP32-C6.
git clone https://github.com/nopnop2002/esp-idf-mirf
cd esp-idf-mirf/Peer-to-peer
idf.py set-target {esp32/esp32s2/esp32s3/esp32c2/esp32c3/esp32c6}
idf.py menuconfig
idf.py flash
Note for ESP32C3
For some reason, there are development boards that cannot use GPIO06, GPIO08, GPIO09, GPIO19 for SPI clock pins.
According to the ESP32C3 specifications, these pins can also be used as SPI clocks.
I used a raw ESP-C3-13 to verify that these pins could be used as SPI clocks.
Note for Channel
Channels range from 0 to 127.
The channel number of the sender and receiver must be the same.
Channel = 0 uses the frequency of 2.4000GHz, channel = 127 uses the frequency of 2.4127GHz.
The width of one channel is only 0.01GHz.
Using multiple radio node at the same time will almost always cause interference, even if you change channels.
The ESP32 series has three SPI BUSs.
SPI1_HOST is used for communication with Flash memory.
You can use SPI2_HOST and SPI3_HOST freely.
When you use SDSPI(SD Card via SPI), SDSPI uses SPI2_HOST BUS.
When using this module at the same time as SDSPI or other SPI device using SPI2_HOST, it needs to be changed to SPI3_HOST.
When you don't use SDSPI, both SPI2_HOST and SPI3_HOST will work.
Previously it was called HSPI_HOST / VSPI_HOST, but now it is called SPI2_HOST / SPI3_HOST.
When used at long distances, lowering the RF data rate stabilizes it.
When changing the RF data rate, the sender and receiver must have the same value.
When using 250KBps, it takes time to PAYLOAD sending and ACK PACKET receiving, so it is necessary to increase the automatic retransmission delay.
I tested it with this.
If you want to initialize the nRF24L01 settings after using the Advanced Settings, you need to power cycle the nRF24L01 before executing.
Because nRF24L01 remembers the previous setting.
nRF24L01 does not have Software Reset function.
nRF24L01 | ESP32 | ESP32-S2/S3 | ESP32-C2/C3/C6 | ||
---|---|---|---|---|---|
MISO | -- | GPIO19 | GPIO37 | GPIO4 | (*1) |
SCK | -- | GPIO18 | GPIO36 | GPIO3 | (*1) |
MOSI | -- | GPIO23 | GPIO35 | GPIO2 | (*1) |
CE | -- | GPIO16 | GPIO34 | GPIO1 | (*1) |
CSN | -- | GPIO17 | GPIO33 | GPIO0 | (*1) |
GND | -- | GND | GND | GND | |
VCC | -- | 3.3V | 3.3V | 3.3V |
(*1)You can change it to any pin using menuconfig.
I used this library on Arduino environment.
You need to match the payload size and channel with Arduino and esp-idf.
- Arduino environment
Mirf.payload = sizeof(mydata.value);
Mirf.channel = 90;
Mirf.config();
- esp-idf
uint8_t payload = sizeof(value);
uint8_t channel = 90;
Nrf24_config(&dev, channel, payload);
I used this library on Raspberry Pi.
nRF24L01 is not interested in the contents of the payload.
Therefore, nRF24L01 can send and receive binary data.
But the internal format of the binary data depends on the MCU architecture, so communication between different architectures is not possible.
If you want to send or receive binary data between different architectures, you need to encode it into a CSV format string like this.
123,-123,1234.5,-1234.5
nRF24L01 can send and receive up to 32 characters, but by adding an index to the sent data, it can send and receive 256 types of data.
When changing the settings of the nRF24L01, it is necessary to power cycle the nRF24L01 before executing.
Because nRF24L01 remembers the previous setting.
nRF24L01 does not have Software Reset function.
nRF24L01 has "Enhanced ShockBurst" features.
"Enhanced ShockBurst" automatically sets the PTX(=Transmitter) in receive mode to wait for the ACK packet from PRX(=Receiver).
ESP32 | nRF24L01[PTX] | nRF24L01[PRX] | ESP32 | |||
---|---|---|---|---|---|---|
ESP32 | --> | nRF24L01 | ||||
nRF24L01 | --(Payload Packet)--> | nRF24L01 | ||||
wait 250uS | ||||||
nRF24L01 | <--(Ack Packet)-- | nRF24L01 | ||||
ESP32 | <-- | nRF24L01 | ||||
nRF24L01 | --> | ESP32 |
PTX waits for an ACK packet for 250uS and retransmits 3 times.
ESP32 | nRF24L01[PTX] | nRF24L01[PRX] | ESP32 | |||
---|---|---|---|---|---|---|
ESP32 | --> | nRF24L01 | ||||
nRF24L01 | --(Payload Packet)--> | nRF24L01 | ||||
wait 250uS | ||||||
nRF24L01 | --(Payload Packet)--> | nRF24L01 | ||||
wait 250uS | ||||||
nRF24L01 | --(Payload Packet)--> | nRF24L01 | ||||
wait 250uS | ||||||
ESP32 | <-- | nRF24L01 |
Using a data rate of 250KBps extends the range of radio waves.
However, it takes time to send PAYLOAD and receive ACK PACKET.
Therefore, the delay time for automatic retransmission should be longer than 250uS.
If the delay of automatic retransmission is not increased, it is considered as a transmission failure.
ESP32 | nRF24L01[PTX] | nRF24L01[PRX] | ESP32 | |||
---|---|---|---|---|---|---|
ESP32 | --> | nRF24L01 | ||||
nRF24L01 | --(Payload Packet)--> | nRF24L01 | ||||
Over 250uS | ||||||
nRF24L01 | <--(Ack Packet)-- | nRF24L01 | ||||
ESP32 | <-- | nRF24L01 | ||||
nRF24L01 | --> | ESP32 |
See the data sheet for details on Enhanced ShockBurst.
spi_device_transmit is executed by the SPI driver and consumes 1tick of CPU time.
When DMA is enabled, SPI max_transfer_sz defaults to 4092(4K).
This indicates that 4092 bytes of data can be sent in 1tick(10 millsec).
Therefore, the SPI transmission potential of ESP-IDF is 400Kbytes/Sec.
This has a significant impact on the nRF24L01, which has a small maximum payload size.
Unfortunately, nRF24L01's maximum payload size is 32 bytes.
1 tick (10 millsec) is required to send payload and receive ack packet.
This has nothing to do with SPI bus speed.
The throughput of nRF24L01 is 32 bytes/10 millsec(=3,200 bytes/sec).
RF data rate of nRF24L01 affects the radio range, but not the throughput.
Si24R1 is marketed as a nRF24L01 compatible.
Si24R1 clone cannot send and receive correctly.
After purchasing the nRF24L01, be sure to check the markings on the chip.
Many suppliers sell Si24R1 as nRF24L01.