This tutorial does not work with the Pi 4 - no ETA on when it may be fixed!

To install the software for this project you'll first want to make sure your Raspberry Pi is running the latest version of the Raspbian operating system.  Using the Raspbian Jessie version is recommended.

You will also want to make sure your Raspberry Pi is connected to the internet through a wired or wireless connection as you follow the steps below.  Software and dependencies will be downloaded from the internet and installed on the Pi.


Connect to a terminal on the Raspberry Pi using SSH and execute the following commands to download dependencies:

sudo apt-get update
sudo apt-get install -y build-essential git libconfig++-dev

Next download the code for this project from its home on GitHub by running:

cd ~
git clone --recursive
cd rpi-fb-matrix

Make sure to use the --recursive so that the required git submodule is installed too!

After the code has been downloaded you're ready to compile it.  If you're using a Raspberry Pi 2 and the RGB LED matrix HAT you're ready to go and can skip down to the compile command.  However if you're using an original Pi or manually wired your Pi to the matrices you might need to adjust some compilation options.

In the Makefile this line at the top sets compilation options for the rpi-rgb-led-matrix library:

# Configure the rpi-rgb-led-matrix library here:
# The -DADAFRUIT_RGBMATRIX_HAT value configures the library to use the Adafruit
# LED matrix HAT wiring, and the -DRGB_SLOWDOWN_GPIO=1 value configures the
# library to work with a Raspberry Pi 2.  For a Pi 1 (or perhaps even on a Pi 2,
# but I found it necessary in my testing) you can remove the -DRGB_SLOWDOWN_GPIO=1
# option.  You can also add any other rpi-rgb-led-matrix library defines here
# to configure the library for more special needs.  See the library's docs for
# details on options:

Like the comments mention adjust the options as necessary for your setup.  See the rpi-rgb-led-matrix library Makefile for a description of available options.

To compile the code run the following command:

make clean all

The code should compile without error and finish with output similar to:

g++ -c -o rpi-fb-matrix.o rpi-fb-matrix.cpp -Wall -std=c++11 -O3 -I. -I./rpi-rgb-led-matrix/include -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host -I/opt/vc/include/interface/vmcs_host/linux -L./rpi-rgb-led-matrix/lib -L/opt/vc/lib
g++ -c -o GridTransformer.o GridTransformer.cpp -Wall -std=c++11 -O3 -I. -I./rpi-rgb-led-matrix/include -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host -I/opt/vc/include/interface/vmcs_host/linux -L./rpi-rgb-led-matrix/lib -L/opt/vc/lib
g++ -c -o Config.o Config.cpp -Wall -std=c++11 -O3 -I. -I./rpi-rgb-led-matrix/include -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host -I/opt/vc/include/interface/vmcs_host/linux -L./rpi-rgb-led-matrix/lib -L/opt/vc/lib
make -C ./rpi-rgb-led-matrix/lib
make[1]: Entering directory '/home/pi/rpi-fb-matrix/rpi-rgb-led-matrix/lib'
g++ -I../include -Wall -O3 -g -fPIC -DADAFRUIT_RGBMATRIX_HAT -DRGB_SLOWDOWN_GPIO=1 -DRGB_SLOWDOWN_GPIO=1 -c -o led-matrix.o
g++ -I../include -Wall -O3 -g -fPIC -DADAFRUIT_RGBMATRIX_HAT -DRGB_SLOWDOWN_GPIO=1 -DRGB_SLOWDOWN_GPIO=1 -c -o framebuffer.o
g++ -I../include -Wall -O3 -g -fPIC -DADAFRUIT_RGBMATRIX_HAT -DRGB_SLOWDOWN_GPIO=1 -DRGB_SLOWDOWN_GPIO=1 -c -o thread.o
g++ -I../include -Wall -O3 -g -fPIC -DADAFRUIT_RGBMATRIX_HAT -DRGB_SLOWDOWN_GPIO=1 -DRGB_SLOWDOWN_GPIO=1 -c -o bdf-font.o
g++ -I../include -Wall -O3 -g -fPIC -DADAFRUIT_RGBMATRIX_HAT -DRGB_SLOWDOWN_GPIO=1 -DRGB_SLOWDOWN_GPIO=1 -c -o graphics.o
g++ -I../include -Wall -O3 -g -fPIC -DADAFRUIT_RGBMATRIX_HAT -DRGB_SLOWDOWN_GPIO=1 -DRGB_SLOWDOWN_GPIO=1 -c -o transformer.o
ar rcs librgbmatrix.a gpio.o led-matrix.o framebuffer.o thread.o bdf-font.o graphics.o transformer.o
make[1]: Leaving directory '/home/pi/rpi-fb-matrix/rpi-rgb-led-matrix/lib'
g++ -o rpi-fb-matrix rpi-fb-matrix.o GridTransformer.o Config.o rpi-rgb-led-matrix/lib/librgbmatrix.a -Wall -std=c++11 -O3 -I. -I./rpi-rgb-led-matrix/include -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host -I/opt/vc/include/interface/vmcs_host/linux -L./rpi-rgb-led-matrix/lib -L/opt/vc/lib -lrgbmatrix -lrt -lm -lpthread -lbcm_host -lconfig++
g++ -c -o display-test.o display-test.cpp -Wall -std=c++11 -O3 -I. -I./rpi-rgb-led-matrix/include -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host -I/opt/vc/include/interface/vmcs_host/linux -L./rpi-rgb-led-matrix/lib -L/opt/vc/lib
cc    -c -o glcdfont.o glcdfont.c
g++ -o display-test display-test.o GridTransformer.o Config.o glcdfont.o rpi-rgb-led-matrix/lib/librgbmatrix.a -Wall -std=c++11 -O3 -I. -I./rpi-rgb-led-matrix/include -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host -I/opt/vc/include/interface/vmcs_host/linux -L./rpi-rgb-led-matrix/lib -L/opt/vc/lib -lrgbmatrix -lrt -lm -lpthread -lbcm_host -lconfig++

