If you have read my previous explorations on the subject of attaching NEOpixel strips to RISC-V MCUs, you will find a change in this project. Rather than using SPI to send the data stream to the strip we will use a peripheral that is rather unique to the ESP line of MCUs. Espressif calls it the RMT peripheral (short for remote control). This may seem surprising as we normally think of a remote control as an output device. But, the RMT is much more than a mechanism for generating remote control pulses to be fed to an IR LED. It is basically a generic method of bit-bashing any serial encoding onto a bit stream. It is very flexible, Espressif gives examples for 1-Wire, music buzzer and stepper motors as well as "led_strip" which we will be exploring here. As an added bonus we will explore the use of the RNG peripheral - the Random Number Generator - to make one of the animations cuter.
As with most of my Explorations this will be published before it's completion so check back often until this sentence disappears.
OverView:The
deliverable we wish to produce is the ability to connect at least 10 neoPixel strips to the tiny ESP32-C3 SuperMini board. Each strip will be able to display it's own separate sequence of pixels. We will go further and allow up to 5 different animation on each strip. All of this action will be provided by freeRTOS.
We will be using only a single instance of RMT (there are only 2) to encode the bitstream for each strip. We will explore the use of the GPIO matrix to switch the RMT output, in turn, to each of the different GPIOs to which the strips are connected.
This exploration was conducted using the Espressif-IDE which is essential for under the hood work on ESP MCUs. Their manufacturer support is 2nd to none.
I uploaded the complete project to CanHobby. It is too big for github. Just create a separate directory called rmtOS and unzip it into that dir. Then open the dir as a workspace with the ESP-IDE.
WorkFlow:We begin with app_main() which starts by setting up the RMT peripheral with rmt_setup() followed by setting up each individual strip by calling strip_setup() which binds it to a strip struct which is specified in NEO.h. We then setup the individual parameters for each animation which are part of the struct.
We then create the show task which is the scanner that goes through each strip in turn, redirecting the bitstream to the corresponding GPIO pin. From a software point of view each strip is a buffer in memory. These buffers are modified by the animation tasks. Each of these tasks is created in the last lines of app_main().
RNGThe RNG basically uses electronic noise read by an ADC connected to nothing to generate the entropy to fuel the random algorithm. We don't need to do any setup, it is done by the bootloader. Neither do we need to be reading system registers - Espressif provides an implementation of the getrandom() standard Linux system call. We see the usage in the anim2() animation.
BLEAs
I threatened in the comments I have added BlueTooth Low Energy control to this project. I am using the Serial BlueTooth Terminal Andriod APP to add some remote control for our NEOpixels. BLE is a relatively complex protocol so it is beyond the scope of this Exploration to discuss all of the software in detail. BLE uses a type of client/server paradigm which can confuse us. In this project the device running the APP is considered as the client and our ESP-C3 and it's firmware as the server. The BLE framework is broken up into a somewhat bewildering array of services, profiles, attributes and characteristics. A server could be offering several services, some of which are predefined, but others may be custom. In our case we will be defining a Serial Port Profile (SPP) service, which is what the APP expects to find. Most of the code given in the example is taken from the Espressif spp_server example. I have named the profile as "CanHobby NeoPixels". It should be noted that BLE makes extensive us of UUIDs when naming service, attributes, characteristics etc. We do not need to acquire any of our own - we are using the predefined SPP profile. We will be using the Read Client feature to retrieve commands from the app to control tasks and animations in our code.
I need to make the disclaimer that this exploration is just that - a superficial example of how to accomplish this task - rather than a full blown application. It is up to the user to embellish with their own animations and possible control structures to integrate with the BLE APP.
In it's present form we see 4 tasks running animations on 3 strips. Strip 0 and 1 are running sample animations for the Espressif example which feature the use of sine functions to get smooth continuous variations of colour and intensity. I have included some much simpler animation for purposes of illustration. The animD and animD1 both run on the same strip, but in different segments so we can visualize the usage of segments. Their parameters are setup just before the tasks are created. Throughout the code we use strip structure to hold the parameters for each strip. There is an array of 5 segments, each of which can hold 9 parameters. The parameters do not have fixed names, although there is a set of logical definitions if we wish to use them for code readability.
Using the APP - If there are no other devices offering the SPP protocol near you the APP should default to connecting to our server. Just make sure we are on the BLE tab as opposed to BT Classic and hit the connect icon near the top. The APP should display connection success and we are ready to control our strips.
The BLE commands are divided into task and animation controls. They are very simple ACSII strings to make for easier parsing.
Task Control:
- Sx - Suspends Task #x (task # is in [ ] at the end of the TaskCreate call).
-Rx - Resumes a suspended task.
Animation Control:
- bxyz - changes strip 'x', segment 'y' brightness to 'z'.
Hint: z = Zero clears the strip, z = letter 'O' is max brightness.
- cxyz - changes strip 'x', segment 'y' to colour 'z'.
eg. "c010" will change the animation color to BLUE.
- dxyz - changes strip 'x', segment 'y' animation delay to 'z'.
Hint: z = Zero is very fast, z = letter 'O' is the slowest.
-C - clear.
If you find that the effects of a command seem to be incomplete, it is better to Suspend the task before issuing the command and then resume the task - alternatively just re-issue the command.
Note these control strings totally depend on the particular animation. The Espressif example animations will not act as expected.
I uploaded the complete BLE project to CanHobby. It is too big for github. Just create a separate directory called BLE and unzip it into that dir. Then open the dir as a workspace with the ESP-IDE.
Happy Exploring!!
CanHobby
remember - if you are looking to make your own PCBs with SMD/SMT technology there is no better provider than...
Comments
Please log in or sign up to comment.