Build Your First ESP32 LED Display: Send Text from Your Mobile

Imagine a small red LED display sitting on your desk.

You open a webpage on your phone, type WELCOME, and press Send. A moment later, the same word begins moving across the LED matrix.

It feels like a tiny digital signboard made just for you.

The best part? You do not need a special mobile app, Bluetooth module, or cloud service. The ESP32 creates the webpage, receives the message through Wi-Fi, and sends it to the MAX7219 display.

If this is your first Wi-Fi project with an ESP32, do not worry. We will build it slowly and understand what every part is doing.


What Are We Building?

We are building a mobile-controlled Wi-Fi LED message display using:

  • An ESP32 development board
  • A MAX7219 4-in-1 LED dot-matrix module
  • A mobile phone

The four MAX7219 matrices work together as one long 32 × 8 pixel display.

When you enter a message from your mobile:

  • A short message stays centred on the display.
  • A longer message scrolls smoothly from right to left.
  • A new message replaces the old message immediately.

The complete flow is:

Mobile phone → Wi-Fi webpage → ESP32 → MAX7219 LED display

That simple flow is the heart of this project.


Why Is This a Good Beginner Project?

Many beginner projects stop after blinking an LED. This one takes you one step further without becoming too difficult.

While building it, you will learn:

  • How to connect a MAX7219 display to an ESP32
  • How the ESP32 creates a small web server
  • How a phone sends text to the ESP32
  • How short and long messages can behave differently
  • How to control scrolling speed and display brightness

You are not merely displaying text. You are making two devices communicate.

That is where an ordinary circuit starts feeling like a real product.


Components Required

ComponentQuantityPurposeBuying link
ESP32 Development Board1Runs the webpage and controls the displayBuy ESP32 on Amazon
MAX7219 4-in-1 LED Matrix Module1Displays the messageBuy MAX7219 on Amazon
Female-to-Female Jumper Wires5Connects the ESP32 and MAX7219Buy Jumper Wires on Amazon
USB Cable1Uploads the program and powers the ESP32

Affiliate note: Some links are Amazon affiliate links — if you buy through them, I may earn a small commission at no extra cost to you, which helps support this site.


ESP32 and MAX7219 Connections

Disconnect the USB cable before making or changing the wiring.

Use the connector marked IN on the MAX7219 module. Do not connect the ESP32 to the OUT side.

MAX7219 pinESP32 pin
VCCVIN / 5V
GNDGND
DINGPIO 23
CSGPIO 5
CLKGPIO 18

What Do These Pins Do?

VCC and GND provide power to the display.

DIN carries the display data. The ESP32 uses this line to tell the MAX7219 which LEDs should glow.

CLK provides the clock pulses that move each data bit into the display.

CS tells the MAX7219 when a complete set of data is ready to use.

Do not worry if these terms feel new. For this project, the important thing is to connect each pin exactly as shown.


Install the Required Libraries

Open the Arduino IDE and go to:

Tools → Manage Libraries

Search for and install:

  1. MD_Parola by MajicDesigns
  2. MD_MAX72XX by MajicDesigns

MD_MAX72XX controls the LED hardware. MD_Parola gives us useful text effects such as scrolling and centring.

The WiFi and WebServer libraries come with the ESP32 board package. Do not install a random separate WebServer library.


Before Uploading the Code

You must change these two lines:

const char* ssid = "YOUR_WIFI_NAME";
const char* password = "YOUR_WIFI_PASSWORD";

Replace them with your Wi-Fi name and password.

Keep the quotation marks.


Complete ESP32 Code

Copy the complete program below into a new Arduino IDE sketch.


// BlueDot Electronics
// ESP32 + MAX7219 Mobile Wi-Fi LED Message Display
// Short text: centred
// Long text : scrolls from right to left

#include <WiFi.h>
#include <WebServer.h>
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

// ---------------- MAX7219 SETTINGS ----------------

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4

#define CLK_PIN  18
#define DATA_PIN 23
#define CS_PIN   5

MD_Parola display(
  HARDWARE_TYPE,
  DATA_PIN,
  CLK_PIN,
  CS_PIN,
  MAX_DEVICES
);

// ---------------- WI-FI SETTINGS ----------------

const char* ssid = "YOUR_WIFI_NAME";
const char* password = "YOUR_WIFI_PASSWORD";

WebServer server(80);

// Stores up to 200 characters plus the ending character
char displayMessage[201] = "READY";

