This build turns an Arduino Nano ESP32 into a small web server that drives an FC-16 LED matrix signboard. You open a page in your browser, type a message, and it scrolls across the matrix in real time. It's a nice intro to combining a web UI with physical hardware output, no separate app needed.
The full tutorial, with every detail and the line-by-line code explanation, is on our site: Arduino Nano ESP32 - LED Matrix via Web
What you need
- Arduino Nano ESP32
- USB Cable Type-A to Type-C (for USB-A PC)
- USB Cable Type-C to Type-C (for USB-C PC)
- FC-16 LED Matrix 32x8
- Breadboard
- Jumper Wires
- DC Power Jack
- Screw Terminal Expansion Board for Arduino Nano
- Breakout Expansion Board for Arduino Nano
- Power Splitter for Arduino Nano ESP32
- DIYables Sensor Kit (18 sensors/displays)
Wiring
The FC-16 LED matrix (32x8, made of four cascaded 8x8 blocks) connects to the Arduino Nano ESP32, with its chip-select line going to pin D10 on the board (set as CS_PIN in the code). If you'd rather not rely on jumper wires that can slip out of the header pins, you can mount the Nano ESP32 on a Screw Terminal Expansion Board, which exposes every pin as a screw terminal and makes the same connections more secure.
How it works
The Arduino Nano ESP32 runs two things at once: a web server that serves an HTML/CSS/JavaScript page, and a WebSocket server. You could send the text over plain HTTP, but WebSocket keeps a persistent connection open between the browser and the board, so messages go through instantly and the page feels more responsive, without adding much extra complexity.
When you type a message on the web page and send it, the board receives it over the WebSocket connection, clears the LED matrix, and scrolls the new text across it using the MD_Parola library. The board also broadcasts a confirmation message back to connected clients.
Code
The project is split into two files in the Arduino IDE: the .ino sketch, which sets up the web server and WebSocket server and controls the LED matrix, and an index.h file holding the webpage's HTML, CSS and JavaScript. The sketch uses the DIYables ESP32 WebServer library for the web and WebSocket handling, and MD_Parola together with MD_MAX72xx to drive the FC-16 matrix. In onWebSocketMessage(), incoming text clears the display and starts a scrolling animation; onWebSocketOpen() and onWebSocketClose() handle connect and disconnect events. The sketch itself has comments explaining each part in detail.
arduino-nano-esp32-led-matrix-via-web.ino
/*
* This Arduino Nano ESP32 code was developed by newbiely.com
*
* This Arduino Nano ESP32 code is made available for public use without any restriction
*
* For comprehensive instructions and wiring diagrams, please visit:
* https://newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-led-matrix-via-web
*/
#include <DIYables_ESP32_WebServer.h>
#include "index.h"
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4 // 4 blocks
#define CS_PIN D10 // The Arduino Nano ESP32 pin
// WiFi credentials
const char WIFI_SSID[] = "YOUR_WIFI_SSID";
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
// Create web server instance
DIYables_ESP32_WebServer server;
DIYables_ESP32_WebSocket* webSocket;
// create an instance of the MD_Parola class
MD_Parola ledMatrix = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Web Page handlers
void handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) {
server.sendResponse(client, HTML_CONTENT);
}
// WebSocket event handlers
void onWebSocketOpen(net::WebSocket& ws) {
Serial.println("New WebSocket connection");
// Send welcome message
const char welcome[] = "Connected to ESP32 WebSocket Server!";
}
void onWebSocketMessage(net::WebSocket& ws, const net::WebSocket::DataType dataType, const char* message, uint16_t length) {
Serial.print("WebSocket Received (");
Serial.print(length);
Serial.print(" bytes): ");
Serial.println(message);
ledMatrix.displayClear(); // clear led matrix display
ledMatrix.displayScroll(message, PA_CENTER, PA_SCROLL_LEFT, 100);
// Broadcast response to all connected clients using the library
if (webSocket != nullptr) {
String response = "Displayed: " + String(message) + "on LED Matrix";
webSocket->broadcastTXT(response);
Serial.print("WebSocket sent (");
Serial.print(response.length());
Serial.print(" bytes): ");
Serial.println(response);
}
}
void onWebSocketClose(net::WebSocket& ws, const net::WebSocket::CloseCode code, const char* reason, uint16_t length) {
Serial.println("WebSocket client disconnected");
}
void setup() {
Serial.begin(9600);
delay(1000);
Serial.println("Arduino Nano ESP32 Web Server and WebSocket Server");
ledMatrix.begin(); // initialize the object
ledMatrix.setIntensity(15); // set the brightness of the LED matrix display (from 0 to 15)
ledMatrix.displayClear(); // clear led matrix display
ledMatrix.displayScroll("newbiely.com", PA_CENTER, PA_SCROLL_LEFT, 100);
// Configure web server routes
server.addRoute("/", handleHome);
// Start web server with WiFi connection
server.begin(WIFI_SSID, WIFI_PASSWORD);
// Enable WebSocket functionality
webSocket = server.enableWebSocket(81);
if (webSocket != nullptr) {
// Set up WebSocket event handlers
webSocket->onOpen(onWebSocketOpen);
webSocket->onMessage(onWebSocketMessage);
webSocket->onClose(onWebSocketClose);
} else {
Serial.println("Failed to start WebSocket server");
}
}
void loop() {
// Then handle HTTP requests
server.handleClient();
// Handle WebSocket
server.handleWebSocket();
if (ledMatrix.displayAnimate()) {
ledMatrix.displayReset();
}
}
Full tutorial
The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: https://newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-led-matrix-via-web

Top comments (0)