Tuesday

New Circuit Board for Audio Prototyping, Sponsored by PCBWay.com


 New Circuit Board for Audio Prototyping, Sponsored by PCBWay.com

 Design and manufacturing of a custom circuit board

 With recent developments to my AutoAnalogAudio library for Arduino adding support for nRF52840 based devices like the Feather 52840 or XIAO 52840 lines, I was getting a little sick and tired of having a big tangle of wires in order to run an SD card, I2S microphone, I2S amplifier, speaker etc, in order to test things out and develop this library.

Thanks to a sponsorship from PCBWay.com, I was able to develop a custom circuit board for prototyping and development, that can later be used as a walkie-talkie or intercom, with range similar to bluetooth.

The first part of this was to actually create the custom circuit board, and I chose the KiCad application. This was a big learning curve, as I had only ever designed an extremely simple circuit board before, and that was quite a challenge for me. This would take things to the next level.

So first, in KiCad, one needs to create a schematic for the circuit. This part was not too difficult, although it still presented some challenges, and took up a fair bit of time.   

 


 Above is the original circuit design and I will be putting the associated files onto a GitHub repository soon.

The people at PCBWay were very helpful in figuring this all out, and since this is what I consider to be my first real attempt at a proper circuit board, I made a number of mistakes. One of the hardest parts seemed to be matching the KiCad component footprints up with the proper part numbers. I assume there must be an easier way to do this, but I ended up searching and searching, and still made some somewhat unrecoverable errors.

Beyond the correctable errors that the folks at PCBWay helped me fix, one of the main mistakes was ordering the wrong part for the J5 connector. This was in addition to a bunch of other parts that I had incorrect, but were caught prior to production. In the end, I had the boards shipped without the J5 connector, but the PCBWay people shipped some connectors that I was able to modify to work, and soldered them on myself.

I was also missing a position file initially, because I didn't know at first, but you need to send three main files, the gerber files in a ZIP format, the Bill of Materials or BOM, and a Position file, all of which can be generated from within KiCad. Putting this all together was one of the hard parts, again I struggled quite a bit with finding the correct part numbers etc.

 

Above are pictures of the PCB itself, and the assembled PCB, missing the J5 connector which I messed up the part number on. Everything else was correct, thanks to a lot of help from PCBWay.com. As stated, I was able to solder on some slightly modified J5 connectors PCBWay sent along with the boards.

Upon hooking it up, inserting an SD card and attempting to play some music, the damn thing worked! I was pretty surprised everything actually seemed to be connected correctly, and functioned flawlessly! Upon trying the microphone however, I discovered that I might have selected an I2S microphone that the attached micro-controller (Feather Express 52840 or Feather Sense 52840) cannot quite handle. According to some searches, I may be able to modify my AutoAnalogAudio library to handle it, but as it stands, the built in mic does not function.

 I am still able to do some testing and work with the Feather Sense 52840, because it has a built in PDM microphone, but I was hoping to use the custom-added I2S microphone. Everything seems to be connected properly circuit wise, its just the 52840 MCU that needs what seems to be a special configuration to work with this microphone.

 


 Above is my test setup with all the components attached. The small battery runs the micro-controller, SD Card and microphone, while the large batteries handle the I2S amplifier. I'm still kind of amazed all the circuitry seems to be correct, there is just a compatibility issue with the microphone!

 That's all for now, I will be posting all the related files and examples to my GitHub repo soon, and will do some follow up posts detailing how to use the AutoAnalogAudio library along with this circuit board. To be continued...

 

Sunday

Direct TCP/IP connectivity between Arduinos using a nRF24 or nRF52 radio link w/RF24Ethernet

 Setting up direct TCP/IP connectivity between Arduinos using a nRF24 or nRF52 radio link w/RF24Ethernet

 Utilizing the new functionality of the RF24Ethernet library

 With some recent experimentation and prototyping involving the lwIP IP Stack, I was able to modify the RF24Ethenet library to function standalone, without the need for a Linux/Raspberry Pi device running RF24Gateway. This allows users to directly connect multiple Arduino devices using the RF24Ethernet library, utilizing TCP or UDP protocols to communicate between devices.