// Remembers whether the current message should scroll
bool scrolling = false;

// ---------------- MOBILE WEBPAGE ----------------

const char webpage[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>BlueDot LED Display</title>

  <style>
    body {
      margin: 0;
      background: #0c1722;
      color: white;
      font-family: Arial, sans-serif;
      text-align: center;
      padding: 30px 15px;
    }

    .box {
      max-width: 420px;
      margin: auto;
      background: #182938;
      padding: 25px;
      border-radius: 16px;
      box-shadow: 0 0 22px rgba(0, 200, 255, 0.25);
    }

    h2 {
      margin-top: 0;
      color: #00d9ff;
    }

    p {
      color: #cbd7df;
    }

    input {
      width: 90%;
      box-sizing: border-box;
      padding: 14px;
      margin: 15px 0;
      border: none;
      border-radius: 8px;
      font-size: 18px;
    }

    button {
      background: #00aeea;
      color: white;
      border: none;
      padding: 14px 24px;
      border-radius: 8px;
      font-size: 18px;
      font-weight: bold;
      cursor: pointer;
    }

    button:active {
      background: #007ca8;
    }
  </style>
</head>

<body>
  <div class="box">
    <h2>BlueDot LED Display</h2>
    <p>Type a message and send it to the LED matrix.</p>

    <form action="/set" method="GET">
      <input
        type="text"
        name="message"
        maxlength="200"
        placeholder="Type your message"
        required
      >

      <br>
      <button type="submit">Display Message</button>
    </form>
  </div>
</body>
</html>
)rawliteral";

// ---------------- DISPLAY FUNCTION ----------------

void showMessage()
{
  display.displayClear();
  display.displayReset();

  // Five characters can normally fit on a 32 x 8 display.
  if (strlen(displayMessage) <= 5)
  {
    scrolling = false;

    display.displayText(
      displayMessage,
      PA_CENTER,
      0,
      0,
      PA_PRINT,
      PA_NO_EFFECT
    );
  }
  else
  {
    scrolling = true;

    display.displayText(
      displayMessage,
      PA_LEFT,
      70,               // Lower value = faster scrolling
      500,              // Pause after one complete scroll
      PA_SCROLL_LEFT,
      PA_SCROLL_LEFT
    );
  }
}

// ---------------- WEB SERVER FUNCTIONS ----------------

void handleHome()
{
  server.send(200, "text/html", webpage);
}

void handleSetMessage()
{
  if (server.hasArg("message"))
  {
    String newMessage = server.arg("message");
    newMessage.trim();

    if (newMessage.length() > 0)
    {
      newMessage.toCharArray(
        displayMessage,
        sizeof(displayMessage)
      );

      showMessage();

      Serial.print("New message: ");
      Serial.println(displayMessage);
    }
  }

  // Return the phone to the main page
  server.sendHeader("Location", "/");
  server.send(303);
}

// ---------------- SETUP ----------------

void setup()
{
  Serial.begin(115200);

  display.begin();
  display.setIntensity(3);   // Brightness: 0 to 15
  display.displayClear();

  showMessage();

  Serial.println();
  Serial.println("================================");
  Serial.println(" BLUEDOT WI-FI LED DISPLAY");
  Serial.println("================================");
  Serial.print("Connecting to Wi-Fi");

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println();
  Serial.println("Wi-Fi connected!");
  Serial.print("Open this address on mobile: http://");
  Serial.println(WiFi.localIP());

  server.on("/", handleHome);
  server.on("/set", handleSetMessage);
  server.begin();

  Serial.println("Web server started.");
}

// ---------------- LOOP ----------------

void loop()
{
  // Listen for a message from the mobile webpage
  server.handleClient();

  // Keep the LED text animation running
  if (display.displayAnimate())
  {
    if (scrolling)
    {
      display.displayReset();
    }
  }
}

The Code Explained Like a Story

Large programs can look frightening when we try to understand every line at once. Instead, let us follow the message.

Chapter 1: The Display Wakes Up

When the ESP32 starts, this line prepares the MAX7219:

display.begin();

The brightness is set to 3:

display.setIntensity(3);

The available range is 0 to 15. Start with a low value because four bright matrices can draw more current than expected.

Chapter 2: The ESP32 Joins Wi-Fi

The ESP32 uses the network name and password to connect to your router:

WiFi.begin(ssid, password);

