Sunday

Streaming Audio over WiFi using the Arduino Uno R4 WiFi, AutoAnalogAudio Library & VLC

Streaming Audio over WiFi using the Arduino Uno R4 WiFi, AutoAnalogAudio Library & VLC

 Pushing the system to its internal limits

 With recent developments regarding the AutoAnalogAudio library and the Uno R4 WiFi, I was able to get an audio stream to play on VLC over WiFi from a microphone attached to the Uno R4. This was a little bit of a challenge due to the inherent limitations of the R4, but I was able to make it function.

 In short, the attached ESP32 that handles WiFi is connected to the main RA4M1 chip via a Serial bridge, running at 115200 baud. This pretty much limits the associated audio stream to lower quality 8Khz 8-bit samples. A modification is possible, but with out-of-the-box behaviour, my tests show that 9Khz 8-bit audio is the upper limit. 

I've included an example into the AutoAnalogAudio library to demonstrate this behaviour, compressing the 14-bit output of the ADC (microphone input) into 8-bit samples using PCMU encoding and sending them directly to VLC Media Player in RTP format over UDP.

 To configure the example, one would need to enter their WiFi credentials into the associated secrets.h file. This helps to establish the WiFi connection used for audio streaming to a computer. With the PC running VLC on the same WiFi network, users then need to determine the IP Address of the VLC machine and enter it into their sketch as targetIP.

Once those two things are done, just run the example with a microphone connected to pin A1 on the Arduino Uno R4 WiFi. Then open VLC and open a Network Stream at  rtp://@:5004

The audio is lower quality, only really good for voice transmission, but as stated, users can override this behaviour by modifying the ESP32 core for the Uno R4 WiFi and configuring the bridge to run at a faster speed. 

Version 1.55.1 of the AutoAnalogAudio library has been released including support for nRF54L15 and Uno/Nano R4 boards, and can be installed via the Arduino Library Manager.

Thursday

The RF24Mesh Users Guide

 The RF24Mesh Users Guide

         How to manage & administer RF24Mesh based networks

 If you are reading this, it is assumed you are using are or interested in using the RF24 Communication stack at some level, including the RF24Mesh library. This guide should apply whether you are using RF24Mesh directly, or using the RF24Ethernet/RF24Gateway libraries and attempts to provide a good general understanding of the basic concepts RF24Mesh was built around.

 What is RF24Mesh? 

 RF24Mesh is a wireless networking library designed to automate the mundane networking tasks that don't require user intervention, including addressing assignment & reassignment, DNS style lookups and general communication tasks. The underlying libraries, RF24 and RF24Network provide many wireless networking and communication features, and RF24Mesh ties them all together with automation.

The RF24Mesh library works using pre-assigned and unique NodeIDs, which can be thought of similar to static IP addresses. These NodeIDs are statically assigned, so any individual node can be identified for communication purposes. At a lower layer, the system uses RF24Network addresses, which are dynamic, changing regularly to accommodate nodes at any level of the network. These addresses represent the physical placement in the network, and are used for direct communication after completing a NodeID lookup, which returns the RF24Network address.

The overall goal of RF24Mesh is to allow users to create and deploy wireless networks based on RF24, RF52 and/or RF54 radios, in short order, and to have them communicate on an ongoing basis, changing physical locations and/or distance as required. Networking tasks are automated to a degree that human intervention should not be required for very long periods of time.

Everything is configured around a central "Master" node, which needs to remain online and active, since it keeps track of all nodes on the network and handles addressing look-ups, which are similar to DNS requests on a purely TCP/IP based network. 

How to set it up?

Arduino: Just download and install the RF24Mesh library via the Arduino Library Manager. As mentioned above, each device must be assigned a static NodeID, but once that is done, everything else can be automated. The network will support NodeIDs ranging from 2 to 253, with nodeID 1 and 0 typically reserved for the "Master" node, which keeps track of all NodeIDs and related addresses.

Linux: See the documentation link below, there is an installer available for Linux based devices which streamlines the installation process. 