The RF24Ethernet library API is based on the official Arduino Ethernet API, so users utilize the same coding style to communicate over nRF24 or nRF52 radio links.  


Setting things up:

1. The first thing to do is verify you have working radios. With nRF52 devices, they are built-in so, there is not much to worry about, but with nRF24 radios, users need to keep in mind power supply and wiring issues, so testing using the official gettingStarted sketch included with the RF24 library is recommended before attempting this.

 2. For now, users need to install the RF24Network library from ZIP file. This will be all be configured automatically once the current updates are deployed to the main branch of RF24Ethernet. This document will be updated at that time.

3. Install the RF24Ethernet library from ZIP from https://github.com/nRF24/RF24Ethernet/tree/lwIP  Note: Once deployed, the updated library will be available from the Arduino Library Manager. Users may need to uninstall/reinstall to get the latest updates at that time.

 4. Install the Arduino lwIP library using the Arduino Library Manager as required for non-ESP32 & non-ESP8266 devices which already include lwIP.

5. Run the included examples from the Headless directory in the RF24Ethernet examples on two devices. I've tested so far on Arduino Due, ESP8266, ESP32 and nRF52 based devices. The RPi Pico still utilizes the uIP stack due to technical issues using lwIP with the Arduino MBED based core.

 

What to expect:

The main server example sets up a RF24Mesh 'Master Node' which handles addressing and address look-ups for all other nodes. Nodes not in range of the Master Node will attempt to connect automatically via routing traffic through other connected nodes. 

The client examples simply connect to the Master Node and request an HTML based web-page. 

 In a real life deployment this activity may be reversed. With the Master Node running a modified Client example, and sensor or other nodes running modified Server examples, the Master Node could then connect to each device in turn and retrieve data as required.

To designate a master node, simply call the following before calling mesh.begin()

mesh.setNodeID(0);

then from the main loop()

 mesh.DHCP();

 

 Things to Note: 

 RF24Ethernet makes use of two separate IP Stacks, the older, unmaintained uIP Stack works on smaller devices like Uno, Nano, Mega, etc, while the newer, lwIP stack is used automatically for devices >50MHz CPU speed, including the Arduino Due, ESP32, ESP8266, and nRF52 based devices using the nrf_to_nrf radio library.

To ensure you are using the lwIP stack, users can #define USE_LWIP 1 & #define RF24ETHERNET_USE_UDP 1 in the RF24Ethernet.h file or prior to compilation. 

 

Saturday

Using the lwIP stack with RF24Ethernet and RF24 radios - Another experiment in progress

 Using the lwIP stack with RF24Ethernet and RF24 radios

Another experiment in networking 

 So I finally got some time to play around with the lwIP stack over the holidays, and decided to try my hand at getting it working with the RF24Ethernet/RF24Gateway layers, so users can more conveniently handle TCP/IP traffic over the nRF24 radios.


 

 Overview:

 The RF24Gateway and RF24Ethernet libraries work together to handle TCP/IP and UDP traffic over nRF24 or nRF52 radio links. Users can communicate using standard protocols and techniques, without additional programming or advanced knowledge of the radio software or hardware.

The RF24Gateway library runs on more powerful systems with their own IP stack like a Raspberry Pi or other Linux devices with GPIO and SPI capabilities. The RF24Ethernet library is designed for Micro-controllers like those found using the Arduino platform. Now it supports the faster devices with a more advanced IP stack, lwIP.

 In studying and playing around with lwIP and the Arduino platform, most if not all of the client examples for Arduino utilize a single connection at a time, whereas lwIP supports multiple connections. In server mode, the default behaviour is to listen on a given port, with a backlog. This means that in the current configuration, lwIP will handle the first connection normally, then accept a second connection, but won't complete the second connection until the first connection has finished.

I've also introduced default timeouts, 30 seconds server side, so that if no data is sent or received for a given timeout period the server will disconnect the client. For the server side, call server.setTimeout(30000); . For the client, users need to implement their own timeout conditions. The server timeout can be set to 0 to disable it.

Usage: 

 Usage remains exactly the same as before, with users utilizing the Arduino Ethernet API and client/server functions to connect, disconnect and transfer data between systems. This means that RF24Ethernet users don't have to learn a new API to use the library, as long as they are familiar with the standard Arduino Ethernet API.

