A classe EthernetServer – Configurando um servidor web com Arduino

Arduino como servidor de rede – a classe EthernetServer

Projeto: Criando um Servidor Web com Arduino e Ethernet Shield

Vamos colocar em prática a teoria mostrada na lição anterior sobre o shield ethernet no Arduino, criando um projeto simples com um Arduino Uno (outras placas também funcionam) e um Shield Ethernet: um Servidor Web, sistema que aceita solicitações de clientes e permite enviar dados como resposta. Por exemplo, podemos ter um sensor medindo a temperatura do ambiente, e consultar os valores medidos pela Internet ou rede local, usando um navegador que acessa o  Servidor Web configurado.

Neste tutorial vamos mostrar como usar um shield Ethernet e a classe EthernetServer para configurar um servidor de rede (web) com Arduino.

Lista de materiais

Vamos precisar de :

  • 1 Shield Ethernet
  • Arduino (Uno, Mega, etc)
  • Cabo de Rede
  • Roteador da sua rede local
  • PC com navegador para testes

A seguir podemos ver o Shield Ethernet conectado a um Arduino Uno:

A Classe EthernetServer

A função desta classe é criar um objeto servidor que irá escutar (aguardar solicitações) requisições de conexão de clientes em uma porta específica, e então servir a esses clientes um serviço quando essa conexão é efetuada.

O primeiro passo para configurar um servidor web com Arduino e shield Ethernet é criar um objeto servidor, usando a sintaxe a seguir:

EthernetServer servidor = EthernetServer(porta);

Onde porta é o número da porta de comunicações na qual o servidor escutará. O padrão é a porta 80 para o serviço web.

Devemos inicializar a biblioteca Ethernet passando como parâmetro, no mínimo, o MAC address do shield Ethernet, como segue:

Ethernet.begin(mac);

Também é possível passar outros parâmetros de rede, com o ip, máscara de subrede e gateway padrão, caso utilizamos IP fixo, por exemplo:

Ethernet.begin(mac, ip, gateway, subrede);

O servidor será inicializado quando necessário invocando-se o método begin:

servidor.begin();

Classe EthernetCLient

Para começar a ouvir, é necessário também criar um objeto cliente, o qual irá representar o cliente real com o qual o servidor irá se comunicar. Para isso, usamos a classe EthernetClient, como segue:

EthernetClient cliente = servidor.available();

Esse objeto cliente retorna o valor falso (0) se não houver nenhum cliente disponível no momento.

Para fechar a conexão com um cliente, após a transmissão dos dados requisitados, por exemplo, usamos o método stop():

cliente.stop();

Consulte a descrição completa das funções de cliente e servidor no Arduino para saber mais sobre como usar essas classes.

Enviar e receber dados de um cliente

Usamos as funções print(), println() e write() para enviar dados a um cliente. Para receber (ler) dados do cliente, usamos o método read().

Código de exemplo (simplificados)

EthernetServer servidor = EthernetServer(80);
void setup() {
  Ethernet.begin(mac, ip, gateway, subrede);
  servidor.begin();
}
void loop() {
  EthernetClient cliente = servidor.available();
  if (cliente) {
    Serial.print(cliente.read());  // Ler dados do cliente e enviar para o monitor serial
  }
}

No exemplo, criamos um objeto EthernetServer de nome servidor, inicializando-o com o número da porta que será utilizada, no caso a porta 80 (padrão HTTP).

Na função de setup() inicializamos a biblioteca Ethernet, passando os dados de endereço mac, ip, gateway e máscara de subrede.

Na função loop() criamos o objeto EthernetClient, de nome cliente, que recebe o retorno do método servidor.available(), o qual verifica se o servidor está disponível. Caso esteja, será impressa no monitor serial um dado lido proveniente do cliente de rede.

O método available() retorna o valor 0 (zero) caso não haja um cliente disponível. Caso haja, o objeto cliente o representará.

Vejamos o código completo para a criação de um servidor web simples, que inclui a geração de um cabeçalho HTTP de resposta e o envio de uma página HTML ao cliente (navegador em um computador ou outro dispositivo)

Código para o servidor Web

Abaixo temos o código completo do sketch de nosso servidor web com Arduino:

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetServer servidor(80);

