How to Build a Scrolling LED Matrix Message Board with ESP32
Display custom scrolling text on a MAX7219 dot matrix using five wires and two libraries
Updated

What you'll build
This guide produces a scrolling LED message board: an ESP32 and a MAX7219 8x32 dot matrix module displaying a looping set of messages, each one scrolling left across four cascaded 8×8 panels. You control the messages, scroll speed, and brightness directly in the code.
The MAX7219 handles LED multiplexing and brightness over SPI, and the MD_Parola library handles text rendering and scroll animation. Together they reduce this to a five-wire connection and a short sketch. The 4-in-1 module you will use has the four panels already chained on a single board, so there is only one connector to wire.
Adding new messages is a one-line change to a string array; the scroll loop picks them up on the next cycle.
What you are building
This guide covers a self-contained scrolling display. The firmware has three jobs:
- initialise the MAX7219 module over SPI and set brightness via
display.setIntensity(), - cycle through a
messages[]array, displaying each string as a left-scrolling animation viaMD_Parola, - log each message transition to Serial Monitor at 115200 baud so you can confirm the cycle is running.
Out of scope: Wi-Fi, live data feeds, multi-zone split-screen layouts, and button controls. The MD_Parola library supports all of those, but the starter sketch keeps things minimal so the display behaviour is easy to verify before adding complexity.
Upload and calibrate
Install the MD_Parola and MD_MAX72XX libraries, then flash the starter sketch from Schematik.
Two values are worth adjusting before or after flashing:
messages[]array — add, remove, or edit the quoted strings. The sketch picks up the count automatically fromsizeof(messages) / sizeof(messages[0]).display.setIntensity(4)— accepts 0 (dimmest) to 15 (brightest). Value 4 is comfortable at a normal desk viewing distance; lower it for evening use or to reduce power draw.
The third argument to displayScroll() is the scroll speed in milliseconds per step. The default is 40. Lower values scroll faster.
After flashing, Serial Monitor at 115200 baud should show LED Matrix Message Board ready followed by Now showing: <message> each time the display advances. If text scrolls backwards or panels appear in the wrong order, change HARDWARE_TYPE from MD_MAX72XX::FC16_HW to MD_MAX72XX::GENERIC_HW in the sketch.
Troubleshooting
- Display stays dark after power-on: confirm VCC is on the 5 V rail, not 3.3 V. Check GND is shared with the ESP32. Reseat DIN, CS, and CLK wires on GPIO 23, 5, and 18 respectively.
- Text scrolls in the wrong direction or panels are in the wrong order: change
HARDWARE_TYPEtoMD_MAX72XX::GENERIC_HW. Different module batches use different LED layouts. - Only some panels light up: the 4-in-1 module is a daisy chain; a broken solder joint between panel segments on the module PCB can drop the chain. Test continuity across the inter-panel connections on the module board.
- Serial Monitor shows
Now showing:but display is blank: the SPI clock speed may be too high for long or capacitive wires. Keep wires short, or adddisplay.setSPISettings()to reduce clock frequency. - Text appears garbled:
MAX_DEVICESmust match the number of chained 8×8 panels (4 for the standard 8×32 module). Confirm it is set to 4 in the sketch.
Going further
The sketch cycles through a fixed message array, but the display is equally happy with live content. Connect to Wi-Fi and pull a live feed — an open weather API, a countdown to an event, or a queue depth from a work dashboard — and pass the result string to displayScroll() on each cycle. A single physical button on a free GPIO can advance messages manually. If you want split-screen layouts or mixed fonts, MD_Parola supports zones: you can dedicate the left two panels to a clock and the right two to a scrolling news line without changing the wiring at all.
Wiring diagram
Components needed
| Component | Type | Qty | Buy |
|---|---|---|---|
| MAX7219 8x8 Dot Matrix Module, Assembled | display | 1 | €2.00 |
Supplier links, prices, and availability are shown as a guide and may change. Schematik may earn a commission from purchases made through affiliate links.
Assembly
Wire the LED matrix to the ESP32
Connect the MAX7219 module VCC to 5V, GND to GND, DIN to GPIO23, CS to GPIO5, and CLK to GPIO18.
- GPIO23 is the default VSPI MOSI pin, GPIO18 is VSPI CLK, and GPIO5 is VSPI SS, so this keeps your SPI bus on its default hardware pins.
- If the module has a 4-in-1 design, only the input header needs wiring. The four 8x8 panels are already daisy-chained.
- Power the matrix from the USB 5V rail, not the 3.3V pin. The MAX7219 needs 5V to drive the LEDs at full brightness.
Flash and test
Upload the sketch and open Serial Monitor at 115200 baud. You should see scrolling text across all four panels. Adjust display.setIntensity(4) from 0 to 15 to control brightness.
- If text scrolls backwards or panels appear in the wrong order, try changing HARDWARE_TYPE to MD_MAX72XX::GENERIC_HW.
- Lower intensity values save power and reduce eye strain at your desk.
Pin assignments
| Pin | Connection | Type |
|---|---|---|
| 5V | led-matrix-1 VCC | POWER |
| GND | led-matrix-1 GND | GROUND |
| GPIO 23 | led-matrix-1 DIN | SPI |
| GPIO 5 | led-matrix-1 CS | SPI |
| GPIO 18 | led-matrix-1 CLK | SPI |
Code
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define DATA_PIN 23
#define CS_PIN 5
#define CLK_PIN 18
MD_Parola display = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
const char *messages[] = {
"Hello from Schematik!",
"Build something cool",
"LED Matrix Demo",
"Maker life is best life"
};
const int NUM_MESSAGES = sizeof(messages) / sizeof(messages[0]);
int currentMsg = 0;
void setup() {
Serial.begin(115200);
delay(100);
display.begin();
display.setIntensity(4);
display.displayClear();
display.displayScroll(messages[currentMsg], PA_LEFT, PA_SCROLL_LEFT, 40);
Serial.println("LED Matrix Message Board ready");
}
void loop() {
if (display.displayAnimate()) {
currentMsg = (currentMsg + 1) % NUM_MESSAGES;
display.displayScroll(messages[currentMsg], PA_LEFT, PA_SCROLL_LEFT, 40);
Serial.printf("Now showing: %s\n", messages[currentMsg]);
}
}
// Run this and build other cool things at schematik.ioReady to build this?
Open this project in Schematik to get the full wiring diagram, pin assignments, and deployable code for the LED Matrix Message Board.
Open in Schematik →