Arduino - Servidor Web com Múltiplas Páginas

Neste tutorial, vamos descobrir como transformar um Arduino em um servidor web capaz de lidar com várias páginas ao mesmo tempo, como index.html, temperature.html, led.html, error_404.html e error_405.html... O conteúdo de cada página, incluindo HTML, CSS e JavaScript, será armazenado em arquivos diferentes na Arduino IDE. Ao acessar o Servidor Web do Arduino a partir de um navegador web no seu PC ou smartphone, você poderá visualizar e controlar sensores e atuadores conectados ao Arduino pela web. Além disso, o servidor web será projetado para aceitar links com ou sem a extensão .html.

Arduino navegador web

Seguindo este tutorial, você poderá transformar seu Arduino em um servidor web com alguns recursos bem legais:

Pode parecer complicado, mas não se preocupe! Este tutorial oferece orientações passo a passo, e o código foi pensado para iniciantes, garantindo que você consiga entender facilmente e criar seu próprio servidor web com Arduino.

Sobre o Arduino Uno R4 e o Servidor Web

Se você não conhece o Arduino Uno R4 e o Servidor Web (incluindo pinagem, funcionamento e programação), pode aprender sobre eles nos seguintes tutoriais:

Como funciona um servidor web no Arduino

Quando um navegador web envia uma requisição HTTP para a placa Arduino, o Arduino precisa ser programado para realizar as seguintes tarefas:

  • Criar um servidor web capaz de escutar requisições HTTP do navegador web.
  • Ler a primeira linha do cabeçalho da requisição HTTP quando receber uma requisição HTTP.
  • Rotear as requisições com base na primeira linha da requisição HTTP para determinar quais páginas web o Arduino deve retornar.
  • (Opcional) Analisar o cabeçalho da requisição HTTP para identificar comandos de controle enviados pelo usuário.
  • (Opcional) Controlar os dispositivos conectados ao Arduino com base nos comandos de controle recebidos.
  • Enviar uma resposta HTTP de volta ao navegador web, que inclui:
    • Um cabeçalho de resposta HTTP.
    • O corpo da resposta HTTP, que contém o conteúdo HTML e (se aplicável) dados de sensores ou o estado dos dispositivos.

    Ao realizar essas tarefas, o Arduino consegue tratar as requisições HTTP de forma eficaz e fornecer respostas adequadas ao navegador web, permitindo o controle e a interação via web com os dispositivos conectados ao Arduino.

    A função de roteamento é a tarefa mais importante, e ela será explicada em detalhes. As outras partes são abordadas no tutorial Arduino - Servidor Web. Depois de entender o algoritmo de roteamento, vamos ver o código completo de um servidor web com várias páginas.

Servidor Web Arduino - Algoritmo de Roteamento

Antes de escrever o código da função de roteamento, você deve criar uma lista das páginas web e dos métodos HTTP correspondentes que estarão disponíveis no Arduino. Neste tutorial, vamos suportar apenas o método GET. No entanto, você pode facilmente estendê-lo para incluir outros métodos HTTP, se necessário. Aqui está uma lista de exemplo:

  • GET página inicial
  • GET página de temperatura
  • GET página da porta
  • GET página do LED

Depois disso, você precisa criar uma lista das primeiras linhas dos cabeçalhos de requisição HTTP correspondentes à lista de páginas:

  • GET página inicial:
    • GET /
    • GET /index.html
  • GET página de temperatura
    • GET /temperature.html
  • GET página da porta
    • GET /door
  • GET página do LED
    • GET /led.html

    Em resumo, temos a seguinte lista:

    GET / GET /index.html GET /temperature.html GET /door.html GET /led.html

Código Arduino - Servidor Web com várias páginas

Abaixo está o código Arduino completo que cria um servidor web com várias páginas. Para manter a simplicidade, o conteúdo HTML de cada página é bem simples e está incorporado diretamente no código do Arduino. Na próxima parte, vamos aprender a separar o conteúdo HTML de cada página em arquivos separados, deixando o código mais organizado e fácil de gerenciar.