As of this writing UDP support is not included but will be added at a later date, TCP/IP support is functional and tested via MQTT and HTTP. The Arduino lwIP library can be installed using the Arduino Library Manager.

 Conclusion:

 I've been wanting to configure lwIP to go along with the RF24Ethernet library for a long time, but just didn't have the time or expertise to sit down and make it happen. With the recent holidays, I was able to put things together, and it came out working very nicely. It is still in prototyping stages, likely with some bugs to work out, but it is functional and available for testing at https://github.com/TMRh20/Sketches/tree/master/RF24Ethernet-lwIP

Update: Jan 18 2026:

As of today, with the latest commits, the server and client tests I am running have been stable for 24 hours. The main bugs have been worked out, and the system is operating normally.  A pull request for the new version of RF24Ethernet will probably be made in the next week or two, pushing the code to a side branch at https://github.com/nRF24/RF24Ethernet and concluding the initial prototyping. Any users making use of the code in the Sketches repository will be encouraged to move to the new branch in the main repo.

 NEW: 

The RF24Ethernet library no longer requires RF24Gateway running! Nodes can simply run RF24Ethernet and establish TCP/IP connections between themselves! See the new Headless examples found in the examples/Headless directory. 

Instructions:

 1. Download the RF24Ethernet library from the link above and place into your Documents/Arduino/libaries/ folder

2. Download and install the RF24Network library from ZIP from https://github.com/nRF24/RF24Network

 3. Edit the RF24Network_config.h file to set MAX_PAYLOAD_SIZE to 1514

4. The library is configured to detect CPU speeds over 50Mhz and use lwIP automatically, but users can edit RF24Ethernet.h and #define USE_LWIP as required

5. Enjoy!!! 

 

 

 

 

 

 

 

 

 

Wednesday

Automation etc with Node Red - How to make your Dashboard2 chart data persistent using a SQLite database

 How to make your chart data persistent using a SQLite database

Reliable charts and graphs with Node Red

 So I've been using Node Red for quite some time now as part of my general IoT network, involving wireless radio modules and numerous sensors etc. One main drawback of using Node Red, is that by default, it doesn't store data long term, and your charts etc will go blank after a restart or shutdown.

 Using a SQLite database combined with Node Red, I've been able to store information for the long term that persists even after restarts and shutdowns and this is how I did it.

 

Above is an image of a simple Node Red flow, logging and retrieving information from a database.

  So first things first, I will go through the process of the above flow:

1. Arduino and other sensors send in data over MQTT (Purple "houseTemp" and "houseHum") 

2. We need to combine the information into a single record and insert it into a database. (Light orange "Filter Dups & Insert")

 3. The data is then logged to a SQLite database

.4 At the same time, we select data from the database, so we can insert the newest data into some charts

5.  The results of that selection are fed directly into some charts:

 

 

 Detailed Process & Code

1. An Arduino sends in a message via MQTT with the msg.topic "houseTemp" and a float that represents the temperature (msg.payload), and another message with the msg.topic "houseHum" and a float that represents the humidity as the msg.payload.

2.  Then we combine the 2 results into 1, and insert the data using a function node:

 let temp = context.get('temp3') || null;

let hum = context.get('hum3') || null;
let ctr = context.get('ctr3') || 0;

if (msg.topic == "houseTemp") {
   context.set('temp3', msg.payload);
} else {
   context.set('hum3', msg.payload);
}

let sendMsg = false;

ctr = ctr + 1;

if (ctr >= 2) {
   ctr = 0;
   sendMsg = true;
}
context.set('ctr3', ctr);

msg.topic = "INSERT INTO HOUSETEMP (TIMESTAMP, TEMPERATURE, HUMIDITY) VALUES (" + Date.now() + ", " + temp + ", " + hum + ")";

if (sendMsg == true) {   
if (hum != null && temp != null) {
      return msg;
   }
} else {
   return;
} 

3. The data is logged to a SQL database, per the "INSERT" command in the previous function. 

4. Lets "select" or retrieve all the data including the data that was just logged:

msg.topic = "SELECT * FROM HOUSETEMP ORDER BY TIMESTAMP DESC LIMIT 1000";
return msg;
 
