Servindo Páginas HTML Simples com o ESP32
Marcelo V. Souza
1s 240ms
O ESP32 é um microcontrolador poderoso que oferece conectividade Wi-Fi e Bluetooth integradas. Uma das aplicações mais interessantes é a capacidade de hospedar um servidor web, permitindo que o dispositivo sirva páginas HTML e interaja com usuários através de uma interface web. Neste artigo, vamos explorar como servir páginas HTML simples utilizando o ESP32.
Servir páginas HTML diretamente do ESP32 abre um mundo de possibilidades para projetos de automação e IoT. Com isso, é possível:
- Monitorar sensores em tempo real: Exibir dados coletados pelo ESP32 diretamente em uma página web acessível por qualquer dispositivo na mesma rede.
- Controlar dispositivos: Acionar relés, LEDs e outros atuadores através de botões e controles em uma interface web.
- Configurar o dispositivo: Permitir que usuários alterem configurações sem a necessidade de reprogramar o ESP32.
Pré-requisitos🔗
Antes de começar, certifique-se de ter:
- ESP32: Qualquer placa de desenvolvimento com o microcontrolador ESP32.
- Ambiente de Desenvolvimento Arduino IDE: Configurado para programar o ESP32.
- Conhecimentos básicos de HTML: Será útil entender a estrutura das páginas que vamos servir.
Configurando o Ambiente🔗
Para servir páginas HTML, precisamos:
1. Conectar o ESP32 à rede Wi-Fi: O ESP32 atuará como servidor, então deve estar conectado à mesma rede dos dispositivos que acessarão as páginas.
2. Configurar o servidor web: Utilizar bibliotecas específicas para criar o servidor e definir rotas.
3. Criar o conteúdo HTML: Escrever a página que será servida.
Conectando o ESP32 à Rede Wi-Fi🔗
Primeiramente, vamos conectar o ESP32 à rede Wi-Fi. Para isso, utilizaremos a biblioteca WiFi.h
.
#include <WiFi.h>
const char* ssid = "NOME_DA_REDE";
const char* password = "SENHA_DA_REDE";
void setup()
{
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.print("Conectando-se à rede Wi-Fi");
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("Conectado! Endereço IP: ");
Serial.println(WiFi.localIP());
}
void loop()
{
// Código principal
}
Explicação:
WiFi.begin(ssid, password);
: Inicia a conexão com a rede especificada.
WiFi.status()
: Verifica o status da conexão.
WiFi.localIP()
: Obtém o endereço IP atribuído ao ESP32.
Configurando o Servidor Web🔗
Com a conexão estabelecida, é hora de configurar o servidor web. Usaremos a biblioteca WebServer.h
.
#include <WebServer.h>
WebServer server(80); // Cria um servidor na porta 80
void setup()
{
// Código de conexão Wi-Fi (como no exemplo anterior)
// Inicia o servidor
server.begin();
Serial.println("Servidor web iniciado");
}
void loop()
{
server.handleClient(); // Lida com clientes conectados
}
Servindo uma Página HTML Simples🔗
Para servir uma página, precisamos definir uma rota e o conteúdo que será enviado ao cliente.
void handleRoot()
{
String html = "<!DOCTYPE html><html><head><title>Página ESP32</title></head><body><h1>Olá, mundo!</h1><p>Esta é uma página servida pelo ESP32.</p></body></html>";
server.send(200, "text/html", html);
}
void setup()
{
// Código anterior
// Define a rota raiz
server.on("/", handleRoot);
// Inicia o servidor
server.begin();
Serial.println("Servidor web iniciado");
}
void loop()
{
server.handleClient();
}
Explicação:
server.on("/", handleRoot);
: Define que, quando a raiz (/
) for acessada, a função handleRoot
será chamada.
server.send(200, "text/html", html);
: Envia uma resposta HTTP com código 200 (OK), especificando o tipo de conteúdo (text/html
) e o conteúdo em si.
Testando o Servidor Web🔗
Após carregar o código no ESP32:
1. Abra o monitor serial: Para obter o endereço IP do ESP32.
2. No navegador, digite o endereço IP exibido no monitor serial.
Você deverá ver a página com a mensagem "Olá, mundo!".
Melhorando o Código HTML🔗
Para tornar o código mais legível e gerenciável, podemos armazenar o conteúdo HTML como uma constante do tipo char
.
const char index_html[] = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<title>Página ESP32</title>
</head>
<body>
<h1>Olá, mundo!</h1>
<p>Esta é uma página servida pelo ESP32.</p>
</body>
</html>
)rawliteral";
void handleRoot()
{
server.send(200, "text/html", index_html);
}
Explicação:
R"rawliteral(...)"
: Permite inserir strings multilinhas sem a necessidade de caracteres de escape.
Adicionando Estilo à Página🔗
Podemos incluir CSS para melhorar a aparência.
const char index_html[] = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<title>Página ESP32</title>
<style>
body { font-family: Arial, sans-serif; text-align: center; }
h1 { color: #0275d8; }
p { font-size: 1.2em; }
</style>
</head>
<body>
<h1>Bem-vindo ao ESP32</h1>
<p>Esta é uma página servida pelo ESP32.</p>
</body>
</html>
)rawliteral";
Criando Rotas Adicionais🔗
Podemos adicionar novas rotas para servir diferentes páginas ou executar ações específicas.
void handleNotFound()
{
server.send(404, "text/plain", "Página não encontrada");
}
void setup()
{
// Código anterior
// Rota raiz
server.on("/", handleRoot);
// Rota para /sobre
server.on("/sobre", []()
{
server.send(200, "text/plain", "Esta é a página Sobre.");
});
// Tratamento para páginas não encontradas
server.onNotFound(handleNotFound);
// Inicia o servidor
server.begin();
}
Explicação:
server.on("/sobre", ...);
: Define uma nova rota /sobre
.
server.onNotFound(handleNotFound);
: Define o que acontece quando uma rota não existente é acessada.
Além de servir páginas estáticas, podemos interagir com o hardware do ESP32.
Controlando um LED
Vamos adicionar um LED ao pino GPIO 2 e controlá-lo através da interface web.
Circuito:
- Conecte um LED ao pino GPIO 2 com um resistor apropriado.
Código:
#define LED_PIN 2
void handleLEDOn()
{
digitalWrite(LED_PIN, HIGH);
server.send(200, "text/plain", "LED aceso");
}
void handleLEDOff()
{
digitalWrite(LED_PIN, LOW);
server.send(200, "text/plain", "LED apagado");
}
void setup()
{
pinMode(LED_PIN, OUTPUT);
// Código de configuração do Wi-Fi e servidor
// Rota para acender o LED
server.on("/led/on", handleLEDOn);
// Rota para apagar o LED
server.on("/led/off", handleLEDOff);
// Inicia o servidor
server.begin();
}
Testando:
- Acesse
http://ENDERECO_IP/led/on
para acender o LED.
- Acesse
http://ENDERECO_IP/led/off
para apagar o LED.
Integrando Botões na Página
Podemos tornar o controle mais intuitivo adicionando botões na página HTML.
Atualize o conteúdo HTML:
const char index_html[] = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<title>Controle de LED</title>
<style>
body { font-family: Arial, sans-serif; text-align: center; }
h1 { color: #0275d8; }
button {
padding: 15px 25px;
font-size: 24px;
margin: 20px;
cursor: pointer;
}
</style>
</head>
<body>
<h1>Controle de LED com ESP32</h1>
<button onclick="fetch('/led/on')">Acender LED</button>
<button onclick="fetch('/led/off')">Apagar LED</button>
</body>
</html>
)rawliteral";
Explicação:
onclick="fetch('/led/on')"
: Quando o botão é clicado, faz uma requisição à rota especificada.
fetch()
: Função JavaScript para realizar requisições HTTP.
Lendo Dados do ESP32🔗
Além de enviar comandos, podemos ler informações do ESP32, como o estado do LED ou valores de sensores.
Exibindo o Estado do LED
Vamos modificar a função que trata a rota raiz para exibir o estado atual do LED.
void handleRoot()
{
String ledState = digitalRead(LED_PIN) ? "Aceso" : "Apagado";
String html = "<!DOCTYPE html><html><head><title>Estado do LED</title></head><body><h1>Estado do LED: " + ledState + "</h1></body></html>";
server.send(200, "text/html", html);
}
Explicação:
digitalRead(LED_PIN)
: Lê o estado atual do pino do LED.
ledState
: Armazena uma string baseada no estado do LED.
Para atualizar informações na página sem recarregá-la completamente, podemos utilizar AJAX.
Atualize o conteúdo HTML:
<button onclick="acenderLED()">Acender LED</button>
<button onclick="apagarLED()">Apagar LED</button>
<p id="status">Estado do LED: ...</p>
<script>
function acenderLED()
{
fetch('/led/on').then(actualizarEstado);
}
function apagarLED()
{
fetch('/led/off').then(actualizarEstado);
}
function atualizarEstado()
{
fetch('/led/status')
.then(response => response.text())
.then(state => {
document.getElementById('status').innerText = 'Estado do LED: ' + state;
});
}
// Atualiza o estado ao carregar a página
window.onload = actualizarEstado;
</script>
No código do ESP32, adicione:
void handleLEDStatus()
{
String ledState = digitalRead(LED_PIN) ? "Aceso" : "Apagado";
server.send(200, "text/plain", ledState);
}
void setup()
{
// Rotas anteriores
// Rota para obter o estado do LED
server.on("/led/status", handleLEDStatus);
// Inicia o servidor
server.begin();
}
Explicação:
- Funções JavaScript:
acenderLED()
, apagarLED()
e atualizarEstado()
gerenciam as requisições e atualizam a página.
/led/status
: Nova rota para obter o estado atual do LED.
Considerações de Segurança🔗
Embora este exemplo seja básico, é importante considerar aspectos de segurança em aplicações reais:
- Restringir o acesso: Implementar autenticação para evitar que qualquer usuário na rede possa controlar o dispositivo.
- Sanitizar entradas: Proteger o servidor contra ataques como injeção de código.
Conclusão🔗
Servir páginas HTML simples com o ESP32 é uma maneira eficaz de criar interfaces para controlar e monitorar dispositivos. A partir deste ponto, é possível expandir o projeto para incluir:
- Design responsivo: Adaptar a interface para diferentes dispositivos (computadores, tablets, smartphones).
- Controle de múltiplos dispositivos: Gerenciar vários atuadores e sensores.
- Integração com serviços externos: Enviar dados para a nuvem ou interagir com APIs.
A chave é entender os princípios básicos de como o ESP32 pode servir conteúdo web e interagir com os usuários. Com criatividade e conhecimento, as possibilidades são infinitas.
Próximos Passos🔗
- Explorar CSS e JavaScript: Para melhorar a experiência do usuário.
- Implementar WebSockets: Para comunicação em tempo real entre o ESP32 e o navegador.
- Adicionar segurança: Implementar HTTPS e autenticação.
A jornada com o ESP32 e o desenvolvimento web está apenas começando. Continue explorando e aprimorando suas habilidades para criar projetos cada vez mais completos e inovadores.
Autor: Marcelo V. Souza - Engenheiro de Sistemas e Entusiasta em IoT e Desenvolvimento de Software, com foco em inovação tecnológica.
Tags