Shield Ethernet W5100 – Monitorando Sensores com um Servidor Web
Se você gostou do nosso tutorial inicial sobre a criação de Servidores Web utilizando o Arduino UNO juntamente com o Shield Ethernet W5100, prepare-se, pois, neste tutorial vamos dar sequência ao conteúdo citado, apresentando novos conceitos para que você possa incrementar a sua aplicação. Neste tutorial você aprenderá como a monitorar as informações de seu Arduino, como por exemplo, temperatura, através de um navegador com o auxilio de um Servidor Web implementado com o Shield Ethernet W5100
É importante, para o pleno entendimento desse tutorial, que o leitor tenha lido o tutorial anterior: Shield Ethernet W5100 – Criando um Servidor Web com Arduino
[toc]
Mãos à obra – Monitorando sensores com um Servidor Web
Nesta seção iremos demonstrar todos os passos que você deve seguir para aprender a monitorar sensores com um Servidor Web. De maneira mais específica, vamos desenvolver um projeto em que o usuário consiga monitorar valores de temperatura provenientes de um sensor LM35 (não esqueça de conferir nosso tutorial sobre o sensor de temperatura LM35 clicando aqui) e também o estado de um botão, ou seja, se o mesmo está pressionado ou não.
Componentes necessários
Para reproduzir este projeto, você irá precisar dos seguintes componentes:
- 1 x Arduino UNO Rev 3
- 1 x Shield Ethernet Wiznet W5100
- 1 x Sensor de temperatura LM35
- 1 x Resistor 150 Ω
- 1 x Resistor 10k Ω
- 1 x Push-button
Montando o projeto
Na figura abaixo você pode conferir o hardware pronto para ser utilizado.
Gostaríamos de sugerir que você tenha bastante cuidado no momento em que for encaixar o Shield Ethernet W5100 no Arduino UNO, pois, além da possibilidade de entortar os pinos do shield, você também pode se machucar.
Lembre-se que o shield em questão possui uma série de pinos em sua parte inferior, tanto nas laterais como em sua parte dianteira, portanto, antes de pressionar o mesmo sobre o Arduino UNO, certifique-se de que os pinos estejam levemente posicionados em suas respectivas entradas para que então você possa ir realizando o encaixe lentamente.
Realizando as conexões
Para reproduzir este projeto, garanta que o seu Shield Ethernet W5100 esteja ligado corretamente a uma das portas LAN presentes no seu modem ou roteador.
Programando
Este programa foi elaborado a partir do código-exemplo da biblioteca Ethernet.h denominado WebServer.
#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() { pinMode(5,INPUT); Ethernet.begin(mac, ip); server.begin(); } void loop() { EthernetClient client = server.available(); if (client) { boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); if (c == '\n' && currentLineIsBlank) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println("Refresh: 2"); client.println(); client.println("<!DOCTYPE html>"); client.println("<html>"); client.println("<head>"); client.println("<title>Servidor Web VDS</title>"); client.println("</head>"); client.println("<body>"); client.println("<h1><font color=#4279c7>Servidor Web do Vida de Silício</font></h1>"); client.println("<hr/>"); client.println("<h1>Temperatura</h1>"); porta_analogica(client); client.println("<br/>"); client.println("<h1>Entrada digital</h1>"); porta_digital(client); client.println("</body>"); client.println("</html>"); break; } if (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') { currentLineIsBlank = false; } } } delay(1); client.stop(); } } void porta_analogica(EthernetClient client_aux) { client_aux.print("LM35:"); int valor = analogRead(A0); float temperatura = (((valor*5)/1023)-0.5)*100; if(temperatura >=50) { client_aux.println("<font color=#FF0000>"); client_aux.println(temperatura); client_aux.println("graus"); client_aux.println("</font>"); } else { client_aux.println("<font color=#000000>"); client_aux.println(temperatura); client_aux.println("graus"); client_aux.println("</font>"); } } void porta_digital(EthernetClient client_aux) { client_aux.print("Pino digital 5:"); bool valor = digitalRead(5); if(valor == HIGH) { client_aux.println("<font color=#FF0000> Ligado</font>"); } else { client_aux.println("<font color=#000000> Desligado</font>"); } }
Colocando para funcionar
Veja como ficou nosso segundo Servidor Web.
Entendendo a fundo
Antes de começarmos com a explicação do código, gostaríamos de ressaltar que iremos apresentar os detalhes apenas dos tópicos não contemplados no tutorial anterior, 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 nosso material citado anteriormente.
Software
– 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 do pino digital que será utilizado (este terá o papel de uma entrada digital) . 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() { pinMode(5,INPUT); Ethernet.begin(mac, ip); server.begin(); }
– Criando a página para responder à requisição do navegador
No artigo anterior foi possível compreender como devemos proceder para elaborar uma página bem simples, contendo apenas elementos escritos e também estáticos, ou seja, que não sofriam nenhum tipo de alteração. Neste momento, iremos incrementar o programa criado anteriormente, portanto, vamos deixar de lado a parte referente ao processo de requisição do navegador (já explicado) e iremos focar apenas na elaboração da página que cumpra o objetivo proposto neste material.
Você se lembra do cabeçalho padrão que enviamos para o navegador antes de enviarmos a página propriamente dita? Para ajudar, vamos colocá-lo aqui.
client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println();
Definindo tempo de atualização da página
A primeira modificação que faremos neste momento será a inclusão de uma linha de código que faça com que a página seja atualizada em intervalos de tempo definidos. Isto é importante para este projeto em virtude de estarmos trabalhando com aquisição de variáveis, portanto, devemos atualizar a página periodicamente para que seja possível visualizarmos sempre os valores atuais das variáveis envolvidas. Sendo assim, utilizamos a seguinte sentença para que a página seja atualizada de 2 em 2 segundos.
client.println("Refresh: 2");
Veja como ficará o nosso cabeçalho padrão
client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println("Refresh: 2"); client.println();
A estrutura da página em HTML
O próximo passo que faremos será construir, de fato, a página que será enviada ao navegador. Com uma breve recapitulação, devemos lembrar que todo conteúdo que compõe a página deve estar dentro da seguinte estrutura:
client.println("<!DOCTYPE HTML>"); client.println("<html>"); . . ***** Conteúdo da página ***** . . client.println("</html>");
Como ressaltado anteriormente, dentro desta estrutura temos o conteúdo da página que queremos enviar para o navegador, de modo que, nesta, devemos ter pelo menos dois blocos, um responsável pelas informações gerais do documento, limitado pelo uso do par <head></head> e o outro, por sua vez, deve conter o corpo da página e está entre as tags <body> e </body>.
client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head>"); . . ***** Bloco 1 ***** . . client.println("</head>"); client.println("<body>"); . . ***** Bloco 2 ***** . . client.println("</body>"); client.println("</html>");
Definido o título para a página
Neste momento, vamos utilizar apenas uma tag dentro do bloco 1, denominada <title>, cuja função consistirá em definir um título para a página (este título aparecerá na aba do navegador). Para executarmos a ação proposta, devemos colocar o título desejado entre o par <title></title>.
client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<head>"); client.println("<title>Servidor Web VDS</title>"); client.println("</head>"); client.println("<body>"); . . ***** Bloco 2 ***** . . client.println("</body>"); client.println("</html>");
Veja como ficou o título da nossa página:
Escrevendo o corpo da página web
Quanto ao corpo da página (entre o par <body></body>), a primeira coisa que faremos será colocar um título visível na própria página. Para realizar este procedimento, utilizaremos a tag <h1>, que por sua vez, consiste em uma tag para apresentar um determinado texto em um modelo predefinido. Além disso, utilizaremos também a tag <font>, através da qual, poderemos fazer alterações no título produzido.
client.println("<h1><font color=#4279c7>Servidor Web do Vida de Silício</font></h1>");
Alguns pontos no trecho de código acima devem ser ressaltados:
- Tudo que estiver escrito entre o par <h1></h1> estará pré formatado no estilo deste cabeçalho.
- A tag <font> é responsável por modificar algum atributo relativo à formatação de uma determinada porção de texto. Para isto, devemos colocar o nome do atributo que queremos modificar, após a palavra font (apenas na tag de abertura), sendo assim, quando escrevemos <font color=#4279c7>, estamos indicando que a porção de texto entre o par <font color=#4279c7></font> deverá está colorida em um certo tom de azul (dado pelo código RGB em hexadecimal #4279c7).
- Repare que a palavra Silício foi escrita no código como Silício. Esta forma de escrita é necessária sempre que temos a utilização de algum tipo de acento, pois, nem todos os dispositivos estão configurados para apresentar caracteres acentuados da mesma forma. Sendo assim, utilizamos o comando í para colocar o acento agudo na letra i da palavra Silício.
Veja o resultado deste procedimento na figura abaixo:
Posteriormente, vamos inserir uma barra horizontal para separar o título criado no passo anterior dos textos que ainda serão criados, através do comando <hr/>.
client.println("<hr/>");
Após a inserção da barra citada, nossa página ficará da seguinte maneira:
Imprimindo a tempertatura
Em seguida, escrevemos outro texto utilizando o modelo de cabeçalho h1 referente ao valor que será obtido pelo sensor de temperatura LM35.
client.println("<h1>Temperatura</h1>");
Com este passo, a página será apresentada assim:
O próximo passo consiste em apresentar o valor de temperatura obtido através da conversão do sinal proveniente do sensor de temperatura utilizado. Obviamente, existem várias formas de fazer isso, no entanto, nós criamos uma função própria para isso, chamada porta_analogica() e passamos a variável client como parâmetro da mesma.
porta_analogica(client);
A função porta_analogica() será responsável por fazer a aquisição do valor de tensão na porta analógica A0 proveniente do sensor de temperatura LM35. Repare que nesta função utilizamos um conjunto if()/else para testar se o valor de temperatura é superior a um determinado valor, de modo que, caso seja, apresentaremos este valor na cor vermelha e caso não seja, na cor preta.
void porta_analogica(EthernetClient client_aux) { client_aux.print("LM35:"); int valor = analogRead(A0); float temperatura = (((valor*5)/1023)-0.5)*100; if(temperatura >=50) { client_aux.println("<font color=#FF0000>"); client_aux.println(temperatura); client_aux.println("graus"); client_aux.println("</font>"); } else { client_aux.println("<font color=#000000>"); client_aux.println(temperatura); client_aux.println("graus"); client_aux.println("</font>"); } }
A apresentação do valor de temperatura ficará conforme a figura abaixo:
Imprimindo o estado da entrada digital – Botão
Após chamar a função porta_analogica(), utilizamos o comando <Br/> para fazer com que a próxima sentença utilizada na construção da página ocorra na próxima linha da tela.
client.println("<br/>");
Neste momento escrevemos um outro texto utilizando o modelo de cabeçalho h1. Este irá definir o título da seção em que o estado do botão será apresentado.
client.println("<h1>Entrada digital</h1>");
Confira em que estágio nossa página está:
Por fim, chamamos a função porta_digital() cuja função consiste realizar os procedimentos necessários para apresentar o estado da nossa variável digital. Repare que, assim como na função porta_analogica(), também passamos a variável cliente como parâmetro.
porta_digital(client);
No bloco de código abaixo demonstramos o funcionamento da função porta_digital(), que por sua vez, apresentará a palavra Ligado, na cor vermelha, caso o botão esteja pressionado e a palavra Desligado, na cor preta, caso o botão esteja solto
void porta_digital(EthernetClient client_aux) { client_aux.print("Pino digital 5:"); bool valor = digitalRead(5); if(valor == HIGH) { client_aux.println("<font color=#FF0000> Ligado</font>"); } else { client_aux.println("<font color=#000000> Desligado</font>"); } }
Veja o nosso resultado final:
Os procedimentos citados anteriormente servem para elaborar a página que será exibida no navegador em resposta a requisição feita pelo mesmo, de modo que, caso você queira entender partes do código externas ao que foi apresentado, verifique nosso primeiro tutorial.
Considerações finais
Neste tutorial, demonstramos como você monitorar as variáveis envolvidas no seu projeto, em uma página criada para ser exibida no seu navegador, utilizando um Arduino UNO e um Shield Ethernet W5100. Esta foi a segunda 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.
11 Comments
Deixe uma pergunta, sugestão ou elogio! Estamos ansiosos para ter ouvir!Cancelar resposta
Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.
Prezado Daniel, gostaria de lhe parabenizar pela explicação, me ajudou a ver e escrever o código de forma diferenciada.
Apenas gostaria de saber como posso adicionar um botão para ligar acionar uma saída?
observei outras postagens suas que utilizava um checkbox, realizei a alteração, mas não obtive um bom resultado, você poderia mostrar como devo proceder para este procedimento
Como seria se ao invés de enviar o sinal da porta digital para o site, eu enviasse um código para um aplicativo em App Inventor.
Ao enviar 5V para a porta digital, o arduíno envie um código via ethernet
Professor, perfeito esse tutorial, vc é 1000000
só, poderia me tirar uma dúvida? no projeto que estou desenvolvendo, eu envio dados de temperatura para uma página e ela salva no banco, poderia me dar uma luz de como eu faço pra enviar os dados pra uma página como ja estou fazendo e ainda disponibilizar uma opção como este tuturial? ou seja, preciso salvar os dados no banco e ter uma tela em tempo real, como eu poderia fazer?
Boa tarde, tenho 2 arduinos com Shield Ethernet W5100 em minha rede local, gostaria de quando o valor da temperatura for menor que um certo valor (não sei ainda) o arduino que tem o sensor acende um led no outro arduino? Obr. Abr.
Daniel, meus parabéns pela sua didática e clareza na explicação !!, Estou me envolvendo agora profissionalmente em automação, e peguei um projeto para monitorar uma horta com alguns canteiros com horários para irrigação, temperatura, monitoramento completo, já estou estudando bastante, garimpando na net e aplicando com meus conhecimentos, mas sempre falta mais conhecimentos, e vi que sua expertise é imensa no que preciso que é criar um servidor web ( fora do básico né ) com programações de horários, relés, queria ver contigo se consigo trocar umas idéias assim contigo, mas tbm não quero lhe tomar seu tempo, desde grato irmão. Neil Bueno
Boa noite!! é possivel fazer uma especie de dashboard que receba informaçoes de varias placas e varios sensores em uma unica pagina web? e então hospeda-la pra facilitar o monitoramento? Gostaria muito de obter respostas! desde ja agradeco!
Olá Iago, pelo que entendi, cada placa com ESP8266 cria uma pagina diferente, com IPs diferentes. Acredito que o que vc possa fazer é as placas acessarem um servidor único para gravar as leituras distintas e este servidor sim mostraria os valores que forem sendo atualizados pelas placas distintas. É tranquilo usando um servidor com scripts PHP, as placas enviarão comandos de internet como por exemplo: http://www.servidorphp.com.br/script.php?id=id_placa&valor1=xxx&valor2=yyy…&valorN=zzz no servidor, que recebe essa chamada grava no banco de dados os valores de cada placa e na pagina do servidor são exibidas as leituras
O artigo esta bem bacana, mas quando montei baseado na foto apresentada do circuito o arduino iniciava e desligava, fui conferir então e vi que a polaridade dos terminais do LM35 estão invertidas, foi trocar os fios e funcionou de primeira.
Muito bom o artigo, me ajudou muito!
Precisaria de um artigo desde mesmo modo só que com sensor de pulso.
Daniel,
Parabéns pelo artigo! Muito claro e o código funcionou perfeitamente aqui na minha bancada! Estou precisando do código da leitura da entrada digital e o código que você escreveu era exatamente o que estava procurando. Gostei muito da página e vou visitá-la mais vezes para aprender mais.
Everton, tudo bem?
Muito obrigado pelo retorno. Ficamos felizes por poder contribuir com você!
Quanto às entradas digitais, o procedimento é o mesmo, no entanto, você deve apenas realizar as modificações para que a leitura seja feita em uma entrada digital, ao invés da entrada analógica.