ÍNDICE DE CONTEÚDO
- Franzininho WiFi: Display 7 Segmentos TM1637
- Franzininho WiFi: Primeiros passos na Arduino IDE
- Franzininho WiFi: Explorando as GPIOs com Arduino
- Franzininho WiFi: Leitura de entradas analógicas com Arduino
- Franzininho WiFi: PWM (Pulse Width Modulation) com Arduino
- Franzininho WiFi: Comunicação Serial (UART) com Arduino
- Franzininho WiFi: Servo Motor com Arduino
- Franzininho WiFi: Web Server
- Franzininho WiFi: Display OLED
- Franzininho WiFi: Sensor de temperatura e umidade DHT22
- Franzininho WiFi: Sensor de temperatura DS18B20
- Franzininho WiFi: Display LCD 16×2 com comunicação I2C
Introdução
Um Web server é o local onde as páginas da web são armazenadas, as requisições são processadas e os serviços são oferecidos aos clientes da web. Embora as palavras “web” e “Internet” estejam intimamente relacionadas, elas não significam exatamente a mesma coisa. A Internet se refere à rede de computadores por onde trafegam diversos serviços diariamente. Já a World Wide Web (WWW), ou simplesmente Web, é uma camada acima da Internet, onde são construídas aplicações (como áudio, vídeo e texto) usando-se a Web como base. Um exemplo de aplicação é o navegador da web.
As páginas da web fazem parte desse contexto e são formatadas em uma linguagem de marcação chamada Hypertext Markup Language (HTML). Elas podem incluir estilos para dar identidade à aplicação web. O servidor web utiliza esses componentes para fornecer o conteúdo ao usuário. O protocolo utilizado para as requisições é conhecido como Hypertext Transfer Protocol (HTTP), que gerencia o processo de comunicação sempre que o usuário interage com a aplicação.
Neste artigo, mostraremos como criar um Web Server utilizando a Franzininho WiFi e exploraremos as possibilidades de uso em IoT, tornando seu projeto mais robusto. Acompanhe o projeto proposto nas próximas seções.
Biblioteca WebServer
Os métodos utilizado pela biblioteca “WebServer.h” no exemplo de projeto serão apresentados seguir:
Embarcados Experience 2024: Evento Presencial
Participe do Embarcados Experience 2024 em São Paulo. Conhecimento técnico, palestras, workshops e oportunidade de networking com profissionais experientes.
begin()
Inicia o servidor, esse método normalmente é chamado após configuramos os elementos presente dentro do serviço a ser atendido, ou seja, quando cliente solicita as requisições.
1 |
void server.begin(void); |
send()
Envia resposta ao cliente, neste caso quem acessa o server recebe a resposta enviada por esse método.
void server.send(int code,char *contet_type, char String& content);
- code : código de resposta HTTP, pode ser 200 (HTTP OK) ou 404 (HTTP SERVER NOT FOUND)
- contet_type : tipo de conteúdo da página, por exemplo : “text/plain” ou “image/png”
- contet : tipo de conteúdo, ou seja, a própria página em HTML
on()
Método para acessar a URL quando é realizado as requisições HTTP.
1 |
void server.on(const Uri &uri,THandlerFunction fn); |
- uri : caminho para a URL, “/” indica que receberá as requisições do root
- fn : ponteiro para a função que vai ser chamada quando o servidor estiver ativo
handlerClient()
Responsável por detectar as solicitações HTTP, cria e notifica os eventos para os métodos on() e onNotFound().
1 |
void server.handlerClient(void); |
onNotFound()
Aponta para a função quando o handler não é alocado.
1 |
void server.onNotFound(THandlerFunction fn); |
- fn : ponteiro para a função
Materiais necessários
Para desenvolver nossa aplicação os materiais utilizados foram:
- Placa Franzininho WiFi
- LDR
- Resistor 10k ohms
- Jumpers
- Arduino IDE
Circuito
O circuito utilizado para este artigo será a placa Franzininho WiFi, o fotoresistor (LDR) para capturar a quantidade de luz captada no ambiente e para auxiliar no debug vamos usar o monitor serial do Arduino IDE.
Código
No projeto proposto, utilizaremos a Franzininho WiFi conectada à rede local para criar um Web Server que exibirá a intensidade luminosa a partir do LDR. Para isso, é necessário conectar a Franzininho à rede utilizando as credenciais da sua rede. Em seguida, copie o endereço IP apresentado no monitor serial (Figura 1) e cole-o no navegador de sua preferência (Figura 2).
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 97 98 99 100 101 102 |
#include "WiFi.h" #include <WebServer.h> #define LDR_PIN 3 // Define o pino do LDR #define MIN_ANALOG 0 #define MAX_ANALOG 4096 #define MIN_PERCENT 0 #define MAX_PERCENT 100 // Configurações da rede Wi-Fi const char *ssid = "sua rede local"; const char *password = "senha da rede local"; // Declara o objeto WebServer WebServer server(80); // Variável para armazenar a porcentagem de luz int light_percent = 0; // Função para retornar a página HTML com a porcentagem de luz String html_page(int percent) { String index = "<!DOCTYPE html><html>\n"; index += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n"; index += "<title>Franzininho WiFi Web Server</title>\n"; index += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n"; index += "body{margin-top: 50px;} h1 {color: #37973f;margin: 50px auto 30px;}\n"; index += "p {font-size: 24px;color: #000000;margin-bottom: 10px;}\n"; index += "div { background-color: lightgrey;width: 400px;border: 20px solid green;padding: 30px;margin: 20px;}\n"; index += "</style>\n"; index += "</head>\n"; index += "<body>\n"; index += "<div id=\"franzininho_webpage\">\n"; index += "<h1>Franzininho WiFi Web Server</h1>\n"; index += "<p>Intensidade luminosa: "; index += (int)percent; index += " %</p>"; index += "</div>\n"; index += "</body>\n"; index += "</html>\n"; return index; } // Manipulador para a página principal void handle_on_connect() { server.send(200, "text/html", html_page(light_percent)); } // Manipulador para páginas não encontradas void handle_not_found() { server.send(404, "text/plain", "Página não encontrada"); } void setup() { Serial.begin(115200); // Configura o driver WiFi para o modo Station WiFi.mode(WIFI_STA); // Inicializa o driver e conecta-se à rede local WiFi.begin(ssid, password); delay(5000); // Aguarda até que esteja conectado à rede local while (WiFi.status() != WL_CONNECTED) { Serial.println("Aguarde conectar-se à rede..."); delay(500); } // Imprime o endereço IP na serial Serial.println("Conectado com sucesso!"); Serial.print("IP: "); Serial.println(WiFi.localIP()); // Adiciona a função "handle_on_connect" quando o servidor estiver online server.on("/", handle_on_connect); // Adiciona a função "handle_not_found" quando o servidor estiver offline server.onNotFound(handle_not_found); // Inicia o servidor server.begin(); // Informa que o Web Server foi inicializado Serial.println("Web Server Ativo"); } void loop() { // Trata as requisições HTTP e sinaliza os eventos server.handleClient(); // Realiza uma conversão do valor de tensão para valor em percentual light_percent = map(analogRead(LDR_PIN), MAX_ANALOG, MIN_ANALOG, MIN_PERCENT, MAX_PERCENT); // Aguarda 5 milisegundos delay(5); } |
Para acompanhar o funcionamento do projeto, abra o monitor serial e verifique as etapas de criação do servidor. Abaixo, você encontrará o endereço IP da Franzininho. Se você desejar configurar um endereço IP estático, consulte nosso artigo “Franzininho WiFi: Station“, onde mostramos como realizar essa configuração.
Abaixo, podemos ver o resultado ao acessar o servidor e a página HTML criada.
Explicação do Código
Nesta seção, vamos explicar o código linha por linha, para garantir uma compreensão completa e entender a finalidade de cada função utilizada.
Inclui as bibliotecas para o driver WiFi e para o WebServer. Estas duas bibliotecas vão nos permitir utilizar os métodos para estabelecer uma conexão com a rede local e configurar o server e tratar as requisições HTTP sem preocupar-se com camadas mais baixas do protocolo, respectivamente.
1 2 |
#include "WiFi.h" #include <WebServer.h> |
Declara as variáveis para receber as credenciais da rede (nome e senha).
1 2 3 |
// Configurações da rede Wi-Fi const char *ssid = "sua rede local"; const char *password = "senha da rede local"; |
Definimos os máximos e os mínimos da leitura analógica e o percentual mínimo e máximo para captação luminosa.
1 2 3 4 5 6 |
// Define o pino do LDR #define LDR_PIN 3 #define MIN_ANALOG 0 #define MAX_ANALOG 4096 #define MIN_PERCENT 0 #define MAX_PERCENT 100 |
Declara o objeto e recebe como parâmetro a porta do servidor que estará recebendo as requisições, entenda como porta apenas um canal de comunicação específico.
1 2 |
// Declara o objeto WebServer WebServer server(80); |
Declara a variavel para receber o valor do percentual de luminosidade.
1 2 |
// Variável para armazenar a porcentagem de luz int light_percent = 0; |
Função responsável por conter a página em HTML, inclui: cabeçalho (head), estilo (style) e corpo (body). Retorna uma String e recebe como parâmetro os valores de temperatura.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// Função para retornar a página HTML com a porcentagem de luz String html_page(int percent) { String index = "<!DOCTYPE html><html>\n"; index += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n"; index += "<title>Franzininho WiFi Web Server</title>\n"; index += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n"; index += "body{margin-top: 50px;} h1 {color: #37973f;margin: 50px auto 30px;}\n"; index += "p {font-size: 24px;color: #000000;margin-bottom: 10px;}\n"; index += "div { background-color: lightgrey;width: 400px;border: 20px solid green;padding: 30px;margin: 20px;}\n"; index += "</style>\n"; index += "</head>\n"; index += "<body>\n"; index += "<div id=\"franzininho_webpage\">\n"; index += "<h1>Franzininho WiFi Web Server</h1>\n"; index += "<p>Intensidade luminosa: "; index += (int)percent; index += " %</p>"; index += "</div>\n"; index += "</body>\n"; index += "</html>\n"; return index; } |
Função responsável por enviar ao cliente, neste caso quem acessa o endereço de IP, para renderizar uma página em HTML com o valor de temperatura.
1 2 3 4 5 |
// Manipulador para a página principal void handle_on_connect() { server.send(200, "text/html", html_page(light_percent)); } |
Função responsável por enviar ao cliente uma mensagem (“Página não encontrada”) quando o handler não é alocado.
1 2 3 4 5 |
// Manipulador para páginas não encontradas void handle_not_found() { server.send(404, "text/plain", "Página não encontrada"); } |
No setup(), vamos inicializar o canal Serial na velocidade de 115200 bps, configurar o WiFi no modo Station e inicializar o drive para conectar-se à rede local. Em seguida vamos aguardar a conexão à rede até que a Franzininho estabeleça o canal de comunicação com o roteador. O driver do WiFi funciona por eventos, ou seja, sequências de ações notificadas a partir de estados. Desta forma utilizamos o WiFi.status() para monitorar como está o estado atual.
Após entrar na rede local vamos, mostrando no monitor Serial o endereço de IP registrado, como apresentado na figura 2.
Por último, vamos fazer a chamadas dos métodos para apontar a função responsável por criar a página em HTML quando a URL foi acessada (server.on), quando o client não consegue ter acesso ao server apontamos a função responsável por retornar o uma mensagem informando a falha (server.onNotFound) e por fim inicializamos o server (server.begin).
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 |
void setup() { Serial.begin(115200); // Configura o driver WiFi para o modo Station WiFi.mode(WIFI_STA); // Inicializa o driver e conecta-se à rede local WiFi.begin(ssid, password); delay(5000); // Aguarda até que esteja conectado à rede local while (WiFi.status() != WL_CONNECTED) { Serial.println("Aguarde conectar-se à rede..."); delay(500); } // Imprime o endereço IP na serial Serial.println("Conectado com sucesso!"); Serial.print("IP: "); Serial.println(WiFi.localIP()); // Adiciona a função "handle_on_connect" quando o servidor estiver online server.on("/", handle_on_connect); // Adiciona a função "handle_not_found" quando o servidor estiver offline server.onNotFound(handle_not_found); // Inicia o servidor server.begin(); // Informa que o Web Server foi inicializado Serial.println("Web Server Ativo"); } |
No void loop, vamos aguardar as requisições HTTP sempre que o cliente desejar acessar o servidor. Recebe o valor percentual de luminosidade, para isso vamos utilizar a função map para converter as leituras analógicas em valores percentuais entre 0 a 100.
1 2 3 4 5 6 7 8 9 10 11 |
void loop() { // Trata as requisições HTTP e sinaliza os eventos server.handleClient(); // Realiza uma conversão do valor de tensão para valor em percentual light_percent = map(analogRead(LDR_PIN), MAX_ANALOG, MIN_ANALOG, MIN_PERCENT, MAX_PERCENT); // Aguarda 5 milisegundos delay(5); } |
Conclusão
Neste artigo, mostramos como criar um servidor utilizando o Franzininho WiFi na rede local. Para aqueles leitores que não estão familiarizados com a estruturação de um arquivo HTML, pode haver alguma dificuldade, mas existem várias ferramentas online disponíveis que podem ajudar e servir como fonte de pesquisa.
Convidamos você a explorar os outros recursos da biblioteca Web Server, a fim de criar aplicações mais robustas e também compartilhar seus resultados com a comunidade por meio de artigos ou vídeos.