Skip to main content

Overview

The app itself is very simple and consists of very few files. It basically provides an HTTP interface so it is able to receive commands from other components, initializes the core and updates it in an infinite loop.

The infinite loop only stops if an unexpected error happens or the program receives a SIGINT or SIGTERM signal for example Ctrl + C is pressed. Once the loop stops, the program terminates the HTTP server and makes a signal for the LED strips to turn off all the LEDs. It might happen that the program stops unexpectedly, in this case the LEDs stop in the last working state until the controller is restarted.

Core initialize

To initialize the core it has to provide 3 functions:

  • Log function

It is a simple function that receives a char* and returns nothing. For now it only puts the received parameter to the standard output. In the future it should be upgraded to use a proper log library.

  • Random function

This function receives 2 integer parameters which determines the range and returns a random integer. To make it happen it uses the C++11 random library and its default random engine with a uniform integer distribution.

  • Delay function

This function receives a delay value a callback function and its void** arguments. It has to call the callback function with its arguments after the specified time. Obviously this waiting cannot be blocking so it has to create a different thread. It uses the C++11 thread library to achieve this. This thread is detached since doesn't have to synchronize with any other threads. With the help of the sleep_for function it waits for the specified time in a non-blocking manner then it just simply calls the callback function.

Main loop

The main loop is the one that calls the tick function of the core that constantly updates the state of the LEDs and calls a function which fills a buffer with the data. The buffer fill function is called for every LED of every strip and it receives the color data in an array of size 3. Each element of the array represents the intensity of the R,G,B colors respectively. The task of this function is to convert this representation of the LED colors and forward it to the library that creates the digital signal.

The main loop has to be called periodically to update the state of the LEDs. The more frequently it is called the smoother the animations are but it also takes more computing power. For now, it is set to execute 60 times every second uniformly, but it might have to be changed in the future based on the length of the strips and the Raspberry PI version.

Dependencies

The component has 2 dependencies besides the core.

rpi_ws281x

The rpi_ws281x makes it possible to control the pins of the Raspberry programmatically. It has to be initialized with the length of the connected LED strips and a few other metadata. A simple Raspberry is able to control 2 different strips on 2 independent channels. These channels can be initialized differently.

The render function of this library is called in the main loop after the tick function fills the buffer for every LED. The render function expects an array filled with 32 bit numbers each representing an array. The first 8 bit represents the R channel, the second 8 bit represents the G channel and the third 8 bit represents the B channel. The last 8 bit is not used. This is the representation that has to be made by the buffer fill function.

cpp-httplib

The cpp-httplib makes it possible to create an HTTP server and this is key to control the animations from other components like a web based frontend or a mobile device. The exact interface is detailed in the HTTP interface section.