ESP32 UNO - LED Matrix
Need a bright scrolling sign? Hook a MAX7219 LED matrix to the ESP32 Uno and print words, digits and moving messages with only a handful of Arduino lines. You can use a single 8x8 dot matrix module or a 32x8 FC-16 strip on the ESP32 Uno form board, and the same sketch scales to 16x8 or 64x8 panels.
What you will do:
- Connect a single-block and a four-block FC-16 dot matrix to the board
- Install MD_Parola together with its MD_MAX72XX helper
- Print aligned words, inverted text and a number on the LED display
- Slide a long message from right to left
- Resize the code for any MAX7219 chain length

Good to know: the ESP32 Uno has no on-board LED grid, so this guide always uses an external MAX7219 module from the parts list.
Components You Need
Or you can buy the following kits:
| 1 | × | DIYables Sensor Kit (18 sensors/displays) |
Additionally, some of these links are for products from our own brand, DIYables .
Overview of the MAX7219 Dot Matrix
At the end of this part, you know what a block is and how blocks form a bigger panel.

Makers mostly pick matrices with a MAX7219 driver chip, because they are low cost, chain together with five wires and have mature libraries.
| Term | Meaning |
|---|---|
| Block | One square of 8 x 8 = 64 LEDs |
| Driver | One MAX7219 chip per block, it scans the 64 LEDs for you |
| Module styles | Generic or FC-16 (the sketch must name the right one) |
| Chain | Several blocks linked in a row, data passes from one block to the next |
| Ready-made panels | 4-block (32x8) or 8-block (64x8) boards already joined |
| DIY panels | Single blocks you link by hand to reach any width |
You always tell the sketch how many blocks sit in the chain, so the library knows the panel width.
Pinout
By the end of this part, you can tell the input header from the output header on each block.

| Pin | Header | Role |
|---|---|---|
| VCC | Input | 5V supply |
| GND | Input | Ground |
| DIN | Input | Serial data in, goes to SPI MOSI on the board |
| CS | Input | Chip Select, goes to any free digital pin |
| CLK | Input | Serial clock, goes to SPI SCK on the board |
| VCC | Output | Feeds VCC of the next block |
| GND | Output | Feeds GND of the next block |
| DOUT | Output | Data out, goes to DIN of the next block |
| CS | Output | Feeds CS of the next block |
| CLK | Output | Feeds CLK of the next block |
ESP32 Uno Pinout
Your sketch talks in GPIO numbers, while the board's silk print shows Uno labels such as D9 or D11. Look up each label in this picture first, so every jumper lands on the right GPIO.

How to Connect
By the end of this part, the matrix gets data and power from the right places.
Only the input header of the first block ever touches the ESP32 Uno. The layout changes a little with the type of panel you own.
Option 1 — One 8x8 block
Wire the input header to the board. The output header stays empty.

This image is created using Fritzing. Click to enlarge image

This image is created using Fritzing. Click to enlarge image
Option 2 — A pre-joined 32x8 panel
The blocks are already linked on the PCB. Wire its input header to the board and leave its output header empty.

This image is created using Fritzing. Click to enlarge image
Option 3 — Single blocks you link yourself
- Run the first block's input header to the board.
- Join each block's output header to the input header of the block after it.
- Keep the output header of the final block empty.

This image is created using Fritzing. Click to enlarge image