/* * Este código de Arduino foi desenvolvido por pt.newbiely.com * Este código de Arduino é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino/arduino-web-server-multiple-pages */ #include <UnoR4WiFi_WebServer.h> // WiFi credentials const char WIFI_SSID[] = "YOUR_WIFI_SSID"; // change your network SSID (name) const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // change your network password // Create web server instance UnoR4WiFi_WebServer server; float getTemperature() { // YOUR SENSOR IMPLEMENTATION HERE // simulate the temperature value float temp_x100 = random(0, 10000); // a ramdom value from 0 to 10000 return temp_x100 / 100; // return the simulated temperature value from 0 to 100 in float } // Page handlers void handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { server.sendResponse(client, "This is home page"); } void handleTemperature(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { server.sendResponse(client, "This is temperature page"); } void handleDoor(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { server.sendResponse(client, "This is door page"); } void handleLed(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { server.sendResponse(client, "This is LED page"); } void handleNotFound(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { server.sendResponse(client, "Page Not Found"); } void setup() { Serial.begin(9600); delay(1000); Serial.println("Arduino Uno R4 WiFi - Multi-Page Web Server"); // Connect to WiFi Serial.print("Connecting to "); Serial.println(WIFI_SSID); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(" connected!"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); // Configure routes server.addRoute("/", handleHome); server.addRoute("/index", handleHome); server.addRoute("/index.html", handleHome); server.addRoute("/temperature", handleTemperature); server.addRoute("/temperature.html", handleTemperature); server.addRoute("/door", handleDoor); server.addRoute("/door.html", handleDoor); server.addRoute("/led", handleLed); server.addRoute("/led.html", handleLed); // Set custom 404 handler server.setNotFoundHandler(handleNotFound); // Start server server.begin(); Serial.println("\n=== Web Server Ready! ==="); Serial.print("Visit: http://"); Serial.println(WiFi.localIP()); } void loop() { server.handleClient(); }

Passos Rápidos

  • Se esta é a primeira vez que você usa o Arduino Uno R4, veja como configurar o ambiente para o Arduino Uno R4 na Arduino IDE.
  • Abra o Gerenciador de Bibliotecas clicando no ícone Library Manager no lado esquerdo da Arduino IDE.
  • Pesquise por Web Server for Arduino Uno R4 WiFi e localize a biblioteca Web Server criada pela DIYables.
  • Clique no botão Install para adicionar a biblioteca Web Server.
Arduino UNO R4 biblioteca Web Server
  • Copie o código acima e abra-o com a Arduino IDE
  • Altere as informações de WiFi (SSID e senha) no código para as suas
  • Clique no botão Upload na Arduino IDE para carregar o código no Arduino
  • Abra o Serial Monitor
  • Confira o resultado no Serial Monitor.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Uno
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno' on 'COM15')
New Line
9600 baud
Connecting to YOUR_WIFI_SSID connected! IP address: 192.168.0.254 Starting web server on IP: 192.168.0.254 === Web Server Ready! === Visit: http://192.168.0.254
Ln 11, Col 1
Arduino Uno on COM15
2
  • Você verá um endereço IP no Serial Monitor, por exemplo: 192.168.0.2
  • Digite os endereços da lista a seguir, um por um, na barra de endereços de um navegador web no seu smartphone ou PC.
192.168.0.2 192.168.0.2/index 192.168.0.2/index.html 192.168.0.2/led 192.168.0.2/led.html 192.168.0.2/door 192.168.0.2/door.html 192.168.0.2/temperature 192.168.0.2/temperature.html 192.168.0.2/blabla 192.168.0.2/blabla.html
  • Observe que você precisa trocar o 192.168.0.2 pelo endereço IP que apareceu no Serial Monitor.
  • Você verá as seguintes páginas: página inicial, página do LED, página da porta, página de temperatura e página Not Found
  • Você também pode conferir a saída no Serial Monitor

O código anterior tem um conteúdo HTML bem simples para cada página. Mas, se quisermos criar uma interface sofisticada com muito HTML, o código pode ficar grande e bagunçado. Para simplificar, vamos aprender a separar o HTML do código do Arduino. Isso nos permite manter o HTML em arquivos separados, facilitando o gerenciamento e o trabalho.

Código Arduino - Servidor Web completo com várias páginas

  • Abra a Arduino IDE.
  • Crie um novo sketch e dê um nome a ele, por exemplo, ArduinoWebServer.ino.
  • Copie o código fornecido e cole-o nesse arquivo.