4. The database node responds immediately to the previous function, returning data
 
5. Display data in the charts:

 The main things to consider are having all of your variable names correct, and
 using the correct "properties" configuration in your Chart Node.

 

General DB Maintenance: 

In order to create a table, you need to add an "inject" node and set the msg.topic to something like:

CREATE TABLE HOUSETEMP ( TIMESTAMP INT PRIMARY KEY NOT NULL, TEMPERATURE float NOT NULL, HUMIDITY float NOT NULL)

 Since we are using a Linux timestamp, we can use the following formula to clean up old data via another "inject" node:

DELETE FROM HOUSETEMP WHERE TIMESTAMP < strftime('%s', 'now', '-14 days'); 

  

 Overview:

This generally works pretty well and keeps the graphs & charts up to date with good data, storing it for up to 2 weeks. Of course, this is a heavy-handed approach, replacing all the chart data each time. A better approach is identified below, using an external MySQL server to offload activity.

A bit better solution would be to make the SELECT function node only return 1 record at a time. Then, add a blank inject node that triggers only once on startup, that both resets the charts ( send JSON msg.payload of []  ), and loads all existing data into the charts. The arrays coming out of the database at the end would need to be reversed as well, so the newest data is at the end of the array.

This is a much less intensive way to go about it, but a little more complicated to set up. 

 

Saturday

RF24: An advanced example for the Arduino Uno Q

 RF24: An advanced example for the Arduino Uno Q

 A new take on the RF24 GettingStarted example

In testing out the RF24 library and related features, I managed to get a few different things working together on the Arduino Uno Q to provide a more advanced example of RF24 interaction. 


 

 The main thing the sketch does is transfer data over RF24 radio link along with a standard Arduino device running the RF24 GettingStarted sketch included with the RF24 library.

Then, any data received is displayed in the Serial Monitor, Python Console and an associated webpage to demonstrate usage of incoming data etc.

 A button is included on the webpage that allows users to toggle the LED matrix on/off, which demonstrates how to pass data from Webpage to Python to Microcontroller. 

All in all its a simple concept, but it did take some figuring to work out how the functions and stuff all relate through JavaScript, HTML, Python, C++ etc.

My Arduino Q sketches can all be found here:

https://github.com/TMRh20/Sketches/tree/master/ArduinoQ 

For a limited time, a live real-time demo of a similar sketch will be available online here:

TMRh20s Example Webpage

The main functionality is tied into 4 files:

sketch/sketch.ino - The Arduino sketch handles radio input/output & passes its data to Python

python/main.py - The middleman between the webserver and the Arduino sketch

assets/app.js - JavaScript handling, communicates between index.html and Python via websockets

assets/index.html - The main webpage, provides variables that can be modified via JavaScript

Thursday

Trying out the Arduino Uno Q - A quick and dirty overview

 Trying out the Arduino Uno Q - A quick and dirty overview

 Love it or hate it, it... exists 

 With the release of the new Arduino Uno Q board, I decided to get one and try it out. After a few days of playing around and experimentation I have to say I'm less than impressed.


 The concept seems to be a solid one, combining a standard Micro-Processor Unit (MPU) with a Microcontroller Unit (MCU), but the execution has been a little rough.

 The first and main thing to probably address is the Bridge concept, which is a way for users to make the MCU 'talk' to the MPU. It is driven by a serial connection running at 115200 baud, using RPC, which altogether is far too slow to pass copious amounts of data, or do it really quickly. On the other hand, it can be used to pass information between programs, be it Python to Python or C++ (Arduino) to Python.

 One of the first things I tried, of course, is running RF24 radio based applications. It appears to work OK initially with the core RF24 driver and RF24Network, but once I got into the RF24Mesh layers, I started to notice problems. I thought it was basic speed issues, but it turned out to be a radio power supply related issue it seems. After changing out the radio and calling 'radio.setPALevel(RF24_PA_MIN,0);', it worked.

Next, I attempted to create a basic TUN network interface in Linux using Python, to see about creating a RF24Gateway like interaction, but realized quickly that this too was outside the general capabilities of the device. It runs a Python virtual environment within a Docker container, with no apparent way to configure things, so I can't seem to get it working. That means an RF24Gateway style library is out of the question for now.