That's all there is to compiling the project code!  Once the code has compiled you're ready to start configuring and testing the display.

If the compilation fails with an error go back and check that all of the previous steps have been completed, and that you're using the Raspbian Jessie operating system.


The software for this project is configured with a simple text configuration file.  An example configuration is provided in the matrix.cfg file.  You can use this file as a base and edit it for your specific display.

Open the file with the nano text editor by running:

nano matrix.cfg

You can scroll through the file and read a description of each configuration value in the comments (comments are lines that start with a // and won't be interpreted as configuration).

The first two settings define the total pixel width and height of the display:

// Define the entire width and height of the display in pixels.
// This is the _total_ width and height of the rectangle defined by all the
// chained panels.  The width should be a multiple of the panel pixel width (32),
// and the height should be a multiple of the panel pixel height (8, 16, or 32).
display_width = 64;
display_height = 64;

The next settings define the pixel width and height of an individual panel:

// Define the width of each panel in pixels.  This should always be 32 (but can
// in theory be changed).
panel_width = 32;

// Define the height of each panel in pixels.  This is typically 8, 16, or 32.
// NOTE: Each panel in the display _must_ be the same height!  You cannot mix
// 16 and 32 pixel high panels for example.
panel_height = 32;

The chain length setting configures the number of panels that are connected together into a single chain:

// Define the total number of panels in each chain.  Count up however many
// panels are connected together and put that value here.  If you're using
// multiple parallel chains count each one up separately and pick the largest
// value for this configuration.
chain_length = 4;

The parallel count defines how many chains of panels are connected to the Pi in parallel.  Remember the Adafruit HAT only supports one parallel chain.

// Define the total number of parallel chains.  If using the Adafruit HAT you
// can only have one chain so stick with the value 1.  The Pi 2 can support up
// to 3 parallel chains, see the rpi-rgb-led-matrix library for more information:
parallel_count = 1;

Next the individual panels of the display are configured by the panels setting.  This setting is a two-dimensional list of panel configurations.  Each panel configuration defines which panel will display that portion of the Pi's screen.  For example the configuration in the first row and first column will define which LED panel displays the top left portion of the screen.

Panels are identified by their order along the chain of panels.  The first panel connected to the Pi is order 0, the next panel is order 1, etc.

In addition to the order each panel configuration can have a unique rotation applied to it.  This allows you to compensate for panels which are rotated relative to each other as they snake around to form a display.  The rotation is a value in degrees and can only be 0, 90, 180, or 270.  You'll see in a moment a tool that helps check and determine which rotation values are needed for the panels.

For example a 4 panel square display might be wired as follows:

This display would have a panels configuration value that looks like:

panels = (
  ( { order = 3; rotate = 180; }, { order = 2; rotate = 180; } ),
  ( { order = 0; rotate =   0; }, { order = 1; rotate =   0; } )

Notice that there are two rows and two columns of panel settings (the panel settings are the values inside the curly braces { }, and the parenthesis indicate the panels in a row).

The order for each panel is set exactly as shown in the diagram, and a rotation of 180 degrees is applied to the top row of panels.  These top panels need to be rotated because they are in a different orientation compared to the bottom panels.  If no rotation was applied then the top row would be flipped and the display wouldn't look right.

If you aren't sure how to set the rotation don't worry you will see how to use a tool in the next section to check the rotations.  Just give each panel a rotation of zero and move on to adjust it later.

Also it's not shown here but each panel entry can set a 'parallel = x;' value where x defines which parallel channel (0, 1, or 2) the panel is associated with.  Remember each parallel channel will have a unique ordering of panels so be sure to set the panel order based on where it is along that parallel chain.  Parallel chains aren't supported on the LED matrix HAT, only if you're manually wiring matrices to GPIO.

The final setting is an optional one to enable the display of a cropped portion of the Pi's video output.  This allows you to see a pixel-perfect part of the Pi's video output instead of shrinking down the entire image.

// By default the rpi-fb-matrix tool will resize and scale down the screen
// to fit the resolution of the display panels.  However you can instead grab
// a specific pixel-perfect copy of a region of the screen by setting the x, y
// screen pixel coordinates below.  A rectangle of the exact size of the display
// (i.e. display_width x display_height pixels) will be copied from the screen
// starting at the provided x, y coordinates.  Comment this out to disable
// this crop behavior and instead resize the screen down to the matrix display.
//crop_origin = (0, 0)

To enable the crop behavior just remove the // comment from the line and set the X and Y coordinate that you'd like to define as the upper left corner of the crop rectangle on the screen.  The width and height of the crop rectangle will be set as the display width and height.

Once you're done editing the file you can save it and exit nano by pressing Ctrl-s then enter, and then Ctrl-x.

Display Test

A useful part of the software for this project is the display-test tool which will print out the row and column of the Pi video display region associated with each panel.  You can run the tool by pointing it at a matrix.cfg file (being careful to run the tool as root with sudo):

sudo ./display-test matrix.cfg

Once running the LED matrix panels should light up with text on each panel.  For example you might see something like:

The text on a panel should be printed in its upper left corner.  If the text is not in that corner then the rotation for that panel needs to be adjusted.  You can see in the photo above the bottom row of panels do not have the right rotation.  To fix this problem the matrix.cfg should be edited and a rotation of 180 degrees should be applied to those panels.

On each panel the column, row of the display region associated with that panel will be printed.  For example the picture above shows the top left panel is displaying the second column and second row (the numbers are zero-based) of the display.  However this is not correct, instead we should expect to see the top left panel displaying the first column and first row, or 0,0 value.  Again the matrix.cfg should be edited and the order of the panels adjusted so they follow the chain from the Raspberry Pi.

With both those problems fixed the tool now displays what you want to see:

All of the panels have the correct orientation with text in the upper left.  In addition the values on each panel are displaying the right order of columns and rows.  Make adjustments to your matrix.cfg panel settings until the display-test tool gives output just like the above.

Running The Program

Once you've configured and tested your display you're ready to run the program that will copy the Pi's video output to the panels.

First make sure a TV or monitor is connected to the HDMI port on the Pi and that you see video output like a terminal or X windows (don't worry you'll learn how to make the panel work without a TV/monitor being connected in the next section).

Now run the rpi-fb-matrix program and point it at your configuration (again running as root with sudo):

sudo ./rpi-fb-matrix matrix.cfg

Woo hoo, you should see the video from the Pi shrunken down and displayed on the matrices!  Try running a game or other graphical application to see how it looks on the display.

You might see some flickering from the LEDs.  This is normal and a side-effect of the Raspberry Pi's Linux operating system trying to drive matrices that need constant refreshing.  Big commercial LED signs use fast FPGA or other dedicated drivers, but the Raspberry Pi is much simpler and can only give a 'best effort' at driving the matrices.  If you're watching a movie, playing a game, or displaying things that have some motion the flickering is generally not noticeable.  The amount of load on the Raspberry Pi CPU will also affect the LED flickering, so try to keep the load low (and the multiple cores of the Pi 2 will greatly help!).

If you notice portions of the screen that seem to be jumbled or rotated the wrong way you might need to adjust your configuration.  Go back to the display test section above and carefully check the configuration using that tool.

When you're finished press Ctrl-C to end the program.  That's really all there is to the Raspberry Pi LED matrix display!  Simply run the program in the background (perhaps even configuring it to run automatically on boot) and it will mirror whatever is displayed by other programs running on the Pi.

Force HDMI Output & Resolution

If you don't plan to have a monitor or TV connected to the Pi you can adjust some configuration to turn on the Pi's HDMI output even with no display connected.  This is necessary to make sure a primary display is available for the rpi-fb-matrix program to copy from.

The configuration you want to change is described in the 5" HDMI monitor display guide.  Specifically edit the /boot/config.txt file on the Pi and adjust it so the following sections are uncommented and added:

# uncomment if hdmi display is not detected and composite is being output
# uncomment to force a specific HDMI mode (here we are forcing 800x480!)
hdmi_cvt 1024 768 60 6 0 0 0

The hdmi_cvt line in particular is important because it defines the resolution that will be forced on the HDMI display, like 1024x768 pixels as shown above.  You can even change this to a square value like 1024x1024 pixels if you're using a square display.

After modifying the /boot/config.txt reboot the Pi for the change to take effect.

I recommend keeping the display at a large value like 1024 pixels instead of trying to set it to the exact dimensions of your LED matrix display.  This will help prevent issues with programs that might not handle such a tiny resolution, but will still scale down well to the matrices.  Experiment with differerent sizes to see what works best for your configuration.

That's all there is to the Raspberry Pi LED matrix display project!

This guide was first published on Dec 18, 2015. It was last updated on Dec 18, 2015.

This page (Software) was last updated on Dec 16, 2015.

Text editor powered by tinymce.