This image is created using Fritzing. Click to enlarge image
| LED Matrix Pin | ESP32 Uno Pin |
|---|---|
| VCC | 5V from the external adapter |
| GND | GND (shared with the adapter) |
| DIN | D11 (GPIO23, SPI MOSI) |
| CS | D9 (GPIO13) |
| CLK | D13 (GPIO18, SPI SCK) |
Good to know: D11 and D13 are the default VSPI MOSI and SCK lines of the ESP32 Uno, so the library finds them with no extra setup. CS can move to any free output pin if you edit CS_PIN.
Power budget
A full-bright 32x8 panel can pull close to 1 A. Do not feed it from the board's 5V header. Use a 5V adapter for the panel; the same adapter can also run the ESP32 Uno. Tie every GND together.
WARNING
ESP32 Uno pins use 3.3V logic and are NOT 5V tolerant. In this circuit, data only flows from the board into the matrix, so no 5V signal reaches an ESP32 Uno pin. Most 5V MAX7219 boards read 3.3V high levels fine. If the panel shows stray dots or stays blank, put a 3.3V-to-5V level shifter on DIN, CS and CLK.
How the Sketch Is Built
By the end of this part, you know the six building blocks every MD_Parola sketch needs.
Step 1 — Include the libraries
Step 2 — Name the module style
Use FC16_HW for FC-16 boards or GENERIC_HW for generic ones.
Step 3 — Give the block count
A 4-in-1 panel holds 4 blocks.
Step 4 — Pick the CS pin
D9 on the header is GPIO13, and the code needs the GPIO number.
Step 5 — Create the display object
Step 6 — Start it in setup()
With these lines in place, you can print text, numbers and effects. The full sketches follow.
ESP32 Uno LED Matrix Code
This sketch targets a four-block 32x8 FC-16 panel and cycles through five screens, two seconds each. Set MAX_DEVICES to 1, 2 or 8 for an 8x8, 16x8 or 64x8 panel.
Upload and Test
- First time with this board? Set it up with ESP32 Uno - Getting Started before you continue.
- Build the circuit by following the wiring table above.
- Plug in the USB Type-C cable between the ESP32 Uno and your computer.
- Select the board in Arduino IDE: pick ESP32 Dev Module and the COM port of the board (CH340).
- Open Library Manager with the Libraries icon in the left bar.
- Add MD_Parola: type "MD_Parola" in the search box and press Install on that entry.
- Search for MD_Parola created by majicDesigns and click the Install button.
- Accept the helper library: the IDE asks for MD_MAX72XX as well. Press Install All.
- Search for MD_MAX72XX created by majicDesigns and click the Install button.
- Paste the sketch into a new Arduino IDE window.
- Press Upload and wait for "Done uploading".
- Check the panel: you get "Left", "Center", "Right", an inverted "Invert", then "1234", and the loop repeats.
- Pro tip: start testing at setIntensity(2) or so while the panel runs from USB power only. Raise it to 15 once the 5V adapter is connected.
Video Tutorial
See the ESP32 Uno build in action in the video below.
In the clip, the panel runs a small block-stacking game in portrait mode. Three push buttons shift the piece left, shift it right and turn it; keep the turn button pressed for a fast drop. A piezo buzzer beeps for moves, landed pieces, cleared rows and the end of a round. All buttons use the internal pull-up, so each one goes between its pin and GND.
| Part | ESP32 Uno Pin |
|---|---|
| Matrix CS | D9 (GPIO13) |
| Matrix DIN | D11 (GPIO23) |
| Matrix CLK | D13 (GPIO18) |
| Left button | D2 (GPIO26) |
| Right button | D3 (GPIO25) |
| Rotate button | D4 (GPIO17) |
| Buzzer | D6 (GPIO27) |
Good to know: the game seeds random() from analogRead on A0 (GPIO2). Leave A0 unconnected, so the pin floats and gives noise. GPIO2 is also a boot strapping pin, which is one more reason to keep it free here.
Code Explanation
At the end of this part, you can change what the first sketch prints.
| Code Part | What It Does |
|---|---|
| setTextAlignment(PA_LEFT / PA_CENTER / PA_RIGHT) | Places the next text at the left edge, the middle or the right edge |
| print("Left") | Draws a short word that fits on the panel |
| setInvert(true) | Lights the background and turns the letters dark |
| print(1234) | Shows a number without converting it to text first |
| delay(2000) | Holds each screen for two seconds |
Swap the words or the number, upload, and the panel shows your own five screens.
Scrolling Message Sketch for the ESP32 Uno Matrix
By the end of this part, a message longer than the panel slides smoothly across it.
A 32x8 panel fits about five characters. Scrolling moves longer text from right to left, so length no longer matters.
| Code Part | What It Does |
|---|---|
| displayScroll(text, PA_CENTER, PA_SCROLL_LEFT, 100) | Sets the message, the effect and a 100 ms frame time |
| displayAnimate() | Moves the text one frame each time loop() runs, returns true at the end |
| displayReset() | Starts the same scroll again from the right side |
Lower the 100 to make the text run faster. More effects are in the MD_Parola Library Reference.
ESP32 Uno vs UNO R4 for This Project
This table lists what changes when you move this matrix project from the UNO R4 to the ESP32 Uno.
| Item | Arduino UNO R4 | ESP32 Uno |
|---|---|---|
| Logic voltage | 5V | 3.3V |
| CS pin in code | 9 | 13 (D9 header) |
| SPI data and clock | D11 and D13 | D11 (GPIO23) and D13 (GPIO18) |
| Demo buttons and buzzer | 2, 3, 4 and 6 | 26, 25, 17 and 27 |
| Random seed pin | A0 | 2 (A0 header) |
| Arduino IDE board | Arduino UNO R4 WiFi or Minima | ESP32 Dev Module |
| WiFi and Bluetooth | WiFi on the WiFi model only | WiFi plus Bluetooth Classic and BLE |
The wiring images keep the same header spots, so the jumpers go in the same holes. Only the pin numbers in code change, and the libraries stay the same.
Go Wireless: Send Messages to the Panel from Your Phone
By the end of this part, you have an idea for a phone-controlled message board.
The ESP32 Uno has built-in WiFi and Bluetooth. Type a line in a chat page on your phone, and the board pushes it straight to displayScroll(). This turns the panel into a shop sign, a desk notice or a scoreboard that you update without a cable.
Try These Next
- Chain a second 32x8 panel and set MAX_DEVICES to 8 for a 64x8 sign.
- Swap PA_SCROLL_LEFT for another MD_Parola effect, such as a wipe or a fade.
- Show a live counter: increase a variable each second and print it.
- Add one push button on D2 (GPIO26) that switches between two messages.
Troubleshooting
| Problem | Possible Cause | Solution |
|---|---|---|
| No COM port appears in Arduino IDE | CH340 driver missing or a charge-only USB cable | Install the CH340 driver and use a data USB Type-C cable |
| Upload stops at Failed to connect or Waiting for download | Board did not enter download mode | Hold the BOOT button while the upload starts, then let go |
| All LEDs stay off | No 5V on VCC, GNDs not joined, or DIN and CLK swapped | Check the adapter, link all GNDs, and put DIN on D11 (GPIO23) and CLK on D13 (GPIO18) |
| Panel shows nothing but the code uploads | CS_PIN does not match the wire | Keep CS on D9 and CS_PIN at 13, or change both together |
| Letters appear backwards or upside down | Module style in code is wrong | Change FC16_HW to GENERIC_HW, or the other way, and upload again |
| Text is cut off or repeats per block | Block count is wrong | Make MAX_DEVICES equal to the real number of blocks |
| ESP32 Uno reboots when the panel gets bright | Panel pulls too much current through the board | Power the panel from the 5V adapter, or lower setIntensity() |
| Random dots and flicker | 3.3V signals are too weak or wires are long | Shorten the jumpers, or add a level shifter on DIN, CS and CLK |
| MD_Parola.h no such file | Library not installed | Install MD_Parola and press Install All for MD_MAX72XX |
FAQ
Is the LED matrix on this page the same as a built-in board matrix?
No. This page uses a separate MAX7219 module that you wire to the headers. The ESP32 Uno has no LED grid on the board, so any 8x8 or 32x8 MAX7219 module from the parts list works.
Do I need a level shifter between the ESP32 Uno and a 5V MAX7219 module?
Usually not. The data only goes from the 3.3V board to the module, and most MAX7219 chips accept 3.3V as a logic high. Add a level shifter only when the panel acts strangely.
Can the board's 5V header run a 32x8 panel?
Only for a dim test. At high brightness, the panel needs up to 1 A. Use a separate 5V adapter and connect its GND to the ESP32 Uno GND.
Which GPIO numbers does the ESP32 Uno use for the matrix SPI lines?
DIN goes to D11, which is GPIO23 (MOSI), and CLK goes to D13, which is GPIO18 (SCK). These are the default VSPI pins, so the library uses them with no setup. Only CS is set in code, here GPIO13.
Can I drive two separate matrix panels from one ESP32 Uno?
Yes. Either chain them into one longer panel and raise MAX_DEVICES, or give the second panel its own CS pin and create a second MD_Parola object. Both panels share DIN and CLK.
How do I change the scroll speed?
Change the last number in displayScroll(). It is the time per frame in milliseconds, so 50 runs faster and 200 runs slower.
Why is the CS pin 13 in the code when the wire goes to D9?
The ESP32 Uno header labels follow the Uno layout, but the chip only knows GPIO numbers. D9 is wired to GPIO13, so the sketch must use 13. GPIO9 is one of the flash pins, so writing 9 can crash the board.
Can I keep my UNO R4 LED matrix sketch on the ESP32 Uno?
Mostly yes. MD_Parola and MD_MAX72XX work on the ESP32 Uno with no change. You only replace the pin numbers with the GPIO numbers from the pinout, for example CS 9 becomes 13.
Does my UNO shield fit the ESP32 Uno for this project?
The headers have the Uno shape, so most shields plug in. Check that the shield runs at 3.3V logic and does not need A4/A5 for I2C, because on this board I2C sits on the SDA (GPIO21) and SCL (GPIO22) header pins.
What if my project needs more pins than the Uno headers give?
The ESP32 Uno has a few extra holes near the power header: GPIO32 and GPIO33 (I/O, PWM, analog on ADC1, so they also work while WiFi is on) and GPIO15 (I/O, PWM, analog on ADC2). To reach them, solder on a short pin header, then put that GPIO number in your sketch. For this project, GPIO32 or GPIO33 is a good choice for a second panel's CS pin or an extra game button. Two warnings: GPIO15 and GPIO0 (the IO0 pin at the unused Uno NC spot) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code, so use GPIO32/33 first. Never use the six holes under the digital header (SD0–SD3, CMD, CLK = GPIO6–GPIO11). They are wired to the flash chip, and using them crashes the board.
Can I update the scrolling message over WiFi?
Yes. The ESP32 Uno has WiFi and Bluetooth, so a web chat or Bluetooth chat app can send new text, and the sketch passes it to displayScroll(). See the Go Wireless section above for links.