XIAO BLE SENSE: nrf52840 radio communication with nrf24L01+

XIAO BLE SENSE: nrf52840 radio communication with nrf24L01+

Establishing a communication layer using the RF24 API 

I recently received an XIAO BLE Sense board from based on the nrf52840 and have been playing around with it for a few days now. In that time I have been able to get audio recording working with my AutoAnalogAudio library, as well as establish basic radio communication with the nrf24l01+ modules. This thing is pretty sweet! It is very small, so I've been leaving it connected to the USB cable so I don't lose it, but its definitely a benefit.

One of the first things to know about this board is that it has a DFU functionality, so it switches ports while uploading, and goes back to the original port after uploading. This means that if you upload some code that crashes the device, you need to press the reset button twice quickly, and it will reaload into DFU mode on a different port, so you can re-upload some working code.

Secondly, if you get an error 'Property 'upload.tool.' is undefined' then you just need to select the correct upload port.

It also uses a USB-C connector, so make sure to have the correct cable handy.

Radio Communication:

To get radio communication working, I've written an Arduino library for the nrf52840 which can be found here: It can be installed just like any other Arduino library.

The library includes one example for now, gettingStarted. To get this example working with the Arduino example from the RF24 library, the following parameters need to be set in the RF24 example:

  1. Call radio.setChannel(7);
  2. Call radio.enableDynamicPayloads();
  3. Comment out the lines for openReadingPipe and openWritingPipe (it uses the default addresses) and power-cycle the radio so it retains default values.
As of this writing, the library only supports reception, and there is no Auto-Ack functionality yet. This is just a preliminary draft of the API.

So far I am very intrigued with this device and its capabilities. Hopefully it isn't too much to get transmission and auto-ack working, but we will see I guess.


New Raspberry Pi + nRF24L01+ shields

 New Raspberry Pi + nRF24L01+ shields

Connect PA+LNA modules to your Raspberry Pi

I recently had some circuit boards made, as I have had enough experience working with nrf24l01 radio modules that I've encountered numerous issues regarding power supplies and the need for additional capacitors soldered to the radios. 

These boards connect to the 5v pins of the Raspberry Pi, which can supply plenty of current for the radios, and converts it down to 3.3v. I've designed two boards, one that fits inside the case, and the other that fits outside the case, so they should work with most cases, though some cases may need modifications. The designs both use a 26-pin header, so they are compatible with earlier versions of Raspberry Pi as well.

Raspberry Pi - nRF24L01+ adapters

These adapters will support even the PA+LNA versions of the radios, so you can extend the range of your wireless networks considerably over the standard modules. They include extra capacitance, with capacitors placed right beside the VCC and GND pins of the radios, so there is no need to solder on additional capacitors.

Shields are available at


RF24 Home Automation Kits now Available

 RF24 Home Automation Kits now Available

Comes with preconfigured devices, just plug and play!

I've finally decided to put together some electronics kits with preconfigured devices, using the RF24 communication stack. As the system is now very stable and reliable, I think it is about time I started putting devices together and selling them to support future development and designs. 

So with that, I am announcing the opening of my online store at

The current kit will come with a RPi4B and all the attachments like HDMI cable, a case, and power supply along with 3 Arduino Uno R3, 2 temperature & humidity sensors and 1 RBG LED ring, plus of course the RF24 radios. I've also designed some custom PCB shields for everything to just plug into, with power for the radios and extra capacitors, so its super simple to put it all together.

The setup uses Node-Red and RF24Gateway to provide a mesh network that seamlessly links all your devices together, and allows you to add custom devices to the network and/or expand the network by purchasing more devices or setting them up yourself with the Arduino platform.

If they sell, I intend to design more devices to go with the currently available products.

Support is available at

General documentation is available at: and more documentation is being created to specifically support the kits.


The RF24 Communication Stack: What are the different layers and which one do I use?

 The RF24 Communication Stack:

What are the different layers and which one do I use?

Over the past number of years, I've been developing a communication stack for nrf24l01+ radios, generally to be used with Arduino and Raspberry Pi devices. The comm. stack is organized into separate layers, per the OSI model, which allows users to establish communication between any number of devices depending on their needs.