void setup() {
 Serial.begin(9600);
//Desativando o SD Card:
 pinMode(4, OUTPUT);
 digitalWrite(4, HIGH);
 
 Ethernet.begin(mac);
 servidor.begin();
 
 Serial.print("IP do servidor: ");
 Serial.println(Ethernet.localIP());
 Serial.print("Gateway: ");
 Serial.println(Ethernet.gatewayIP());
}

void loop() {
 EthernetClient cliente = servidor.available();
 if (cliente) {
   boolean linha_atual_branca = true;
   while (cliente.connected()) {
     if (cliente.available()) {
       char c = cliente.read();
       Serial.write(c);
 
       if (c == '\n' && linha_atual_branca) {
         // Criando o cabeçalho HTTP:
         cliente.println("HTTP/1.1 200 OK");
         cliente.println("Content-Type: text/html");
         cliente.println("Connection: close");
         cliente.println("Refresh: 5");
         cliente.println();
         // Código da página Web a ser exibida:
         cliente.println("<!DOCTYPE html>");
         cliente.println("<html lang='pt-br'>");
         cliente.println("<head>");
         cliente.println("<meta charset='UTF-8'>");
         cliente.println("<title>Servidor Web com Arduino</title>");
         cliente.println("</head>");
         cliente.println("<body>");
         cliente.println("<hr>");
         cliente.println("<p>Bem-vindo à Bóson Treinamentos em Tecnologia!</p>");
         cliente.println("<hr>");
         cliente.println("</body>");
         cliente.println("</html>");
         break;
       }
     if (c == '\n') {
       // Iniciando uma nova linha
       linha_atual_branca = true;
     }
     else if (c != '\r') {
       // Há um caractere na linha atual
       linha_atual_branca = false;
     }
   }
 }
 // Tempo para o navegador receber os dados
 delay(1);
 // Fechar a conexão:
 cliente.stop();
 }
}    

Após carregar o sketch no Arduino, abrimos o monitor serial para verificar se um endereço IP foi atribuído corretamente ao shield ethernet:

Web Server no Arduino - Monitor Serial

Veja que foi atribuído o IP 192.168.1.109 ao shield ethernet. Vamos agora abrir um navegador no computador e acessar o endereço do nosso servidor web:

Servidor Web com Shield Ethernet no Arduino

Note que também é possível usar um endereço IP fixo no servidor web, bastando para isso acrescentar a seguinte linha ao nosso código (logo após a declaração do endereço MAC), fornecendo o IP desejado, com seus números separados por vírgulas, como no exemplo:

IPAddress ip(192, 168, 1, 10);

E então alterar a instrução:

Ethernet.begin(mac);

para

Ethernet.begin (mac, ip);

Desta forma, será usado o IP fornecido no código, em vez de um endereço IP obtido a partir de um servidor DHCP na rede – o qual pode mudar de tempos em tempos, dificultando a tarefa de acessar o Arduino pela rede.

No próximo tutorial vamos mostrar como é possível enviar comandos a um Arduino a partir de um navegador, por meio da configuração do servidor Web.

 

Sobre Fábio dos Reis (1221 Artigos)
Fábio dos Reis trabalha com tecnologias variadas há mais de 30 anos, tendo atuado nos campos de Eletrônica, Telecomunicações, Programação de Computadores e Redes de Dados. É um entusiasta de Ciência e Tecnologia em geral, adora Viagens e Música, e estuda idiomas, além de ministrar cursos e palestras sobre diversas tecnologias em São Paulo e outras cidades do Brasil.

2 Comentários em A classe EthernetServer – Configurando um servidor web com Arduino

  1. Boa noite. É possível pegar os dados de um multimedidor PM 5000, via Ethernet e usar o arduino como gate, e salvar os dados no cartao de memoria!?

  2. Nilton Oliveira // 22/07/2020 em 11:02 // Responder

    Bom dia, preciso fazer a comunicação via internet.
    Fiz a configuração No-IP. No site no-ip não aceita configurar a porta 80 e sim outra.
    Ao trocar a porta (80) aqui no arduino no teste de abrir o site aqui na máquina, acontece de não abrir. Qual é a solução ?

Escreva um comentário

Seu e-mail não será divulgado


*