Basic Fadecandy C++ Framework Tutorial

In this tutorial we will show you the basics of creating an LED program using the Fadecandy framework.

On Fadecandy’s GitHub page you will find out how to set up the hardware as well as find several software examples in different languages. We will concentrate on C++, which has the most powerful Fadecandy framework. To study the C++ framwork in detail, this is the place to go.

Also, have a look at this blogpost where we go into detail of how we built our interactive LED lamp where we use Fadecandy hardware and C++ software framework.

The Basic Setup

You can use the following code as sort of a template.

#include "lib/effect.h"
#include "lib/effect_runner.h"
#include "lib/color.h" //necessary for HSV to RGB conversion

#define MAX_FPS 60

class MyEffect : public Effect
{
public:
	MyEffect()
	{
		//initialize variables
	}

	virtual void beginFrame(const FrameInfo &f)
	{
		//runs once each frame
	}
	virutal void shader(Vec3& rgb, const PixelInfo &p) const
	{
		//runs once for each pixel per frame
	}

private:
	//declare variables
};

int main(int argc, char **argv)
{
	EffectRunner r;
	MyEffect e;
	r.setEffect(&e);
	r.setLayout("../layouts/myLayout.json");
	r.setMaxFrameRate(MAX_FPS);

	return r.main(argc, argv);
}

The most important aspects of this small chunk of code is the beginFrame() and shader() functions.

The beginFrame function

In the beginFrame() function you do things that should happen once each frame (the function is automatically called at the start of each frame). This can be calculations, event handling or timer-based stuff. A neat little trick to get a timer going is to write

timer += f.timeDelta;

inside the beginFrame() function (remember to declare timer as a float prior to this).

The shader function

This is where you actually do what you set out to do: setting a color on a pixel. This function is automatically called one time for each pixel per frame. So if you for instance have 128 LEDs, this function will be called 128 times as often as beginFrame().

We like to operate within the HSV domain when calculating colors (and we recommend you do that too) since you have more clearly defined components (hue, saturation and value) of a color to play with than within the RGB domain (red, green and blue). You can read more about HSV here.

When you have calculated the hue, saturation and value for a pixel (we can call these h, s and v, all floats between 0 and 1) you can use the hsv2rgb(rgb, h, s, v) function to set a color to a pixel. This function is found in color.h and should be called within the shader() function.

From the pixelinfo variable p you can get index, position and other information about the relevant pixel (study the header files in the “lib” folder for more info).

Max Frame Rate

When running relatively demanding LED programs on lesser hardware, such as the Raspberry Pi, you might want to set a maximum frame rate to keep the program running smoothly.

Look at line 34 in the code above to see how to set maximum frame rate.

In our interactive LED lamp we needed to reduce the max frame rate down to 30 fps to keep it from hogging all of the CPU resources on the Raspberry Pi. If the CPU can’t keep up, the LED program will stutter.

Mapping/Layout

You might’ve noticed the r.setLayout("../layouts/myLayout.json"); line in the code above. It is necessary to have a .json file which describes where each LED is positioned in space defined by a set of x,y,z coordinates. You can look at this section of Fadecandy’s GitHub for examples of how these .json files should look as well as some JavaScript examples of how to make these .json files. We made a Python script which made ours for the interactive LED lamp which you can look at under the “Mapping the LEDs” chapter in this post.

As soon as you have this layout you can make spatial programs without having to think about LED indexing and positioning, which is kinda nice.

The Mixer

Sometimes you might want to mix several programs or crossfade between some of them. This can be done using the mixer module of the framework. Imagine each program being an instrument going into the mixing table in a recording studio where you can adjust the faders for each instrument from 0 to 100%.

Here is an example of usage of the mixer.

Take note of lines 17 through 20 where they add the different programs/channels to the mixer using the function mixer.add(). In line 39 they call the function mixer.setFader() which set the fader value for each channel.

Another thing to take note of is that they’ve put each program within its own header file to make things a lot cleaner (highly recommended!).

Perlin Noise

You have access to simplex perlin noise functions called noise2() (2D) and noise3() (3D) which is really handy when you want to create an organic looking program. Perlin noise is used a lot in CGI and computer games to increase the realism in computer graphics. Read more about perlin noise here and study the framework implementation here.

Cuncluding Words

The Fadecandy C++ framework is a powerful framework for designing spatial LED programs. Utilize the example code and the framework implementation on Fadecandy’s GitHub page to get a deeper understanding of how to make cool looking programs.

Click this link to visit a forum where you can post questions and read answers regarding any Fadecandy-related issues.

Related Posts