Shield Ethernet W5100 – Controlando um LED RGB via PWM com HTML – Servidor WEB

Neste tutorial, iremos ampliar um pouco mais do conteúdo relacionado à criação de um Servidor Web utilizando o Arduino UNO juntamente com o Ethernet Shield W5100. Anteriormente, aprendemos a desenvolver uma interface utilizando caixas de seleção, através das quais, tornou-se possível o realizarmos o acionamento e o desligamento de relés (e consequentemente cargas que não poderiam ser acionadas diretamente pelo Arduino UNO). Desta vez, vamos demonstrar como criar uma interface HTML para controlarmos a cor da luz emitida por um LED RGB usando PWM.

É importante, para o pleno entendimento desse tutorial, que o leitor tenha lido todos os tutoriais anteriores:

Além disso, caso você queira aprender mais sobre o funcionamento destes tipo de LED, confira o nosso tutorial específico sobre a utilização de LED RGB.

[toc]

kit robotica educacional com Arduino ESP ou Microbit


Mãos à obra – Criando a interface HTML para manipulação do LED RGB via PWM

Componentes necessários

Para desenvolver este projeto, precisaremos dos seguintes componentes:

Montando o projeto

Hardware utilizado.

Programando

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

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 25, 16);
EthernetServer server(80);

void setup() 
{
  Ethernet.begin(mac, ip);
  server.begin();
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(9,OUTPUT);
 // Serial.begin(9600);
}
void loop() 
{  
     String req_str;
     EthernetClient client = server.available();  
     if (client) 
     {
           req_str = "";
           boolean currentLineIsBlank = true;
           while (client.connected()) 
           {
                 if (client.available()) 
                 {
                       char c = client.read();    
                       req_str += c;    
                       if(c == '\n' && currentLineIsBlank) 
                       {
                               int pwm_range_5 = 0;
                               int pwm_range_6 = 0;
                               int pwm_range_9 = 0;
                               client.println("HTTP/1.1 200 OK");
                               client.println("Content-Type: text/html");
                               client.println("Connection: close");
                                client.println();
                             client.println("<!DOCTYPE html>");
                             client.println("<html lang=\"pt-br\">");                
                                  client.println("<head>");
                                       client.println("<meta charset= \"UTF-8\"/>");
                                       client.println("<title>RGB Vida de silício</title>"); 
                                 client.println("</head>");
                                 client.println("<body>");
                                      client.println("<h1>Acionamento de leds RGB</h1>");
                                      client.println("<hr/>");
                                      client.println("<h2>Componentes do led RGB</h2>");
                                       if(req_str.startsWith("POST"))
                                        {
                                              String conteudo_POST = "";
                                              for(int i=0;i<26;i++)
                                              {
                                                  c = client.read();  
                                                  conteudo_POST += c; 
                                                  
                                              }
                                              
                                                   pwm_range_5 = conteudo_POST.substring((conteudo_POST.indexOf("PWM5") + 5),(conteudo_POST.indexOf("PWM6") - 1)).toInt();
                                                   pwm_range_6 = conteudo_POST.substring((conteudo_POST.indexOf("PWM6") + 5),(conteudo_POST.indexOf("PWM9") - 1)).toInt();
                                                   pwm_range_9 = conteudo_POST.substring((conteudo_POST.indexOf("PWM9") + 5),(conteudo_POST.indexOf("PWM9") + 8)).toInt();
                                                   analogWrite(5,pwm_range_5);
                                                   analogWrite(6,pwm_range_6);
                                                   analogWrite(9,pwm_range_9);
                                                    conteudo_POST = "";
                                                
                                            }
                                          client.println ("<form action=\"\" method=\"post\">");
                                                 client.println("<p>Porta D5: " + String(pwm_range_5) + "</p>");
                                                 client.println("0 <input type=\"range\" value=\"" + String(pwm_range_5) + "\"name=\"PWM5\"  min=\"0\"  max=\"255\" step=\"1\" onchange=\"submit()\"/>  255");
                                                 client.println("<p>Porta D6: " + String(pwm_range_6) + "</p>");
                                                 client.println("0 <input type=\"range\" value=\"" + String(pwm_range_6) + "\"name=\"PWM6\"  min=\"0\"  max=\"255\" step=\"1\" onchange=\"submit()\"/>  255");
                                                 client.println("<p>Porta D9: " + String(pwm_range_9) + "</p>");
                                                 client.println("0 <input type=\"range\" value=\"" + String(pwm_range_9) + "\"name=\"PWM9\"  min=\"0\"  max=\"255\" step=\"1\" onchange=\"submit()\"/>  255");
                                           client.println ("</form>");   
                                    client.println ("</body>");
                             client.println ("</html>");
                             break;
                         }
                  if (c == '\n') 
                 {
                       currentLineIsBlank = true;
                 }
                 else if (c != '\r')                   
                {
                      currentLineIsBlank = false; 
                                  }
            }
       }
       delay(1);
      client.stop();
     }
}