Nodes do not need to be in range of the Master node for operation, they just need to be in range of another node that does have connectivity to the Master node. Operating nodes will automatically route traffic on behalf of other nodes. The network is built in layers, with the master at layer 0, and subsequent layers 1 to 4. This means that a given node can be as far away as 4 hops from the master, with traffic routed automatically through other nodes.  

 What can I do with RF24Mesh?

 The RF24Mesh library can handle many different communication scenarios, but was built with a focus on IoT systems, allowing users to create large-scale sensor networks or command & control scenarios. When using RF52 based radios, users can incorporate encryption into their networks directly as well. When using the RF24Ethernet or RF24Gateway libraries with RF24Mesh, encryption must be implemented at a higher level, using technologies like SSL, SSH, TLS, etc.

 Users can securely and reliably receive data from multiple sensors and control devices with a simple API and interface, customizing their system to the Nth degree.

 Tips & Tricks

 When using RF24Mesh, there is a need to continuously verify connectivity and renew addresses when nodes move around or simply lose wireless connectivity, and these features are incorporated into the examples. Nodes typically verify connectivity with a direct parent node, assuming that if the parent node remains connected, it has connectivity to the Master node. 

No matter what layer users are working at, RF24Mesh or RF24Ethernet/RF24Gateway, the mesh library generally works the same. With RF24Ethernet/RF24Gateway, users can utilize standard networking tools over the wireless network, including TCP/IP, UDP etc, making use of protocols like MQTT, SSH or HTTP. The network still functions using the underlying communication protocols, allowing users to send very small RF24Mesh or RF24Network messages, while handling large TCP/IP or UDP packets at the same time.

 This configuration allows the smallest of devices, including ATTiny devices, to be configured as routing nodes, with more powerful devices like Arduino Uno, Nano, Mega etc functioning as fully operational RF24Mesh or RF24Ethernet nodes. Larger devices capable of running Linux would make use of the RF24Gateway and/or RF24Mesh libraries directly.

RF24Mesh also allocates memory on the Master node dynamically for storing NodeID & RF24Network address combinations. The default is to configure the memory space for up to 10 nodes. Users can edit the RF24Mesh_config.h file, and set  #define MESH_MEM_ALLOC_SIZE 10 to a higher number to increase the memory allocated for storing node information. This is typically recommended when running the master node on a non-linux device so that memory is not continuously being allocated and re-allocated as nodes join the network.

In the case of devices that only receive data, and don't verify connectivity that often, users can un-comment #define RF24MESH_CONN_CHECK_TYPE RF24MESH_CONN_CHECK_MASTER in the RF24Mesh_config.h file, to ensure they are verifying connectivity with the Master node, instead of just a parent node. This also prevents some temporary DOS attacks from being possible, but does increase network traffic. 

In the case of users that require static nodes, RF24Network can be used directly at the same time as RF24Mesh. On the master node, users just need to define a static address for the static nodes, and they will function as RF24Network nodes on the RF24Mesh network, but will need to remain in the same physical location/maintain connectivity themselves. 

Linux vs Arduino

The code-base for Linux devices is a little more advanced than the Arduino code-base, but functions very similarly. The main difference is that on Linux devices, the default behaviour is to save the Address list (NodeIDs and RF24Network addresses) to file periodically. On Arduino devices the list is not saved by default, but this can be implemented quite easily if desired. This is important to understand, because on reboot, a Linux based network (Linux Master Node) will resume operations using the preexisting address assignments. An Arduino based network (Arduino Master Node) will resume operations using blank address assignments, meaning every node will need to re-join the network. Typically, nodes should verify connectivity every 30 seconds or so at least, so the Master node should remain off for at least 30-seconds in that case, to ensure all nodes refresh/renew their addresses. On a Linux based master node, a file dhcplist.txt is created, and can be deleted prior to startup to force a fresh startup.

The other important difference between Linux & Arduino devices revolves around fragmentation and re-assembly of large packets. A Linux based device will cache and store fragments for each individual node, while Arduino devices will only receive and cache fragments for a single node at a time, making Linux the system of choice for operating RF24Mesh master nodes that handle very large payloads and multiple devices transmitting at the same times.  

 How to get started?

 You have to start somewhere, and I would generally recommend installing RF24Mesh directly, and testing out some of the provided examples. It helps later to have a good understanding of the basic operation and features, including the use of NodeIDs, RF24Network addresses, and the difference between the two.

Users can then move on to trying out the more complex libraries, like RF24Ethernet and RF24Gateway, which use complex underlying code to provide a simple and seamless communication system based on TCP/IP and UDP. 

 The documentation is available at https://nrf24.github.io/RF24Mesh/ 

Sunday

Audio Playback on the Uno R4 using the 12-bit DAC and the AutoAnalogAudio Library

Audio Playback on the Uno R4 using the 12-bit DAC and the AutoAnalogAudio Library

Having some fun with audio reproduction 

 Since recently receiving some Uno R4 and Uno R4 WiFi boards, I just started playing around with audio reproduction. It seems they are not directly I2S capable, but do have ADC and DAC functionality. So far, I've gotten audio playback working via the DAC on Analog Pin 0.