/* * Este código de Arduino foi desenvolvido por pt.newbiely.com * Este código de Arduino é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino/arduino-web-server-multiple-pages */ #include <UnoR4WiFi_WebServer.h> #include "index.h" #include "temperature.h" #include "door.h" #include "led.h" #include "error_404.h" // WiFi credentials const char WIFI_SSID[] = "YOUR_WIFI_SSID"; // change your network SSID (name) const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // change your network password // Create web server instance UnoR4WiFi_WebServer server; float getTemperature() { // YOUR SENSOR IMPLEMENTATION HERE // simulate the temperature value float temp_x100 = random(0, 10000); // a ramdom value from 0 to 10000 return temp_x100 / 100; // return the simulated temperature value from 0 to 100 in float } // Page handlers void handleHome(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { server.sendResponse(client, HTML_CONTENT_HOME); } void handleTemperature(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { String html = String(HTML_CONTENT_TEMPERATURE); html.replace("TEMPERATURE_MARKER", String(getTemperature(), 2)); server.sendResponse(client, html.c_str()); } void handleDoor(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { String html = String(HTML_CONTENT_DOOR); html.replace("DOOR_STATE_MARKER", "OPENED"); server.sendResponse(client, html.c_str()); } void handleLed(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { String html = String(HTML_CONTENT_LED); html.replace("LED_STATE_MARKER", "OFF"); server.sendResponse(client, html.c_str()); } void handleNotFound(WiFiClient& client, const String& method, const String& request, const QueryParams& params, const String& jsonData) { String html = String(HTML_CONTENT_404 ); server.sendResponse(client, html.c_str()); } void setup() { Serial.begin(9600); delay(1000); Serial.println("Arduino Uno R4 WiFi - Multi-Page Web Server"); // Connect to WiFi Serial.print("Connecting to "); Serial.println(WIFI_SSID); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(" connected!"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); // Configure routes server.addRoute("/", handleHome); server.addRoute("/index", handleHome); server.addRoute("/index.html", handleHome); server.addRoute("/temperature", handleTemperature); server.addRoute("/temperature.html", handleTemperature); server.addRoute("/door", handleDoor); server.addRoute("/door.html", handleDoor); server.addRoute("/led", handleLed); server.addRoute("/led.html", handleLed); // Set custom 404 handler server.setNotFoundHandler(handleNotFound); // Start server server.begin(); Serial.println("\n=== Web Server Ready! ==="); Serial.print("Visit: http://"); Serial.println(WiFi.localIP()); } void loop() { server.handleClient(); }
  • Altere as informações de WiFi (SSID e senha) no código para as suas
  • Crie o arquivo index.h na Arduino IDE da seguinte forma:
    • Clique no botão logo abaixo do ícone do serial monitor e escolha New Tab, ou use as teclas Ctrl+Shift+N.
    Arduino IDE 2 adiciona arquivo
    • Dê ao arquivo o nome index.h e clique no botão OK
    Arduino IDE 2 adiciona arquivo index.h
    • Copie o código abaixo e cole-o no arquivo index.h.
    /* * Este código de Arduino foi desenvolvido por pt.newbiely.com * Este código de Arduino é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino/arduino-web-server-multiple-pages */ const char *HTML_CONTENT_HOME = R""""( <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="icon" href="data:,"> <title>Home Page</title> </head> <body> <h1>Welcome to the Home Page</h1> <ul> <li><a href="/led">LED Page</a></li> <li><a href="/temperature">Temperature Page</a></li> <li><a href="/door">Door Page</a></li> </ul> </body> </html> )"""";
    • Da mesma forma, crie o arquivo temperature.h na Arduino IDE com o seguinte conteúdo.
    /* * Este código de Arduino foi desenvolvido por pt.newbiely.com * Este código de Arduino é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino/arduino-web-server-multiple-pages */ const char *HTML_CONTENT_TEMPERATURE = R""""( <!DOCTYPE html> <html> <head> <title>Arduino - Web Temperature</title> <meta name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=0.7"> <meta charset="utf-8"> <link rel="icon" href="https://diyables.io/images/page/diyables.svg"> <style> body { font-family: "Georgia"; text-align: center; font-size: width/2pt;} h1 { font-weight: bold; font-size: width/2pt;} h2 { font-weight: bold; font-size: width/2pt;} button { font-weight: bold; font-size: width/2pt;} </style> <script> var cvs_width = 200, cvs_height = 450; function init() { var canvas = document.getElementById("cvs"); canvas.width = cvs_width; canvas.height = cvs_height + 50; var ctx = canvas.getContext("2d"); ctx.translate(cvs_width/2, cvs_height - 80); update_view(TEMPERATURE_MARKER); } function update_view(temp) { var canvas = document.getElementById("cvs"); var ctx = canvas.getContext("2d"); var radius = 70; var offset = 5; var width = 45; var height = 330; ctx.clearRect(-cvs_width/2, -350, cvs_width, cvs_height); ctx.strokeStyle="blue"; ctx.fillStyle="blue"; //5-step Degree var x = -width/2; ctx.lineWidth=2; for (var i = 0; i <= 100; i+=5) { var y = -(height - radius)*i/100 - radius - 5; ctx.beginPath(); ctx.lineTo(x, y); ctx.lineTo(x - 20, y); ctx.stroke(); } //20-step Degree ctx.lineWidth=5; for (var i = 0; i <= 100; i+=20) { var y = -(height - radius)*i/100 - radius - 5; ctx.beginPath(); ctx.lineTo(x, y); ctx.lineTo(x - 25, y); ctx.stroke(); ctx.font="20px Georgia"; ctx.textBaseline="middle"; ctx.textAlign="right"; ctx.fillText(i.toString(), x - 35, y); } // shape ctx.lineWidth=16; ctx.beginPath(); ctx.arc(0, 0, radius, 0, 2 * Math.PI); ctx.stroke(); ctx.beginPath(); ctx.rect(-width/2, -height, width, height); ctx.stroke(); ctx.beginPath(); ctx.arc(0, -height, width/2, 0, 2 * Math.PI); ctx.stroke(); ctx.fillStyle="#e6e6ff"; ctx.beginPath(); ctx.arc(0, 0, radius, 0, 2 * Math.PI); ctx.fill(); ctx.beginPath(); ctx.rect(-width/2, -height, width, height); ctx.fill(); ctx.beginPath(); ctx.arc(0, -height, width/2, 0, 2 * Math.PI); ctx.fill(); ctx.fillStyle="#ff1a1a"; ctx.beginPath(); ctx.arc(0, 0, radius - offset, 0, 2 * Math.PI); ctx.fill(); temp = Math.round(temp * 100) / 100; var y = (height - radius)*temp/100.0 + radius + 5; ctx.beginPath(); ctx.rect(-width/2 + offset, -y, width - 2*offset, y); ctx.fill(); ctx.fillStyle="red"; ctx.font="bold 34px Georgia"; ctx.textBaseline="middle"; ctx.textAlign="center"; ctx.fillText(temp.toString() + "°C", 0, 100); } window.onload = init; </script> </head> <body> <h1>Arduino - Web Temperature</h1> <canvas id="cvs"></canvas> </body> </html> )"""";
    • Da mesma forma, crie o arquivo door.h na Arduino IDE com o seguinte conteúdo.
    /* * Este código de Arduino foi desenvolvido por pt.newbiely.com * Este código de Arduino é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino/arduino-web-server-multiple-pages */ const char *HTML_CONTENT_DOOR = R""""( <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="icon" href="data:,"> <title>Door Page</title> </head> <body> <h1>Door Page</h1> <p>Door State: <span style="color: red;">DOOR_STATE_MARKER</span></p> </body> </html> )"""";
    • Da mesma forma, crie o arquivo led.h na Arduino IDE com o seguinte conteúdo.
    /* * Este código de Arduino foi desenvolvido por pt.newbiely.com * Este código de Arduino é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino/arduino-web-server-multiple-pages */ const char *HTML_CONTENT_LED = R""""( <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="icon" href="data:,"> <title>LED Page</title> </head> <body> <h1>LED Page</h1> <p>LED State: <span style="color: red;">LED_STATE_MARKER</span></p> </body> </html> )"""";
    • Da mesma forma, crie o arquivo error_404.h na Arduino IDE com o seguinte conteúdo.
    /* * Este código de Arduino foi desenvolvido por pt.newbiely.com * Este código de Arduino é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino/arduino-web-server-multiple-pages */ const char *HTML_CONTENT_404 = R""""( <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="icon" href="data:,"> <title>404 - Page Not Found</title> <style> h1 {color: #ff4040;} </style> </head> <body> <h1>404</h1> <p>Oops! The page you are looking for could not be found on Arduino Web Server.</p> <p>Please check the URL or go back to the <a href="/">homepage</a>.</p> <p>Or check <a href="https://arduinogetstarted.com/tutorials/arduino-web-server-multiple-pages"> Arduino Web Server</a> tutorial.</p> </body> </html> )"""";
    • Agora você tem vários arquivos na Arduino IDE, como abaixo:
    Arduino IDE 2 vários arquivos
    • Clique no botão Upload na Arduino IDE para carregar o código no Arduino
    • Acesse as páginas web da placa Arduino pelo navegador web, uma por uma, como antes. Você verá todas as páginas web como abaixo:
    Arduino várias páginas web

    ※ Nota:

    • Se você fizer alterações no conteúdo HTML dentro do arquivo index.h, mas não modificar nada no arquivo ArduinoWebServer.ino, a Arduino IDE não vai atualizar o conteúdo HTML quando você compilar e carregar o código no Arduino Uno R4 WiFi.
    • Para forçar a Arduino IDE a atualizar o conteúdo HTML nessa situação, você precisa fazer uma modificação no arquivo ArduinoWebServer.ino. Por exemplo, você pode adicionar uma linha vazia ou inserir um comentário. Essa ação faz a IDE reconhecer que houve mudanças no projeto, garantindo que o seu conteúdo HTML atualizado seja incluído no upload.

※ NOSSAS MENSAGENS

  • Fique à vontade para compartilhar o link deste tutorial. Porém, por favor, não use nosso conteúdo em outros sites. Investimos muito esforço e tempo para criar este conteúdo, por favor respeite nosso trabalho!