A parte mais interessante na utilização do esp8266 é criar um web server para dar comandos à distância para a plaquinha. Dessa forma, nós podemos criar nossos próprios dispositivos IoT. Portanto, neste post, vamos aprender a criar um web server utilizando um arquivo HTML para exibir informações básicas.

Na aula anterior, aprendemos a executar duas rotinas independentes sem uma atrapalhar a outra (executar elas “ao mesmo tempo”).

Informações básicas

O que é um Web Server

Um Web Server ou servidor web nada mais é do que um servidor que se comunica por meio do protocolo HTTP (ou HTTPS). O HTTP é apenas um padrão utilizado para esse tipo de comunicação servidor-cliente. A imagem abaixo mostra o exemplo de uma mensagem.

Exemplo de uma mensagem com protocolo HTTP

Normalmente e também no nosso caso, a resposta do servidor é uma página na internet. Essa página é simplesmente um arquivo HTML. HTML é um tipo de linguagem (código) utilizado para representar textos e mídias (entre outros elementos especiais). As imagens abaixo mostram: o exemplo de um código em HTML e a sua representação em um navegador.

Código em HTML
Representação do código em HTML

E, para acessar esses dados, geralmente nós (clientes) utilizamos um navegador de internet. Podemos também fazer essa comunicação por meio de um aplicativo de celular ou por um software de computador. Essas são as formas mais interessantes de se utilizar dispositivos IoT. No geral, será desejável criarmos uma página com botões para comandar dispositivos ligados no esp8266 e com textos para mostrar a leitura de sensores.

Quem tiver interesse em aprender sobre o funcionamento da linguagem HTML (muito importante para criar um Web Server), recomendo o site w3schools. Com ele você pode aprender rapidamente os diferentes elementos de um código em HTML. É interessante aprender sobre CSS também, que é uma linguagem útil para descrever o estilo dos elementos HTML. Garanto que é um assunto bem tranquilo de aprender.

ESP8266 criando webserver

Conectando em uma rede

A primeira coisa a ser feita, é conectar o esp8266 em uma rede Wi-Fi, pois é por meio dessa rede que poderemos acessar o Web Server. E, fazer isso é bem simples, basta utilizar as seguintes funções:

WiFi.mode(WIFI_STA);
WiFi.begin(nome_rede_wifi, senha_rede_wifi);

A primeira configura o esp no modo de estação (modo em que ele se conecta a uma rede existente) e a segunda de fato faz a conexão.

A titulo de curiosidade, existem outros dois modos além do de estação: um chamado Access Point, que faz o esp criar a própria rede; e outro que ele faz as duas coisas (conecta a uma rede existente e cria uma). Veremos isso em aulas futuras.

Uma coisa importante a ser feita após o comando WiFi.begin, é aguardar a conexão ser finalizada (veja no código como fazer isso). Após a espera, é desejável printar o IP que o esp obteve da rede, pois é por ele que nós acessaremos a página criada pela plaquinha.

Apenas com esse procedimento, caso eu tente me conectar no IP informado (colocar o IP na barra de endereço do navegador), nada acontece. Isso porque, o esp ainda é apenas um dispositivo qualquer conectado na rede.

Criando servidor

A criação do servidor pode ser dividida em 4 etapas que serão abordadas nos tópicos seguintes:

1 - Criação de instância da classe do servidor

Crie a variável global no início do código:

ESP8266WebServer server(80);

80 é a porta a ser utilizada pelo web server (80 é a porta usada pelo padrão HTTP).

2 - Criação das páginas

É possível criar uma página diferente para cada caminho do web server (para cada nome que você digitar após a / do IP). Para fazer isso, você precisará criar uma função para cada página. Uma vez que a função for criada, você precisa informar ao servidor a correspondência entre o caminho e a função com o comando adiante:

server.on(caminho, funcao_pagina);

Exemplo: caminho = “/teste” e funcao_pagina = handler_pagina_teste.

Assim, dentro da função da página, você cria a rotina que será executada quando alguém acessar àquela página. A função não precisa necessariamente responder alguma coisa para o cliente, ela pode simplesmente conter um comando para acionar um LED por exemplo. Entretanto, como padrão da comunicação HTTP, é ideal que a função responda à requisição sim.

A resposta à requisição é conseguida pelo uso do comando:

server.send(codigo_resposta, “text/html”, mensagem_resposta);