1. The RF24 layer: This layer is generally used for simple device-to-device communication, where speed and simplicity are key. One example is for radio control of a single device, where a stream of small data packets are communicated from one device directly to another in rapid succession. Streaming of audio in real-time is another example where the RF24 layer would be used directly. Using the RF24 layer can be a bit complex, and some knowledge of radio communication is beneficial.

2. The RF24Network layer: This layer expands on the RF24 layer by providing a number of features, both to enhance radio communication and provide users with the features of an OSI layer 3 (network) layer. RF24Network nodes are arranged in a static tree topology, and this layer provides all the features to manage them. RF24Network handles routing, fragmentation/reassembly of large packets, and communication to any other device is straight-forward. Users don't require knowledge of the RF24 layer to operate a network of nodes at the RF24Network layer, and it can be much simpler than using the RF24 layer directly. Recommended when not able to use the RF24Mesh library, when there is a need for static nodes, or to simplify one-to-one communication.

3. The RF24Mesh layer: This layer expands on all underlying layers by providing an automated, self-healing network that allows nodes to move around and or re-establish connectivity as required. This layer is generally recommended when creating a network of devices, as it automates addressing for RF24Network, and provides a more seamless interaction. Users generally communicate using the RF24Network API, with RF24Mesh providing address lookups and automation for the network. 

4. The RF24Ethernet/RF24Gateway layer: This layer allows communication using standard networking protocols, such as TCP, UDP, ICMP. It is generally recommended to run RF24Gateway on a Raspberry Pi as the master node, with smaller devices running RF24Ethernet. Allows very simple or very complex communication scenarios, with users requiring little to no knowledge of radio or RF24 programming APIs. 

The RF24Ethernet API is very similar to the Arduino Ethernet API, and RF24Gateway allows users to use standard networking tools to communicate with devices running RF24Ethernet. Recommended for communication scenarios where speed is not essential, but reliability and consistency is, such as a home automation system using MQTT and Node-Red and/or a sensor network reporting data. Users can run a wireless, Arduino based webserver, or interact with nodes using their mobile device over MQTT, HTTP, etc. 

As can be demonstrated, each layer has its place, providing communication capabilities for a very wide range of scenarios, and allowing users to benefit from the built-in features or to dig right in and customize things to the nth degree. Generally, the higher you go up in the stack, the simpler the interaction, with complex underlying code providing the simplest and most advanced user interaction.

Related Code and Documentation:


Sensors & IoT Stuff: Home Automation with NodeRed, RF24Ethernet/RF24Gateway & MQTT

Sensors & IoT Stuff: Home Automation with NodeRed, RF24Ethernet/RF24Gateway & MQTT 

Control a homemade, Arduino-based RGB light, other devices or display data using NodeRed

I made a video demonstrating how to configure NodeRed with RF24Ethernet/RF24Gateway to control a homemade, Arduino-based RGB light. The process is fairly straightforward, with the Arduino node subscribing to the MQTT server, and the NodeRed device publishing some RGB values. The same system can be used to send or receive data from a wide range of devices, thus enabling an nrf24l01 based home automation/IoT and/or monitoring system.

The video assumes users are already somewhat familiar with the RF24 communication stack, having the radios installed and ready to go. The sketch used in the video is very closely based on the existing RF24Ethernet MQTT examples, with some extra code to control some NeoPixel based lighting.

Note: As of mosquitto 2.0 you need to add  listener 1883 and  allow_anonymous true in /etc/mosquitto/mosquitto.conf.

With this setup, users can add simple input/output toggles, sliders and charts to manage devices and display incoming sensor data. It is just a matter of configuring the Arduino devices to handle the input/output messages to and from MQTT. NodeRed can also log incoming MQTT data to a database, to store and display historical data.

This system has the benefit of requiring no apps, so everything can be controlled from a mobile device or PC etc. with some simple button clicks. Everything used is also completely open-source and free, so setup costs are minimal, and there is a host of information available for Arduino and Raspberry Pi.


AutoAnalogAudio Arduino library updated with ESP32 Support

 AutoAnalogAudio Arduino library updated with ESP32 Support