I attempted to get mp3 playback working as well, but the R4 just doesn't have the available memory for decoding, so it will just be wav files and similar for now.

Initial results are pretty good, playing anywhere from 8 to 16-bit audio at 16KHz to 44.1KHz from SD card with ease. I've connected an analog amplifier directly to the output pin (A0), and results are so far good.

Next up will be the ADC, then onto figuring out other methods, including possibly hacking an I2S signal and output using the SPI peripheral.

For now, the code is available in the UnoR4Support branch of the AutoAnalogAudio library, so users can switch to that branch and download the ZIP if wanting to test it out.

Thursday

Playing around with the Arduino Uno R4 Minima, Uno R4 Wifi and Uno Q

Playing around with the Arduino Uno R4 Minima, Uno R4 Wifi and Uno Q

Stepping up to a new level of micro-controller 

 

 Thanks to the fine people at Arduino, specifically Per Tillisch, an Arduino Support Engineer, I just received some free hardware! An Uno R4 Minima, Uno R4 WiFi and Uno Q!

 

Uno R4 Wifi and Uno R4 Minima
 
Now its just a matter of figuring out what to do with this stuff. I've already begun testing with the RF24 Communication Stack, and most of it works out-of-the-box. The only change required was adjusting the CPU speed detection in RF24Ethernet to accommodate the Uno R4 Wifi and Uno R4 Minima. I've put the changes in, but haven't done a release yet. Users can download the ZIP or clone the repo to install for now.
 
The R4 Minima appears pretty straight forward, with a micro-controller attached to a familiar board type, and a lot more processing power and memory than previous AVR-based designs. Not that the AVR boards are no longer useful, but its nice playing around with the newer designs and architecture. Newer boards actually tend to have a simpler interface when getting into direct register access and control, so its easier to develop libraries and applications that work with the newer boards. The R4 WiFi is more complex, with a main MCU, the Renesas RA4M1, and an ESP32 handling WiFi with a bridge between the MCUs.
 
Now I've played around with the Arduino Q quite a bit already, so will be mostly focusing on understanding and working with these new R4 boards that I have no experience with. I've gotten them working with the RF24 Comm stack as mentioned above, so it will probably be onto the AutoAnalogAudio library, to see what can be accomplished. The Arduino Q runs Linux along with the MCU, with a Serial bridge between them, but these boards are quite different. They seem to be more comparable to regular MCUs, just with enhanced functionality.
 
The boards themselves came with no strings attached, Arduino folks just sent them for free, so I can pretty much do whatever I want, with whatever time frame I want. 
 
Of course the big difference is that the R4 WiFi has an embedded ESP32 chip for WiFi in addition to the main micro-controller, so I will need some time to understand the bridge interface and whether it is worth it to explore programming the ESP32 chip directly. At first I will focus on the Renesas RA4M1 chip and explore its main capabilities, leaving the rest for later.
 
A big thanks to Arduino for these boards!

Monday

RF24Ethernet w/lwIP - Reaching a Point of Long Term Stability

 RF24Ethernet w/lwIP - Reaching a Point of Long Term Stability

Stable & Secure Communications with the RF24 Communication Stack 

Since I started on this journey integrating the lwIP TCP/IP stack into the RF24 Comm Stack, I was unsure if I would ever get to this point. Its been about 6 months since I started, and at this point I can say I am glad I did. Using lwIP really brings the stack up to standard, as previously it used only the uIP TCP/IP stack, which works well, but is no longer maintained. Now, newer micro-controllers will use the newer, up-to-date lwIP stack, while smaller, older MCUs will use the uIP stack.

 Over the past week or so, I've put in quite a lot of work on the RF24 Comm. Stack, including RF24Ethernet. In that time, it has become more secure, more stable, and is working better than it has in a long, long time.


Constant attacks & jamming targeting my networks has been taking place for years, and with the rise of AI, I decided to do some security & code reviews involving the RF24 Comm Stack. This was hugely beneficial, since I was able to work out a number of bugs and security flaws affecting the system. I would assume that most open source projects are beginning to do this as well, since there is a huge benefit from having a computer scan and verify your code.

 In the end, I was able to fix what I see as the "Final Major Issues" affecting the communication stack, from buffer overflows, to memory leaks, to a problem with millis() timer usage, involving rollover un-safe millis() calls. The system is now more resilient and stable than ever before, still susceptible when jamming overwhelms parts of the system, but able to bring itself back online, recovering all functionality as soon as the jamming stops. The constant attacks against my network have slowed significantly, with very little to no impact on the system when they do occur, since there are now less if any avenues to exploit remotely.

 I am now just running some final tests regarding the interaction of RF24Ethernet w/RF24Network when using lwIP, since there seemed to be some timing related issues with delay() vs network.update() calls, which should be addressed in the RF24Network master branch, but require testing before a release is made. These issues cause WDT resets on my ESP8266 while using WiFi in testing, but only occur once every 3-4 days or more, so tracking them down was difficult.

 All in all, I am very happy with the progress made over the last week, satisfied that my security concerns have been addressed, functionality is back to where it should be, and everything just keeps working.

