Am a newbie, learning to use this fantastic library in my own test program. And would like some help, please?
What I’ve done so far:
- I use a Raspberry Pi 4B, with DietPi.
- Have Waveshare 64x32 RGB panels; Chain=3, Parallel=3
- Have changed “hardware-mapping.c” file, swapping blue and green pins in ‘regular’, and have then done a remake on the rpi-rgb-led-matrix, examples-api-use and utils directories. All to stop having to use
–led-rgb-sequence=rbg
in the command-flags, successfully. Now all examples in those directories work correctly without having to use that particular flag!! - Am using VS Code to SSH in. And have copied the relevant lines of code within demo-main.cc that “ColourPulseGenerator” (or
sudo ./demo -D4
) uses in my own C++ file, called Colour_Changer_01.cc - Within the directory /home/dietpi/, are the directories /rpi-rgb-led-matrix, and /My_RGB_Matrix_Code
- I have put Colour_Changer_01.cc in a subdirectory here; /home/dietpi/My_RGB_Matrix_Code/Code_01/
- I have copied the Makefile from /examples-api-use into this same directory. And altered it. But am having trouble getting it to make my C++ file.
I would like help, as the makefile is my stumbling block right now, I think.
Here’s what I’ve got, (and I know it’s wrong):
CFLAGS=-Wall -O3 -g -Wextra -Wno-unused-parameter
CXXFLAGS=$(CFLAGS)
OBJECTS=Colour_Changer_01.o
BINARIES=Colour_Changer_01
# Where our library resides. You mostly only need to change the
# RGB_LIB_DISTRIBUTION, this is where the library is checked out.
RGB_LIB_DISTRIBUTION= ../home/dietpi/rpi-rgb-led-matrix
RGB_INCDIR=$(RGB_LIB_DISTRIBUTION)/include
RGB_LIBDIR=$(RGB_LIB_DISTRIBUTION)/lib
RGB_LIBRARY_NAME=rgbmatrix
RGB_LIBRARY=$(RGB_LIBDIR)/lib$(RGB_LIBRARY_NAME).a
LDFLAGS+=-L$(RGB_LIBDIR) -l$(RGB_LIBRARY_NAME) -lrt -lm -lpthread
# To compile image-example
MAGICK_CXXFLAGS?=$(shell GraphicsMagick++-config --cppflags --cxxflags)
MAGICK_LDFLAGS?=$(shell GraphicsMagick++-config --ldflags --libs)
all : $(BINARIES)
$(RGB_LIBRARY): FORCE
$(MAKE) -C $(RGB_LIBDIR)
Colour_Changer_01 : Colour_Changer_01.cc
# All the binaries that have the same name as the object file.q
% : %.o $(RGB_LIBRARY)
$(CXX) $< -o $@ $(LDFLAGS)
image-example.o : image-example.cc
$(CXX) -I$(RGB_INCDIR) $(CXXFLAGS) $(MAGICK_CXXFLAGS) -c -o $@ $<
image-example: image-example.o $(RGB_LIBRARY)
$(CXX) $< -o $@ $(LDFLAGS) $(MAGICK_LDFLAGS)
# Since the C example uses the C++ library underneath, which depends on C++
# runtime stuff, you still have to also link -lstdc++
c-example : c-example.o $(RGB_LIBRARY)
$(CC) $< -o $@ $(LDFLAGS) -lstdc++
%.o : %.cc
$(CXX) -I$(RGB_INCDIR) $(CXXFLAGS) -c -o $@ $<
%.o : %.c
$(CC) -I$(RGB_INCDIR) $(CFLAGS) -c -o $@ $<
clean:
rm -f $(OBJECTS) $(BINARIES)
FORCE:
.PHONY: FORCE
When I run it, the error is that the “led-matrix.h” file isn’t found.
For reference, this is the C++ file I’m toying with and learning from (Colour_Changer_01.cc):
// Name: Colour_Changer_01.cc
// Date: 2025/08/18
// Raspberry Pi 4B, with Waveshare 64x32 rgb led matrix
// Command line flags usually used: --led-cols=64 --led-rows=32 --led-chain=3 --led-parallel=3 --led-slowdown-gpio=2 --led-gpio-mapping=regular
// Notes:
// - Try to get the RGB LED Matrix to display colours, for a few seconds, then change to another colour, and loop infinitely
// - Copying from demo-main.cc in /rpi-rgb-led-matrix/examples-api-use
// - This should work without the usual command flags (see above) after the "-D4"
// - To run this: sudo ./demo -D4
// Start of copying from demo-main.cc
#include "led-matrix.h"
#include "pixel-mapper.h"
#include "graphics.h"
#include <assert.h>
#include <getopt.h>
#include <limits.h>
#include <math.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <algorithm>
using std::min;
using std::max;
#define TERM_ERR "\033[1;31m"
#define TERM_NORM "\033[0m"
using namespace rgb_matrix;
volatile bool interrupt_received = false;
static void InterruptHandler(int signo) {
interrupt_received = true;
}
class DemoRunner {
protected:
DemoRunner(Canvas *canvas) : canvas_(canvas) {}
inline Canvas *canvas() { return canvas_; }
public:
virtual ~DemoRunner() {}
virtual void Run() = 0;
private:
Canvas *const canvas_;
};
// Simple generator that pulses through RGB and White.
class ColorPulseGenerator : public DemoRunner {
public:
ColorPulseGenerator(RGBMatrix *m) : DemoRunner(m), matrix_(m) {
off_screen_canvas_ = m->CreateFrameCanvas();
}
void Run() override {
uint32_t continuum = 0;
while (!interrupt_received) {
usleep(5 * 1000);
continuum += 1;
continuum %= 3 * 255;
int r = 0, g = 0, b = 0;
if (continuum <= 255) {
int c = continuum;
b = 255 - c;
r = c;
} else if (continuum > 255 && continuum <= 511) {
int c = continuum - 256;
r = 255 - c;
g = c;
} else {
int c = continuum - 512;
g = 255 - c;
b = c;
}
off_screen_canvas_->Fill(r, g, b);
off_screen_canvas_ = matrix_->SwapOnVSync(off_screen_canvas_);
}
}
private:
RGBMatrix *const matrix_;
FrameCanvas *off_screen_canvas_;
};
static int usage(const char *progname) {
fprintf(stderr, "usage: %s <options> -D <demo-nr> [optional parameter]\n",
progname);
fprintf(stderr, "Options:\n");
fprintf(stderr,
"\t-D <demo-nr> : Always needs to be set\n"
);
rgb_matrix::PrintMatrixFlags(stderr);
fprintf(stderr, "Demos, choosen with -D\n");
fprintf(stderr, "\t0 - some rotating square\n"
"\t1 - forward scrolling an image (-m <scroll-ms>)\n"
"\t2 - backward scrolling an image (-m <scroll-ms>)\n"
"\t3 - test image: a square\n"
"\t4 - Pulsing color\n"
"\t5 - Grayscale Block\n"
"\t6 - Abelian sandpile model (-m <time-step-ms>)\n"
"\t7 - Conway's game of life (-m <time-step-ms>)\n"
"\t8 - Langton's ant (-m <time-step-ms>)\n"
"\t9 - Volume bars (-m <time-step-ms>)\n"
"\t10 - Evolution of color (-m <time-step-ms>)\n"
"\t11 - Brightness pulse generator\n");
fprintf(stderr, "Example:\n\t%s -D 1 runtext.ppm\n"
"Scrolls the runtext until Ctrl-C is pressed\n", progname);
return 1;
}
int main(int argc, char *argv[]) {
int demo = -1;
int scroll_ms = 30;
const char *demo_parameter = NULL;
RGBMatrix::Options matrix_options;
rgb_matrix::RuntimeOptions runtime_opt;
// These are the defaults when no command-line flags are given.
matrix_options.rows = 32; // Kept the same
matrix_options.cols = 64; // Not originally included
matrix_options.chain_length = 3; // Originally = 1
matrix_options.parallel = 3; // Originally = 1
matrix_options.slowdown.gpio = 2; // Not originally included
matrix_options.gpio.mapping = "regular"; // Not originally included
// First things first: extract the command line flags that contain
// relevant matrix options.
if (!ParseOptionsFromFlags(&argc, &argv, &matrix_options, &runtime_opt)) {
return usage(argv[0]);
}
int opt;
while ((opt = getopt(argc, argv, "dD:r:P:c:p:b:m:LR:")) != -1) {
switch (opt) {
case 'D':
demo = atoi(optarg);
break;
case 'm':
scroll_ms = atoi(optarg);
break;
default: /* '?' */
return usage(argv[0]);
}
}
if (optind < argc) {
demo_parameter = argv[optind];
}
if (demo < 0) {
fprintf(stderr, TERM_ERR "Expected required option -D <demo>\n" TERM_NORM);
return usage(argv[0]);
}
RGBMatrix *matrix = RGBMatrix::CreateFromOptions(matrix_options, runtime_opt);
if (matrix == NULL)
return 1;
printf("Size: %dx%d. Hardware gpio mapping: %s\n",
matrix->width(), matrix->height(), matrix_options.hardware_mapping);
Canvas *canvas = matrix;
// The DemoRunner objects are filling
// the matrix continuously.
DemoRunner *demo_runner = NULL;
switch (demo) {
case 0:
case 1:
case 2:
case 3:
case 4:
demo_runner = new ColorPulseGenerator(matrix);
break;
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
}
if (demo_runner == NULL)
return usage(argv[0]);
// Set up an interrupt handler to be able to stop animations while they go
// on. Each demo tests for while (!interrupt_received) {},
// so they exit as soon as they get a signal.
signal(SIGTERM, InterruptHandler);
signal(SIGINT, InterruptHandler);
printf("Press <CTRL-C> to exit and reset LEDs\n");
// Now, run our particular demo; it will exit when it sees interrupt_received.
demo_runner->Run();
delete demo_runner;
delete canvas;
printf("Received CTRL-C. Exiting.\n");
return 0;
}
// End of copying from demo-main.cc
Any help on how to make the make file work would be great.
Sorry if this is an obvious thing, but am muddling through the learning process (with a lot of fun)
Thank you