Colocando para funcionar

Interface de acionamento do led RGB via pwm
Interface HTML de acionamento do led RGB.

Entendendo a fundo

Software

Antes de começarmos com a explicação do código, gostaríamos de ressaltar que iremos apresentar apenas os detalhes dos tópicos não contemplados nos tutoriais anteriores, pois, desta maneira, será mais fácil focar nas partes referentes às atualizações feitas sobre o programa já existente, portanto, caso você tenha alguma dúvida sobre alguma parte do programa que não seja explicada neste momento, sugerimos que acesse o nossos materiais citados anteriormente.

– Definindo os pré-requisitos para o funcionamento do código

Inicialmente, devemos incluir duas bibliotecas no código para que o mesmo pudesse funcionar corretamente. A biblioteca SPI.h, responsável pela comunicação dos módulos do shield com o Arduino UNO utilizando o protocolo SPI e a biblioteca Ethernet.h que atua possibilitando a conexão do conjunto, em um primeiro momento, com uma rede local.

Após a inclusão das bibliotecas citadas, devemos definir um endereço MAC (lembre-se que este pode ser qualquer um, desde que seja único em sua rede local) e um endereço IP (este deve ser um endereço válido  e disponível dentro da sua rede local). Além disso, devemos criar o objeto que será responsável por representar o Servidor Web no código (aqui, chamamos este de server) e relacioná-lo com a porta 80.

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

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 25, 16);
EthernetServer server(80);

– Definindo as configurações iniciais

Dentro da função setup(), devemos determinar o modo de operação dos pinos digitais que serão utilizados (estes terão o papel de saídas digitais) . Além disso, iniciamos a conexão com a rede local através da função Ethernet.begin() (passando como parâmetro os endereços MAC e IP definidos anteriormente) e também iniciamos o Servidor Web por meio da sentença server.begin() (lembre-se que server é o objeto criado para representar o Servidor Web no código).

void setup() 
{
  Ethernet.begin(mac, ip);
  server.begin();
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(9,OUTPUT);
}

– Entendendo as requisições do navegador

Nos tutoriais anteriores, ressaltamos o mecanismo básico de funcionamento dos códigos voltados para a criação de Servidores Web, o qual, começa através de um procedimento padrão, que por sua vez, consiste em utilizar uma variável para obter caractere por caractere da requisição feita pelo navegador até que esta seja completamente recebida pelo Arduino UNO, de modo que, apenas a partir deste ponto inicia-se o processo de elaboração da página.

Em nosso último tutorial, apresentamos o modo de funcionamento do método GET, no entanto, neste material iremos fazer o uso do método POST. Assim como o método GET, o método POST também serve para envio de informações provenientes dos formulários para o nosso Servidor Web. O primeiro passo para a realização deste procedimento na declaração de uma variável local, do tipo String (esta servirá para armazenar a requisição feita pelo navegador).

