|
Tiny-WS2812
1.0.0
A tiny cross-platform WS2812 LED Strip driver
|
Welcome to the Tiny-WS2812 documentation.
The Tiny-WS2812 library initially derived from the driver code of an open source WS2812 LED controller that I had worked on prior, and provides a nearly barebone interface to communicate with WS2812 devices.
The following platforms and frameworks are currently supported:
It has been developed out of the necessity to have an extremely light weight and flexible cross-platform library that can be further abstracted and used troughout my WS2812 projects, particullary on MCUs with severe memory constraints (ex. ATTiny and STM8S chips), where one cannot just define an RGB array equivalent to the number of LEDs. This libraries purpose is NOT to provide fancy abstractions and functions for color correction, brightness settings, animations etc.
To summerize, this library is inteded to:
It is perhaps also noteworthy to mention that this library provides a pretty decent base to implement more abstract WS2812 libraries for the STM8S platform, which is fairly sparse in terms of available libraries. Futher, it has come to my notice that the few WS2812 libraries that are available for the STM8S at the time of writing often lack documentation.
The WS2812 library code is split into two parts. The first part is the abstract library interface defined in ws2812.h. The second part is the platform specific driver code that implements the interface for different platforms. The platform specific library implementations can be found in the src directory. To use this library throughout your project, only an understanding of the library interface is required.
For C++ projects, the WS2812 library also offers a WS2812 C++ wrapper class. For an usage example of the C++ wrapper, refer to the blink_cpp example for the Arduino Framework or the blink_cpp example for barebone AVR programming
To make the use of this library a breeze, all source files have been documented and referenced using doxygen.
In the next section we will go through a basic example to get familiar with the library in no time.
The library has been primarily written with platformio in mind, but can be also be imported into the Arduino IDE and frankly, any other programming environment.
To import the library on platformio, simply look for its name in the extensions browser and download the extension.
Importing the library into the Arduino IDE is a little nasty, due to its limitations of now allowing one to define compile macros, as well as its incompatibility with c files. To still be able to import this project into the Arduino IDE, I have written a bash script to generate an Arduino-IDE compatible library, called makearduinolib.sh, which can be found in the tools/ folder of this project. To run it, simply execute:
The script will ask you to specify a target platform and produce a Arduio-IDE compatible library zip in the root folder of this project.
To use the Tiny-WS2812 library throughout your project, first ensure that you have specified the target platform for which the library is being build for. To do so, define one of the following build flags in your project:
WS2812_TARGET_PLATFORM_AVRWS2812_TARGET_PLATFORM_ARDUINO_AVRWS2812_TARGET_PLATFORM_STM8SSupport for more platforms (ex. ESP and ARM) is planned in the future.
Perhaps you may be wondering what the difference it makes to build for the barebone AVR target and the Arduino AVR target. While both targets can be effectively used for any AVR MCU based device, the barebone AVR target limits itself to the code provided by the AVR C libraries. The Arduino AVR target makes use of the code provided by the Arduino framework. The only difference relevant to the library user here is that the Arduino framework target will include the Arduino framework (which may not be desired or possible in some circumstances) and the differences in the library configuration struct (ws2812_cfg, more on that later), which is platform specific and is used to configure various library parameters (data output pin, reset time, color order etc.).
As for STM8S builds: The STM8S target currently requires the Standard Peripheral Library (SPL) to be included. In the future, there will likely be a version of the library that does not require the SPL.
In the following section we will working our way through the examples/arduino_avr/blink_array.c example. We assume our target platform to be ARDUINO_AVR, however most of the library specific code is the same across all platforms. Platform specific differences will be indicated.
Let's begin with the most obvious parts first. At the top of the code we import the ws2812.h header.
This header exposes the interface of the WS2812 library, in other words, it provides you with all of the relevant functions to drive WS2812 devices.
Following the header inclusion, we define some fixed macro parameters that you must adjust to your own setup.
The DATA_PINS parameter tells the library which Arduino pins are used to program WS2812 devices. As you may have noticed by now, the library has the option to drive multiple WS2812 devices in parallel. However, this feature may be platform specific and comes with some restrictions.
The RESET_TIME parameter tells the library how many microseconds it must wait after programming the WS2812 devices before it can program them from the first LED again. Should none of this make sense, it is highly advised to take a look at how WS2812 devices are driven.
The COLOR_ORDER parameters defines the color order in which the WS2812 LEDs must be written to. Unfortunately there is no fixed standard on the color order of WS2812 LEDs. Some are programmed in RGB order, however, from my own experience, GRB seems to be the most common order.
The remaining parameters, along with their comments, should be rather self explanatory.
Next up we have the following three defintions:
In the top definition we create an array that will tell the library which pins are used to drive WS2812 devices.
In the middle definition we create an array of RGB values equal to the number of LEDs. This RGB array will be used to program the WS2812 devices and act as virtual representation of the LEDs on the device(s).
The latter definition creates a WS2812 device struct instance which is used to drive one or more assigned WS2812 devices.
Continuing further down we define the setup function:
Within the setup() function we set the fields, we create a ws2812_cfg configuration struct and use it to configure our WS2812 device struct instance using the ws2812_config() function. The code should be rather self explanatory since it simply parses the parameter macros that we have already discussed above.
Next up we come to the loop() function, here we will make the device blink.
We start off by setting all RGB values in our LEDs array to white:
Now that the LED array has been filled with white, all that is left is to transmit its values to the WS2812 device(s):
First, we call ws2812_prep_tx() to prepare the host device and the device object for data tranmission. Following the ws2812_prep_tx() call we then transmit the rgb values of the RGB array to the WS2812 device(s). Finally, once we are done transmitting, we proceed to close the tranmission. The WS2812 device(s) should now be set to white.
Given that we have made it this far, the rest of the code should require little explanation, as we simply wait for a total of 500ms, set our device(s) to off using the exact same procedure that we have used to set it white, and lastly wait another 500ms. After that, everything simply gets repeated again and we should be seeing one or more blinking WS2812 devices.
In the example above we have used an RGB array to set the colors of one or more WS2812 devices. However, for cases like above, where we only wish to fill the entire device with a single color, allocating an RGB array equal to the number of LEDs seems like a memory expensive solution. Instead of allocating an array for all LEDs, we can simply repeatedly transmit the same color value to the WS2812 device(s) until all LEDs has been set. This much more memory friendly method is showcased in the blink_loop example.