ESP32 DAC/ADC Output/Input via the I2S peripheral

Previously this year, I received some ESP32 based MCUs with OLED displays from DigitSpace, and used these devices to add ESP32 support to the AutoAnalogAudio library. It is a bit different from previous iterations, since instead of AVR interrupts and PWM, the ESP32 uses much more advanced peripherals. The I2S capabilities of the ESP32 provide a fairly seamless interaction when in/outputting audio signals, since it is just a matter of configuring the I2S, DAC and/or ADC and feeding and/or drawing data from the device. The main challenge in this case was combining the I2S functionality with RTOS tasks to provide a simple, asynchronous audio interface as is the case with the AutoAnalogAudio library.

The capabilities are much the same, but the ESP32 portion is still a bit in development, although working nicely at this point. The ESP32 example is specifically for the ESP32 device, since some minor API changes were required to manage RTOS tasks in combination with the I2S peripheral. This allows asynchronous handling of audio, so users can start playback and manage other tasks however desired while audio playback occurs.


1 x ESP32 OLED Wifi Kit
1 x MAX9815 Microphone Preamp
1 x TDA7297 PA Module

The MAX9815 will provide some audio to sample, and the TDA7297 was used to amplify the output of the onboard DAC. The above hardware as mentioned is provided by DigitSpace.

Connecting the Hardware:

With the ESP32, the AAAudio library samples the ADC on analog channel 4 by default, and sound output is on DAC1 and/or DAC2 (See previous post for pinout) The ADC channel cannot currently be changed, but that is on the to-do list.


The ESP32 onboard ADC will provide relatively good quality audio sampling, at 12-bits. The onboard DAC however, is only 8-bits, so the output will not be quite as high quality as with the Arduino Due. Using a higher sample rate can make up a for the low bit-rate of the DAC, as higher sample-rate * bit-rate = quality.


Updating the library for ESP32 support has been fairly interesting, as it required a fair bit of learning and development time to understand I2S and how to control the related peripherals, while providing the same or similar behavior as with currently supported devices like the Due or Uno.

All in all it seems to perform pretty well. Audio input or output from virtually any source can be managed via the AAAudio library.

The updated library has been released and should be available via the Arduino Library Manager.


ESP32 - Playing around with the I2S peripheral and DAC audio output

 ESP32 Arduino - Playing around with the I2S peripheral, ADC and DAC audio output

 In some of my last posts, I mentioned the ESP32 based boards I recently received from DigitSpace, and I finally found some time to play around with some of the audio based peripherals. In this case I'm starting small, attempting to create a simple sine wave output using the internal DAC.

The documentation for the I2S peripheral is a bit limited it seems, but there is enough information in the Arduino Github repo to make sense of things and get some basic audio output going.

The general theory seems to be pretty simple compared to working with previous libraries, TMRpcm and AutoAnalogAudio, which utilize timer driven interrupts and nested interrupts (AVR devices) to handle asynchronous audio processing. The ESP32 provides a number of methods to handle audio processing, with peripherals designed to offload this work from the central processor, making the user interface mostly about buffering and handling audio data.

The above code will produce a simple sine wave output on the DAC pins (see previous ESP32 related posts for pinout) and can be toggled off/on by entering a '1' on the Arduino Serial monitor. An audio file can also be defined and played by entering a '2' in the Serial monitor. In this case the sketch is setup for a 32Khz, 16-bit, Mono audio file.

In this case the hardest part is following the documentation found above and figuring out just how simple it actually is to handle the I2S peripheral. Really, you just configure the appropriate sample rate and output pins, mode etc, and then feed data into the peripheral. If doing any digital signal processing, its really about providing enough CPU time to handle the data and feed it into I2S. If handling audio files, the hardest part is decoding.

This should prove to be a good basis for the AutoAnalogAudio library since the only thing left to do is add ADC support and either use timers or RTOS tasks to handle asynchronous processing of the audio.

XIAO BLE SENSE: nrf52840 radio communication with nrf24L01+

XIAO BLE SENSE: nrf52840 radio communication with nrf24L01+ Establishing a communication layer using the RF24 API  I recently received an XI...