Onde codigo_resposta segue a correspondência explicada neste link e mensagem_resposta é uma String contendo o html da página.

Obs: normalmente, o código para uma resposta sem erros é 200.

A construção da String com o conteúdo da página será melhor entendida no código final (tópico mais adiante). Mas é importante esclarecer que uma determinada página pode conter um HTML relativamente extenso e, passar isso pra String pode ser um pouco chato. Isso, porque qualquer aspas no HTML que for igual as aspas da declaração da String precisará receber uma barra invertida (\) antes para informar ao código que aquela aspas faz parte do conteúdo da String. Uma forma de contornar isso é substituindo as aspas duplas (“) do HTML por aspas simples (‘) e declarar a String com aspas dupla. Além disso, criar uma String que se divide em várias linhas exige que você coloque uma barra invertida ao final de cada linha.

2.1 - Páginas não existentes

Também é possível configurar uma função para ser a resposta padrão para todas àquelas páginas que não forem criadas explicitamente. Isso é feito com o seguinte comando:

server.onNotFound(funcao_pagina);

A função deve obedecer ao que falei no tópico anterior. Entretanto, como é uma resposta de uma página que não existe, o código de resposta padrão é o 404. No código final eu coloquei o código 200 sem nenhum motivo específico.

3 - Inicialização do servidor

Use o comando seguinte após configurar as páginas:

server.begin();

4 - Verificação constante de requisições que estão chegando

Coloque o comando abaixo no void loop:

server.handleClient();

Código completo

O código abaixo abrange tudo o que foi falado acima. No caso, criei um web server com uma página de exemplo no caminho “/” e qualquer outro caminho gera um texto falando “Página não encontrada”. Leia os comentários para entender os detalhes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//// ----- Bibliotecas -----
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

// ----- Definições -----
#define WIFI_NAME   "NOME_REDE_WIFI"
#define WIFI_PASS   "SENHA_REDE_WIFI"


// ----- Variáveis globais -----
ESP8266WebServer server(80);


// ----- Protótipo das funções -----
void handle_pagina_inicial();



void setup(void)
{
  // Inicializa a comunicação serial
  Serial.begin(115200);
 
  // Configura o WiFi
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_NAME, WIFI_PASS);
  Serial.println("Conectando à rede...");

  // Aguarda conexão
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
 
  // Printa o IP
  Serial.print("IP obtido: ");
  Serial.println(WiFi.localIP());
   
  // Configura as funções das páginas
  server.on("/", handle_pagina_inicial);
  server.onNotFound(handle_nao_existe);

  // Inicializa o servidor
  server.begin();
  Serial.println("Web Server iniciado");
}


void loop(void)
{
  // Responde às requisições feitas
  server.handleClient();
}


/*
 * Resposta da página inicial
 */

void handle_pagina_inicial()
{
  // Criando o HTML dividindo o texto em várias linhas
  // Para isso, é preciso colocar o \ no final de cada linha
  String message = "<html>\
 <meta http-equiv=\'content-type\' content=\'text/html; charset=utf-8\'>\
 <h1>Central de controle dos LEDs</h1>\
 <p> Apague e acione os LEDs facilmente.</p>\
 <p> Basta apertar os botões.</p>\
 <img src='https://mundoprojetado.com.br/wp-content/uploads/2018/06/Template2-e1528172108632.png'>\
</html>"
;

  // Outra forma de declarar a variável é concatenar cada linha
  // separadamente
  /*String message = "<html>";
  message += "<meta http-equiv=\'content-type\' content=\'text/html; charset=utf-8\'>";
  message += "<h1>Central de controle dos LEDs</h1>";
  message += "<p> Apague e acione os LEDs facilmente.</p>";
  message += "<p> Basta apertar os botões.</p>";
  message += "<img src='https://mundoprojetado.com.br/wp-content/uploads/2018/06/Template2-e1528172108632.png'>";
  message += "</html>";*/

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


/*
 * Resposta de uma página que não existe
 */

void handle_nao_existe()
{
  String message = "<html><meta http-equiv=\'content-type\' content=\'text/html; charset=utf-8\'>";
  message += "<h1>Página não encontrada</h1></html>";
 
  server.send(200, "text/html", message);
}

Resultado

Após carregar o código no esp8266, abri o monitor serial, aguardei a conexão do WiFi finalizar e copiei o IP informado. Em seguida, colei o IP no navegador (192.168.0.16/) e obtive o seguinte:

Web server do esp8266 com imagem