Repository navigation
Communication NRF24
The nRF24L01(+) is a cheap 2.4 GHz radio module that is connected via SPI. With up to 2 Mbit/s it is fast enough for uncompressed audio and has a very low latency - a nice choice for a wireless microphone or speaker with Arduino boards that have no WiFi. See Communication for the general considerations.
NRF24Stream (AudioTools/Communication/NRF24Stream.h) uses the RF24 library (install it). In TX_MODE the written data is sent in packets of payload_size bytes, in RX_MODE the received packets are collected in a buffer that you can read. It works on any board that is supported by RF24 (ESP32, Teensy, Nano, RP2040 ...).
You can pass your own RF24 object or receive buffer in the constructor; by default they are created for you.
Field (NRF24Config) |
Default | Description |
|---|---|---|
mode |
TX_MODE or RX_MODE (the parameter of defaultConfig()) |
|
pin_ce, pin_csn
|
9, 10 | the pins of the module |
channel |
124 | 0..125: the upper channels are less crowded by WiFi |
data_rate |
RF24_2MBPS |
RF24_250KBPS, RF24_1MBPS or RF24_2MBPS
|
pa_level |
RF24_PA_MAX |
the transmit power |
payload_size |
32 | bytes per packet (max. 32) |
address |
0xF0F0F0F0E1 | sender and receiver must use the same address |
auto_ack |
false | wait for acknowledgments and repeat lost packets |
crc_length |
RF24_CRC_DISABLED |
check the packets with a CRC |
use_write_fast |
true | use writeFast() (no waiting for each packet) |
max_begin_retry |
10 | retries if the module does not start |
The defaults are tuned for a low latency: no acknowledgments and no CRC. Mono, 16 bit at 32 kHz reaches about 6.5 ms latency.
From the nrf24 examples. The sender:
#include "AudioTools.h"
#include "AudioTools/Communication/NRF24Stream.h"
AudioInfo info(32000, 1, 16);
SineGenerator<int16_t> sineWave(32000);
GeneratedSoundStream<int16_t> sound(sineWave);
NRF24Stream radio;
StreamCopy copier(radio, sound);
void setup() {
auto cfg = radio.defaultConfig(TX_MODE);
// cfg.pin_ce = 9; // adjust for your board
// cfg.pin_csn = 10;
cfg.copyFrom(info);
if (!radio.begin(cfg)) stop();
sineWave.begin(info, N_B4);
}
void loop() { copier.copy(); }The receiver:
AudioInfo info(32000, 1, 16);
NRF24Stream radio;
I2SStream i2s;
StreamCopy copier(i2s, radio);
void setup() {
auto cfg = radio.defaultConfig(RX_MODE);
cfg.copyFrom(info);
radio.begin(cfg);
auto icfg = i2s.defaultConfig(TX_MODE);
icfg.copyFrom(info);
i2s.begin(icfg);
}
void loop() { copier.copy(); }- Bandwidth: 2 Mbit/s is the raw air rate - in practice you get much less. 32 kHz mono 16 bit needs 512 kbit/s; stereo at 44.1 kHz (1.4 Mbit/s) is too much: use mono, a lower sample rate or a codec.
-
Data loss: without
auto_acklost packets are gone; withcrc_lengthcorrupted packets are dropped instead of played as noise. With PCM a lost packet is just a short glitch, but encoded data needs a codec or container that can resync. -
Throttle: a generator or file produces data faster than the audio rate - put a
Throttlebeforeradioon the sending side, so that the receiver is not overrun. See also clock drift. - Power supply: the module needs a stable 3.3 V - add a 10 µF capacitor at the module, especially with the PA/LNA versions.