image Saravati

Como desenhar no celular e reproduzir em uma matriz LED usando ESP32

O objetivo deste projeto é permitir que o usuário desenhe diretamente na tela do celular e veja o mesmo desenho sendo reproduzido em tempo real na matriz LED. Tudo isso sem aplicativo, utilizando apenas o navegador do celular.

Além de ser um projeto muito visual e divertido, ele também ensina conceitos importantes de:

  • Internet das Coisas (IoT)
  • Comunicação WiFi
  • Servidor Web embarcado
  • Controle de displays LED
  • Programação Web integrada ao ESP32

Como funciona o projeto

O ESP32 cria sua própria rede WiFi e hospeda uma página web. Quando o celular se conecta nessa rede e acessa o IP do ESP32, aparece uma interface 8×8 para desenho. Cada pixel desenhado na tela é enviado instantaneamente para o ESP32, que atualiza a matriz LED em tempo real. O fluxo funciona assim:

Celular

Página Web

WiFi

ESP32

Matriz LED MAX7219

Materiais necessários

Para montar o projeto você precisará de:

Ligações da matriz MAX7219

MAX7219 → ESP32

MAX7219ESP32
VCC5V
GNDGND
DINGPIO 23
CLKGPIO 18
CS/LOADGPIO 5

Biblioteca necessária

Na Arduino IDE instale a biblioteca: MD_MAX72XX

Como instalar a biblioteca

  1. Abra a Arduino IDE;
  2. Vá em:

Sketch → Incluir Biblioteca → Gerenciar Bibliotecas

  1. Pesquise por:

MD_MAX72XX

  1. Instale a biblioteca.

Código completo do projeto

Copie e cole o código abaixo:

#include <WiFi.h>

#include <WebServer.h>

#include <MD_MAX72xx.h>

#include <SPI.h>

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW

#define MAX_DEVICES 1

#define CS_PIN 5

MD_MAX72XX mx(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

WebServer server(80);

const char* ssid = "MatrixPad";

const char* password = "12345678";

bool pixels[8][8];

String htmlPage() {

 return R"rawliteral(

<!DOCTYPE html>

<html>

<head>

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>

body {

 background:#081C30;

 color:white;

 font-family:Arial;

 text-align:center;

}

h2 {

 margin-top:20px;

}

#grid {

 display:grid;

 grid-template-columns:repeat(8,35px);

 grid-template-rows:repeat(8,35px);

 gap:4px;

 justify-content:center;

 margin-top:20px;

}

.cell {

 width:35px;

 height:35px;

 background:white;

 border-radius:6px;

}

.on {

 background:#ff3030;

}

button {

 margin-top:20px;

 padding:12px 25px;

 font-size:18px;

 border:none;

 border-radius:8px;

 background:#ff3030;

 color:white;

}

</style>

</head>

<body>

<h2>AI Matrix Drawing Pad</h2>

<p>Desenhe na tela</p>

<div id="grid"></div>

<button onclick="clearGrid()">Limpar</button>

<script>

let grid = document.getElementById("grid");

let drawing = false;

let data = Array(8).fill().map(()=>Array(8).fill(0));

for(let y=0; y<8; y++){

 for(let x=0; x<8; x++){

   let cell = document.createElement("div");

   cell.className = "cell";

   cell.dataset.x = x;

   cell.dataset.y = y;

   cell.addEventListener("mousedown", draw);

   cell.addEventListener("mouseover", function(e){

     if(drawing) draw(e);

   });

   cell.addEventListener("touchstart", drawTouch);

   cell.addEventListener("touchmove", drawTouch);

   grid.appendChild(cell);

 }

}

document.body.addEventListener("mousedown", ()=>drawing=true);

document.body.addEventListener("mouseup", ()=>drawing=false);

function draw(e){

 let x = e.target.dataset.x;

 let y = e.target.dataset.y;

 if(x === undefined) return;

 e.target.classList.add("on");

 data[y][x] = 1;

 sendPixel(x, y, 1);

}

function drawTouch(e){

 e.preventDefault();

 let touch = e.touches[0];

 let el = document.elementFromPoint(

   touch.clientX,

   touch.clientY

 );

 if(el && el.classList.contains("cell")){

   let x = el.dataset.x;

   let y = el.dataset.y;

   el.classList.add("on");

   data[y][x] = 1;

   sendPixel(x, y, 1);

 }

}

function sendPixel(x, y, state){

 fetch(`/pixel?x=${x}&y=${y}&s=${state}`);

}

function clearGrid(){

 document.querySelectorAll(".cell")

 .forEach(c => c.classList.remove("on"));

 data = Array(8).fill()

 .map(()=>Array(8).fill(0));

 fetch("/clear");

}

</script>

</body>

</html>

)rawliteral";

}