void loop() 
{  
     String req_str;
     .
     .
     .

Em seguida, criamos o processo no qual esta variável será preenchida com os caracteres da requisição.

if (client.available()) 
                 {
                       char c = client.read();    
                       req_str += c;    
                       . 
                       . 
                       .

De acordo com o tutorial anterior, pudemos aprender que, em uma requisição GET, o parâmetro da requisição, ou seja, o elemento proveniente da interação do usuário do sistema com um formulário, está localizado na primeira linha da requisição em questão. Entretanto, no caso de uma requisição POST, este mesmo elemento está registrado apenas ao final da mesma. Logo, o que vamos fazer aqui é justamente ler a requisição inteira (ou até o aparente final, como se fosse uma requisição GET) e depois forçaremos o programa a ler mais alguns caracteres da mesma (estes irão conter o parâmetro da requisição).

O primeiro passo a ser realizado após a leitura inteira da requisição é inicializar as variáveis que irão conter os valores a serem utilizados na geração do sinal PWM para cada componente.

 if(c == '\n' && currentLineIsBlank) 
   {
       int pwm_range_5 = 0;
       int pwm_range_6 = 0;
       int pwm_range_9 = 0;
       .
       .
       .

– Enviando o cabeçalho da página

Após termos lido a requisição inteira, devemos primeiramente enviar o cabeçalho padrão para o navegador.

client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();

– Desenvolvendo a nossa página

Para começar a desenvolver a nossa página, utilizamos primeiro a sentença <!DOCTYPE html> para informarmos ao navegador que estamos utilizando a versão 5 da linguagem HTML.

client.println("<!DOCTYPE html>");

Como sabemos, entre as tags <head> e </head>, fazemos algumas configurações pertinentes ao funcionamento da página que estamos desenvolvendo. As configurações citadas, correspondem à determinação do conjunto de caracteres que deverá ser utilizado pelo navegador (para apresentar caracteres acentuados) e à inclusão de um título na aba da página do navegador.

client.println("<head>");
    client.println("<meta charset= \"UTF-8\"/>");
    client.println("<title>RGB Vida de silício</title>"); 
client.println("</head>");

No corpo da página, começamos escrevendo alguns títulos utilizando as tags de cabeçalho <h1> e <h2>.

client.println("<body>");
     client.println("<h1>Acionamento de leds RGB</h1>");
     client.println("<hr/>");
     client.println("<h2>Componentes do led RGB</h2>");
     .
     .
     .

Em seguida, utilizamos a função startsWith() para verificarmos se a requisição que chegou é do tipo POST (esta função verifica se a primeira palavra do conteúdo armazenado na variável req_str é o fragmento de texto POST). Após verificarmos que a requisição é de fato do tipo POST, declaramos uma variável do tipo string e armazenamos nela 26 caracteres (existentes após o aparente término da requisição). Estes 26 caracteres são justamente o parâmetro da requisição POST, de modo que, este terá a seguinte forma: PWM5=xyz&PWM6=xyz&PWM9=xyz.

 if(req_str.startsWith("POST"))
    {
        String conteudo_POST = "";
        for(int i=0;i<26;i++)
        {
            c = client.read();  
            conteudo_POST += c; 
        }

Posteriormente, preenchemos as variáveis pwm_range5/6/9 com os valores existentes na variável conteudo_POST. Este processo, consiste em desmembrar a string inteira em vários pedaços e associar cada um deles à respectiva variável, que por sua vez, será utilizada na geração do sinal PWM. (A explicação do funcionamento das funções utilizadas pode ser encontrada em nossos tutoriais anteriores)

 pwm_range_5 = conteudo_POST.substring((conteudo_POST.indexOf("PWM5") + 5),(conteudo_POST.indexOf("PWM6") - 1)).toInt();
 pwm_range_6 = conteudo_POST.substring((conteudo_POST.indexOf("PWM6") + 5),(conteudo_POST.indexOf("PWM9") - 1)).toInt();
 pwm_range_9 = conteudo_POST.substring((conteudo_POST.indexOf("PWM9") + 5),(conteudo_POST.indexOf("PWM9") + 8)).toInt();

Por fim, geramos os sinais PWM e limpamos a variável conteudo_POST.

analogWrite(5,pwm_range_5);
analogWrite(6,pwm_range_6);
analogWrite(9,pwm_range_9);
conteudo_POST = "";

– Criando o formulário

Neste momento, adicionamos o formulário e explicitamos que o método que será utilizado para o envio de dados na requisição feita pelo navegador será o POST. Entre as tags <form> e </form>, criaremos os ranges, isto é, os elementos que serão utilizados na interface de comandos na página do navegador.

client.println ("<form action=\"\" method=\"post\">");
   client.println("<p>Componente Azul: " + String(pwm_range_5) + "</p>");
   client.println("0 <input type=\"range\" value=\"" + String(pwm_range_5) + "\"name=\"PWM5\"  min=\"0\"  max=\"255\" step=\"1\" onchange=\"submit()\"/>  255");
   client.println("<p>Componente Verde: " + String(pwm_range_6) + "</p>");
   client.println("0 <input type=\"range\" value=\"" + String(pwm_range_6) + "\"name=\"PWM6\"  min=\"0\"  max=\"255\" step=\"1\" onchange=\"submit()\"/>  255");
   client.println("<p>Componente Vermelha: " + String(pwm_range_9) + "</p>");
   client.println("0 <input type=\"range\" value=\"" + String(pwm_range_9) + "\"name=\"PWM9\"  min=\"0\"  max=\"255\" step=\"1\" onchange=\"submit()\"/>  255");
client.println ("</form>");

Os ranges devem ser incluídos no código através da tag <input> (assim como os checkboxes). Nesta tag nós utilizamos alguns atributos, estes são:

  • type: Determina o tipo de elemento de entrada
  • value: Valor no qual o cursor deverá permanecer
  • name: Nome associado ao elemento
  • min/max: Valores extremos da escala
  • step: Passo

Considerações finais

Neste tutorial, demonstramos como você pode fazer para criar um sistema de acionamento de um LED RGB para ser utilizado através de um navegador de internet. Para isto, utilizamos um Arduino UNO em conjunto com um Ethernet Shield W5100. Esta foi a quinta parte de uma série de artigos sobre a criação de Servidores Web, portanto, esperamos que continue nos acompanhando e sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.

Privacy Preference Center