Until the connection is complete, dots appear in the Serial Monitor.

After connecting, the ESP32 receives a local IP address, such as:

192.168.1.15

Think of this address as the ESP32’s house number inside your Wi-Fi network.

Chapter 3: Your Phone Opens the ESP32 Webpage

When you enter that IP address in your mobile browser, the ESP32 sends the webpage stored inside the program.

The phone is not opening a page from the internet. It is opening a page directly from the ESP32.

Chapter 4: The Message Arrives

When you press Display Message, the webpage sends your text to:

/set?message=YOUR_TEXT

The function named <code>handleSetMessage()</code> reads that text and saves it inside <code>displayMessage</code>.

Chapter 5: The ESP32 Makes a Decision

Now the program checks the message length.

If it contains five characters or fewer, it is printed in the centre.

If it contains more than five characters, it scrolls from right to left.

That tiny decision makes the project feel intelligent.


Uploading and Testing the Project

Step 1: Select the ESP32 Board

In Arduino IDE, select:

Tools → Board → esp32 → ESP32 Dev Module

Then select the correct COM port.

Step 2: Upload the Program

Click Upload and wait for the program to finish.

Step 3: Open the Serial Monitor

Set the baud rate to:

115200

After the ESP32 connects to Wi-Fi, you should see an address similar to:

Open this address on mobile: http://192.168.1.15

Step 4: Open the Webpage

Connect your mobile to the same Wi-Fi network as the ESP32.

Enter the complete IP address in your mobile browser, including <code>http://</code>.

Step 5: Send Your First Message

Try these messages:

  • HI
  • HELLO

The shorter messages should remain still. The longer messages should move smoothly across all four matrices.

That first moving message is the moment the project becomes real.


Easy Customisations

Change the Brightness

Find:

display.setIntensity(3);

Use any value from 0 to 15.

Do not immediately set it to 15. A value between 2 and 6 is usually comfortable indoors.

Change the Scrolling Speed

Find the number 70 here:

PA_LEFT,
70,
500,
  • Smaller number = faster scrolling
  • Larger number = slower scrolling

Try 50 for faster movement or 100 for slower movement.

Change the Starting Message

Find:

char displayMessage[201] = "READY";

Replace READY with any short startup message you like.


Troubleshooting

Error: WebServer.h: No Such File or Directory

This normally means Arduino IDE is not compiling the sketch as an ESP32 project.

Check:

Tools → Board → esp32 → ESP32 Dev Module

If ESP32 boards are missing, install esp32 by Espressif Systems from Boards Manager.

Do not install a separate WebServer library.

Nothing Appears on the Matrix

Check these points:

  • The display is connected through the IN connector.
  • VCC is connected to 5V/VIN.
  • ESP32 and MAX7219 share the same GND.
  • DIN, CLK, and CS match the pins used in the code.
  • The USB cable can carry data and is not a charge-only cable.

Text Is Mirrored or Upside Down

Different MAX7219 modules use different hardware arrangements.

This project uses:

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW

If your text is incorrect, the wiring may still be fine. Your module may require a different hardware type.

The Phone Cannot Open the Webpage

Make sure:

  • The phone and ESP32 are on the same Wi-Fi network.
  • You copied the latest IP address from the Serial Monitor.
  • You entered <code>http://</code> before the address.
  • Mobile data or a VPN is not forcing the browser away from the local network.

Display Flickers or ESP32 Restarts

The four LED matrices can require more current when many LEDs are bright.

Reduce the intensity and use a stable 5V supply. Always keep the ESP32 and display grounds connected together.



Where Can We Use This Project?

This simple circuit can become:

  • A welcome message board
  • A desk notification display
  • A classroom announcement panel
  • A shop counter message display
  • A Wi-Fi clock with extra programming
  • A live sensor-data display
  • A subscriber-count or stock-information display

Once you can send words from a phone, the next step is sending useful information automatically.


Final Thoughts

At the beginning, we had only three separate things: a phone, an ESP32, and an LED matrix.

By the end, they speak to one another.

The phone gives the message. The ESP32 carries it. The MAX7219 brings it to life, one glowing dot at a time.

That is the joy of electronics. A handful of wires and a few lines of code can turn an idea into something you can see, touch, and share.

If your first message is scrolling now, congratulations—you have built your first mobile-controlled Wi-Fi LED display.

Leave a Reply

Your email address will not be published. Required fields are marked *

More Articles & Posts