It seems that so much of what I've tried do to so far just doesn't work. There was also a forced, breaking update that happened recently, to version 3.0, where users have to manually download a new version of App Lab in order to program their devices.

 One essential thing to note, is that when the App Lab stops responding, or the Serial/Monitor output gets corrupted, I need to close App Lab, and run `arduino-app-cli system cleanup` from the command line to get it working again.

 Some of the features still seem promising, the ability to easily incorporate "Bricks" and features into your programs, and the underlying software for the MPU is Debian/Linux along with Arduino, so you can still do a lot with it. 

I don't think I'll get another one, but I will definitely be playing around with the one I've got for a while. 

In the meantime, I've included a new example in the RF24 core library that users can try with the Arduino Uno Q that allows users to configure the radio and print debug information.

I've also added an example sketch to go along with the stock RF24 GettingStarted example here:

https://github.com/TMRh20/Sketches/tree/master/ArduinoQ 

 

RF24Gateway - What Does It Do And How Do I Use It?

 RF24Gateway - What Does It Do And How Do I Use It?

 A simplified explanation...

 So maybe you've taken a look at the RF24 communication stack and have seen RF24Gateway, along with the RF24Ethernet libraries, and are wondering what they do? I've noticed some confusion among users who aren't sure what the libraries do exactly.

 The simplest explanation, is that it allows users to use nRF24L01 radios as standard Network Interface Cards (NICs). Once RF24Gateway is installed, its like having a standard NIC linked into the wireless RF24 radio network.

This means users don't need to understand programming, RF24 APIs, or anything much about how the RF24 comm. stack operates in order to use RF24Gateway &/or RF24Ethernet. It means users can use standard networking tools like the 'ping' command to test network connectivity, or more advanced tools & protocols like MQTT, HTTP, etc to interact with their Arduino devices or other Raspberry Pi/Linux devices wireless, over RF24Gateway & the radio network.

Linux users, for example, can connect to other Linux devices over the RF24 based network by using SSH, SSL or other secure protocols.

A good general understanding of standard networking and protocols is probably going to be beneficial to anyone trying to make use of RF24Gateway/RF24Ethernet. The system uses the proprietary ESB protocol by Nordic for communication, and although it operates on similar frequencies to WiFi, it is not a WiFi based system. However, it does allow your RF24Ethernet & RF24Gateway devices to interact with WiFi devices on your network, because RF24Gateway can link the WiFi & RF24 networks together using standard networking techniques like forwarding and routing, or by using an intermediary like an MQTT server.



 This means advanced users can also do things like link RF24 based sensor networks together by using VPNs, SSH tunneling, etc and create a centralized environment to collect and display data, control devices, or otherwise interact with the networks. I've experimented with automation systems like Home Assistant and Node Red to create these types of networks myself, and there are a number of alternatives that can be easily integrated into the system. Networks can work over very wide geographical areas, covering many KM locally, via radio link, and spanning the globe using VPNs or SSH tunneling.

 RF24Ethernet is companion software to RF24Gateway, which is meant to run on smaller devices like Arduino Uno, Nano, etc. while RF24Gateway is designed solely for Linux devices. RF24Gateway typically requires little to no programming, while RF24Ethernet lets users build web servers, sensor nodes, interactive nodes with on/off switches, lighting controllers, etc. and customize things to the nth degree, or simply build off the included examples.

 ESP32 based devices have become extremely popular, but in a large scale sensor network, WiFi is a very power hungry alternative to nRF24 based devices, which can offer similar features, wireless protocols & connectivity. 

To sum it up, RF24Gateway & RF24Ethernet provide connectivity & functionality similar to a WiFi network, but using much less power, and are able to support the smallest devices like ATTiny all the way to larger, much more powerful computers like Raspberry Pi and other Linux based devices that support GPIO & SPI capabilities. By default, the system uses the RF24Mesh and RF24Network libraries, so all of the internal networking and routing is handled automatically.


 

New Circuit Board for Audio Prototyping, Sponsored by PCBWay.com

 New Circuit Board for Audio Prototyping, Sponsored by PCBWay.com   Design and manufacturing of a custom circuit board  With recent developm...