void setMatrixPixel(int x, int y, bool state) {

 // Correção do espelhamento

 mx.setPoint(y, 7 - x, state);

}

void handleRoot() {

 server.send(200, "text/html", htmlPage());

}

void handlePixel() {

 int x = server.arg("x").toInt();

 int y = server.arg("y").toInt();

 int s = server.arg("s").toInt();

 if (x >= 0 && x < 8 &&

     y >= 0 && y < 8) {

   pixels[y][x] = s;

   setMatrixPixel(x, y, s);

 }

 server.send(200, "text/plain", "OK");

}

void handleClear() {

 mx.clear();

 for(int y=0; y<8; y++){

   for(int x=0; x<8; x++){

     pixels[y][x] = 0;

   }

 }

 server.send(200, "text/plain", "CLEAR");

}

void setup() {

 Serial.begin(115200);

 mx.begin();

 mx.control(MD_MAX72XX::INTENSITY, 5);

 mx.clear();

 WiFi.softAP(ssid, password);

 Serial.println("Rede criada:");

 Serial.println(ssid);

 Serial.println("Senha:");

 Serial.println(password);

 Serial.println("IP:");

 Serial.println(WiFi.softAPIP());

 server.on("/", handleRoot);

 server.on("/pixel", handlePixel);

 server.on("/clear", handleClear);

 server.begin();

}

void loop() {

 server.handleClient();

}

Explicação do código

Criação da rede WiFi

WiFi.softAP(ssid, password);

O ESP32 cria sua própria rede WiFi.

Criação do servidor Web

WebServer server(80);

O ESP32 funciona como servidor web.

Interface HTML

A página HTML é enviada pelo ESP32 e aberta diretamente no navegador do celular.

Envio dos pixels

Quando o usuário desenha:

fetch(`/pixel?x=${x}&y=${y}&s=${state}`);

o navegador envia os pixels para o ESP32.

Atualização da matriz LED

mx.setPoint(y, 7 – x, state);

Acende os LEDs correspondentes na matriz.

Como utilizar

1. Grave o código no ESP32

Após gravar, abra o Serial Monitor.

2. Conecte o celular na rede

Rede: MatrixPad

Senha: 12345678

3. Abra o navegador

Digite o IP: 192.168.4.1

4. Desenhe

Agora basta desenhar na tela do celular e a matriz LED reproduzirá tudo em tempo real.

Resultado final

O sistema permite:

  • desenhar letras;
  • criar símbolos;
  • desenhar formas;
  • controlar LEDs pelo celular em tempo real.

Possíveis melhorias

Você pode evoluir o projeto adicionando:

  • múltiplas matrizes;
  • animações;
  • reconhecimento de letras;
  • inteligência artificial;
  • salvamento de desenhos;
  • envio remoto pela internet;
  • efeitos visuais;
  • controle de brilho.

Conclusão

Neste projeto criamos um painel interativo utilizando ESP32 e matriz LED MAX7219. O sistema permite desenhar diretamente pelo celular e reproduzir tudo em tempo real na matriz LED. Além de ser extremamente divertido e visual, esse projeto também demonstra na prática conceitos modernos de:

  • IoT;
  • redes WiFi;
  • comunicação web;
  • sistemas embarcados;
  • integração entre hardware e software.

É um excelente projeto para iniciantes e também para quem deseja explorar aplicações mais avançadas com ESP32.

Saiba mais sobre a parceria Saravati e Sara Educação

Este “Guia de Montagem” é uma colaboração especial entre a Saravati e a Sara Educação, criado pelo Professor Felipe Rosa. Nosso objetivo é enriquecer a comunidade de entusiastas da eletrônica, IoT e automação com recursos educacionais de alta qualidade. Através dessa parceria, buscamos inspirar e capacitar criadores em seus projetos, disponibilizando esses guias em nosso blog e nas redes sociais.

@saravatirobotica no Instagram e Tiktok

@sara.educacao no Instagram e Tiktok