Thursday

Using RF24Ethernet & RF24Gateway with the Arduino Cloud

 Using RF24Ethernet & RF24Gateway with the Arduino Cloud

 Pushing automation even further

 Recently, I was offered an Arduino Uno Q, Arduino Uno R4 Wifi and 1-year of Arduino Cloud access for free! This came as quite the surprise, because I was contacted out of nowhere by Per Tillisch, an Arduino Support Engineer, who offered me the devices and cloud access with no strings attached! I was quick to take him up on his offer. He stated it was due to my work contributing to the Arduino ecosystem.

In looking at the cloud access, it looks like it will be very simple to create dashboards etc, and integrate everything I want from my existing systems into the cloud! No code changes, no updates, no nothing. Just some simple changes in the NodeRed system I use.

With the current wireless IoT systems I am using, based on RF24Ethernet and RF24Gateway + wireless radios + MQTT, I also use NodeRed for managing all the data and interactions locally. This means that all I had to do was install the node-red-contrib-arduino-iot-cloud nodes, setup an API key, and use the newly installed nodes to communicate with the cloud!

 My system is setup so the RF24Ethernet nodes use MQTT to communicate with the RPi running RF24Gateway & NodeRed. NodeRed then handles the communication with the cloud.

See  https://docs.arduino.cc/arduino-cloud/guides/node-red/ for more information.

Right off the bat, I was able to create a simple dashboard that displays incoming Temperature, Humidity & Barometric pressure data on some charts!


 From here, it is very simple to add/remove & create new parts of the dashboard.

All of the existing Arduino devices in my network now have potential cloud access via NodeRed! I didn't have to modify any code, upload new firmware or really do much of anything! This all works with my existing systems!

The beauty of this is users can keep all their data and integrations local, logging to a database if desired etc, and still make use of the Arduino Cloud at the same time. Some data can go to the cloud, some to a local repository, and everything just seems to work in sync!

I currently have all my integrations set up via NodeRed + NodeRed Dashboard, so it is very similar already to the Arduino Cloud Dashboard, though only available locally. Using the cloud, I can now make some parts of it accessible from anywhere.

This is all very cool, I can't wait to get the new hardware! 

 

Monday

AutoAnalogAudio Library - Updated with I2S support for nRF54L15 devices

 AutoAnalogAudio Library - Updated with I2S support for nRF54L15 devices

 Bringing audio to the nRF54L15

 I was able to dabble little over the weekend, and ended up connecting an I2S amp and microphone to a nRF54L15 device. Getting it working was a little confusing at first, but the datasheet provided enough info to figure out the compatibility differences between nRF52840 and nRF54L15 devices. It was just a matter of making a few small changes.

One of the most glaring differences is with the main data pointer (NRF_I2S->RXTXD.MAXCNT). With the nRF52840 it counts by the number of 32-bit words, where the nRF54L15 counts individual bytes, so the main data handling functions needed to be modified.  

The other glaring difference is the pin layouts, but I've used the same physical layout as the 52840. That is, the physical spots on the board are the same, but the underlying pin and port numbers have changed.

 


    Per the AutoAnalogAudio library, these are how the pins are laid out by GPIO Pin / Port numbers:

    I2S_PIN_MCK = 8;
    I2S_PORT_MCK = 2;
    I2S_PIN_SCK = 5;
    I2S_PORT_SCK = 1;
    I2S_PIN_LRCK = 7;
    I2S_PORT_LRCK = 1;
    I2S_PIN_SDOUT = 11;
    I2S_PORT_SDOUT = 1;
    I2S_PIN_SDIN = 10;
    I2S_PORT_SDIN = 1;

 The changes have been pushed to the master branch as of this writing, and I will clean up the code, possibly add support for the PWM and SAADC features, and do a release soon. For now users can clone from the master branch or install from ZIP.

Streaming Audio over WiFi using the Arduino Uno R4 WiFi, AutoAnalogAudio Library & VLC

Streaming Audio over WiFi using the Arduino Uno R4 WiFi, AutoAnalogAudio Library & VLC  Pushing the system to its internal limits  With ...