terça-feira, 25 de janeiro de 2011

Monitor de Temperatura via TCP/IP

A diferença desse tutorial para o anterior é o meio por onde iremos monitorar temperaturas.Com esse projeto (WebTemp) você poderá monitorar, por exemplo, uma estufa de plantas, uma câmara frigorífica ou mesmo sua adega ;-) tudo remotamente pela Rede Local ou através da Internet usando computador ou celular via Wifi! Para tanto, utilizaremos um Shield, que é uma placa auxiliar "espetada" no Arduino  que tem uma determinada funcionalidade, você pode comprá-lo como também criar o seu próprio shield. Existem shields praticamente pra tudo, nesse link (http://shieldlist.org/)  você confere a lista de shields disponíveis por fabricante, bem como os pinos que eles ocupam no Arduino! Para esse projeto iremos utilizar um dos shields que eu mais gosto e um dos mais interessantes, o EthernetShield (http://www.arduino.cc/en/Main/ArduinoEthernetShield) ,que implementa a pilha TCP/IP e suporte a UDP, possibilitando a comunicação via ethernet! Por ser de fácil implementação, utilizaremos o modelo que conta com o chip da Wiznet 5100 (Figura1)

Figura1 - EthernetShield da WizNet



Testando a placa

Primeiramente você deverá ter privilégios de Administrador para configurar a sua placa de rede no PC. Para que a comunicação possa ser estabelecida sem problemas entre o Arduino e o PC, atribua o IP: 192.168.1.14, Gateway: 192.168.1.1 e Máscara de subrede: 255.255.255.0. Caso não saiba como configurar sua placa de rede no Windows veja esse link: http://www.baboo.com.br/conteudo/modelos/Configurando-uma-rede-domestica-no-Windows-XP_a5307_z0.aspx

Para um teste inicial, "espete" a placa EthernetShield no Arduino, conecte o cabo usb ao PC(os leds da shield acenderão indicando que a placa está energizada), conecte uma extremidade do cabo UTP RJ-45M no conector RJ-45F do Arduino e a outra extremidade do conector na placa de rede do PC. Abra a IDE do Arduino, carregue o código abaixo, salve e faça o upload do sketch: 


/* ---------------------------------------------
 * Teste EthernetShield V1.0 Rev0.0
 * Arduino-ce
 * Comunidade Cearense de Hardware Livre
 * http://groups.google.com/group/arduino-ce?hl=pt-br 
 * http://arduino-ce.blogspot.com 
 * janeiro de 2011
 ---------------------------------------------*/
#include <Ethernet.h>//Biblioteca EthernetShield 

#define SAMPLES 500 //Número de amostras de temperaturas
#define sensortemp 0 //Pino analógico em que estará conectado o sensor LM35

int tempvector[SAMPLES]; //Vetor que armazenará as temperaturas
double tempSensor = 0.0; //Variável auxiliar
int  valAnalog = 0; // Variável para aramazenar a leitura do sensor LM35


byte mac[]     = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //Define o endereço físico da placa
byte ip[]      = { 192, 168, 1, 15 };  // Ip da EthernetShield
byte gateway[] = { 192, 168, 1, 1 };   // Gateway (opcional)
byte subnet[]  = { 255, 255, 255, 0 }; // Mascara de subrede

Server server(80); //Cria o objeto na porta 80

void setup()
{
  Ethernet.begin(mac, ip, gateway, subnet); //Inicializando a ethernet
  server.begin(); //Inicializando o servidor web
}

void loop()
{
  Client client = server.available(); //
  if (client) {
    // uma requisição http termina com uma linha em branco
    boolean current_line_is_blank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read(); // Recebe caractere do browser e guarda em "c"
        // Se chegamos ao fim da linha (recebeu uma nova linha
        // de caractere) e a linha está em branco, a requisição http termina
        // para que possamos enviar uma resposta!
        if (c == '\n' && current_line_is_blank) {
          // Envia um cabeçalho padrão de resposta HTTP 
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          break;
        }
        if (c == '\n') {
          // Se começamos uma nova linha...
          current_line_is_blank = true;
        } 
        else if (c != '\r') {
          // Se ainda temos um caractere na linha atual...
          current_line_is_blank = false;
        }
      }
    }

    client.println("<html>"); //Início do código HTML
    client.println("Arduino na web!");
    client.println("</html>"); //Fim do código HTML 
  } 
  // Damos ao navegador um tempo para receber os dados
  delay(1);
  client.stop();// Fecha a conexão 
}



Após feito o upload para o Arduino, clique em iniciar&gt;executar&gt; digite "cmd" sem aspas, no prompt de comando digite "ping 192.168.1.15 -t" sem aspas. Isso é o teste básico de conexão via rede! Se tudo estiver OK ficará como a tela abaixo:

Figura2 - Pingando no Arduino + EthernetShield



Agora, abra o seu navegador e digite o endereço 192.168.1.15, a janela deverá exibir conforme abaixo:

Figura3 - Teste no Browser


Montando o WebTemp

Desconecte o cabo usb do Arduino e conecte o sensor LM35 conforme figura abaixo:

Figura4 - Conexão EthernetShield com LM35


Reconecte o cabo usb, abra a IDE do Arduino, carregue o código abaixo, salve e faça o upload do sketch: 



/* ---------------------------------------------
 * WebTemp V1.0 Rev0.0
 * Monitor de temperatura via TCP/IP
 * Arduino-ce
 * Comunidade Cearense de Hardware Livre
 * http://groups.google.com/group/arduino-ce?hl=pt-br 
 * http://arduino-ce.blogspot.com 
 * janeiro de 2011
 ---------------------------------------------*/
#include <Ethernet.h>//Biblioteca EthernetShield 

#define SAMPLES 500 //Número de amostras de temperaturas
#define sensortemp 0 //Pino analógico em que estará conectado o sensor LM35

int tempvector[SAMPLES]; //Vetor que armazenará as temperaturas
double tempSensor = 0.0; //Variável auxiliar
int  valAnalog = 0; // Variável para aramazenar a leitura do sensor LM35


byte mac[]     = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //Define o endereço físico da placa
byte ip[]      = { 192, 168, 1, 15 };  // Ip da EthernetShield
byte gateway[] = { 192, 168, 1, 1 };   // Gateway (opcional)
byte subnet[]  = { 255, 255, 255, 0 }; // Mascara de subrede

Server server(80); //Cria o objeto na porta 80

void setup()
{
  Ethernet.begin(mac, ip, gateway, subnet); //Inicializando a ethernet
  server.begin(); //Inicializando o servidor web
}

void loop()
{
  Client client = server.available(); //
  if (client) {
    // uma requisição http termina com uma linha em branco
    boolean current_line_is_blank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read(); // Recebe caractere do browser e guarda em "c"
        // Se chegamos ao fim da linha (recebeu uma nova linha
        // de caractere) e a linha está em branco, a requisição http termina
        // para que possamos enviar uma resposta!
        if (c == '\n' && current_line_is_blank) {
          // envia um cabeçalho padrão de resposta HTTP 
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          break;
        }
        if (c == '\n') {
          // Se começamos uma nova linha...
          current_line_is_blank = true;
        } 
        else if (c != '\r') {
          // Se ainda temos um caractere na linha atual...
          current_line_is_blank = false;
        }
      }
    }

    client.println("<html>"); //Início do código HTML
    client.println("<font face='arial' size='4' color='green' >WEBTEMP V1.0</font><hr>"); //Exibe texto com formatação    
    for (int i=0; i &lt;= SAMPLES; i++) // Incrementa i ate i = SAMPLES
    {    
      valAnalog = analogRead(sensortemp); // Leitura do pino analogico correspondente ao sensor e guarda em valAnalog
      tempvector[i] =( 5.0 * valAnalog * 100.0)/1024.0; //Armazena as temperaturas num vetor de tamanho = SAMPLES
      tempSensor = tempSensor +tempvector[i]; // Soma as temperaturas e armazena em tempSensor
    } 
    tempSensor = tempSensor/SAMPLES;  // Calcula a média das temperaturas e as armazena em 'tempSensor'

    client.println("<h1>"); //Inicio do cabeçalho H1

    client.print(tempSensor); //Exibe a temperatura  

    client.print("&deg;"); // Referência do caratere(graus º) na codificação Latin-1 (ISO-8859-1)     client.println("C" </h1><br>);// Exibe o "C" e finaliza a tag H1

    client.println("<input type='button' value='Refresh' onClick='window.location.href=window.location.href'>");    
    client.println("</html>"); //Fim do código HTML          
  } 
  // Damos ao navegador um tempo para receber os dados
  delay(1);
  client.stop();// Fecha a conexão 
}



Observe que a maior parte o trecho em negrito foi copiado do tutorial anterior com uma mudança, apenas, na exibição da temperatura (vide trecho em cor verde)

Agora, abra o seu navegador e digite o endereço 192.168.1.15, a janela deverá exibir conforme abaixo:

Figura5 - WebTemp em funcionamento




Deixando o projeto mais profissional (Sugestão)

Para acomodar o Arduino + EthernetShiled + LM35 utilizei a caixa SFE Arduino Project Enclosure (http://www.robotshop.com/world/sfe-arduino-project-enclosure.html), disponível na Robotshop, eu sei é um pouco caro, mas fica um ótimo acabamento! Vide fotos do projeto finalizado:


Figura6

Figura7

Figura8


Figura9


Alimentando a placa

Se o local monitorado possui um computador com porta usb disponível, a alimentação do circuito poderá ser feita por ela, entretanto, se o local monitorado não tiver computador próximo, o circuito poderá ser alimentado por uma fonte externa de 12V x 500mA (Figuras 10 e 11), essa fonte custa em torno de R$25,00 em lojas de eletrônicas. Outra opção seria utilizar uma fonte de carregador de celular com entrada USB (Figuras 12 e 13), que custa menos de R$ 5,00 no DealExtreme (http://www.dealextreme.com/c/batteries-chargers-204)


Figura10

Figura11

Figura12

Figura13
.  


Sugestões:

- O Firmware pode ser alterado para receber até 6 sensores de temperatura, podendo monitorar mais de um ponto, deve-se, no entanto, utilizar cabos blindados e de curto alcance, visto que interferências externas podem prejudicar a leitura do sensor por causa do próprio tamanho do cabo!

- Um Access Point pode ser conectado diretamente ao EthernetShield, o que possibilita o monitoramento via Wifi pelo notebook ou celular com essa tecnologia!


Por enquanto é só. Até o próximo tutorial!



27 comentários:

  1. Boa, mas ainda não consegui comprar este shield

    ResponderExcluir
    Respostas
    1. Mande a mensagem pra nossa lista de discussão https://groups.google.com/group/arduino-ce?hl=pt-BR abraço!

      Excluir
  2. Olá Melo, Congratulações

    Muito bom o seu TUTORIAL! Qdo eu fui compilar recebi um mensagem sobre a necessidade de inclusão da librarie SPI. Fizemos a inclusão e compilou sem problemas... Não deu ainda para fazer um teste completo,isto é, utilizando a shield. Faremos em breve.

    ResponderExcluir
  3. Amigo, tudo bem?

    você testou usando o Access Point? tem alguma sugestão para como utilizá-lo? Por exemplo, se eu quiser monitorar 3 laboratórios ao mesmo tempo, como procederia?

    ResponderExcluir
  4. Amigo, não usei access point, mas funcionaria perfeitamente com ele. Quanto a monitorar mais de um ponto, sugiro fazer uma alteração no firmware para acessar uma página dinâmica (php por exemplo) e passar, por parâmetro, os dados do sensor para um banco de dados, para depois, ser acessado e ter as informações exibidas e formatadas para cada sala. Em caso de dúvida entra na lista para discutirmos o assunto. Abraço!

    ResponderExcluir
  5. Ola! desenvolvemos o arduino duemilanove compativel, visite o nosso site www.empretecnet.com.br para maiores detalhes.

    ResponderExcluir
  6. Parabéns pela qualidade do material.

    Por favor, tenho uma dúvida, ao carregar o código no EthernetShiled ele me voltou o seguinte erro, antes tive que mudar o Server server(80); //Cria o objeto na porta 80, para EthernetServer server(80); //Cria o objeto na porta 80.

    Teria alguma dica para este erro? Configurei a placa do meu computador conforme descrito.

    http://i17.photobucket.com/albums/b57/melisei/CapturadeTela2012-02-04s230043.png

    ResponderExcluir
    Respostas
    1. Mande a mensagem pra nossa lista de discussão https://groups.google.com/group/arduino-ce?hl=pt-BR abraço!

      Excluir
  7. Olá não consegui visualizar o erro. Favor envie um e-mail para tentarmos resolver esse problema! marcelolaranjeira@hotmail.com Abraço!

    ResponderExcluir
  8. Olá! Primeiramente, parabéns pelo tutorial, muito didático.
    Olha tenho uma dúvida com relação a uma aplicação com o arduino ethernet shild. É o seguinte...Se eu fizesse algum programinha cliente( utilizando um socket em java) para comunicação em rede via TCP/IP no meu pc e esse pc estivesse na mesma rede local do arduino, eu conseguiria me comunicar com o servidor que o arduino cria sem precisar ter uma conexão com a internet? Até mais!

    ResponderExcluir
    Respostas
    1. Olá Ueslei, obrigado! Sim pode perfeitamente comunicá-los na rede local! Participe de nossa lista de discussão para sanarmos quaisquer dúvidas https://groups.google.com/group/arduino-ce?hl=pt-BR abraço!

      Excluir
  9. Tah beleza, obrigado pela resposta! Eu vou fazer um socket em um programinha para android e me comunicar com o arduino ethernet, esses são os planos.
    Valeu! Vou participar sim da lista!Até mais

    ResponderExcluir
  10. Tenho uma duvida, é possivel deixar o sensor a uma distancia de 15 metros do arduino?? sem alterar o correto funcionamento e leitura da temperatura???

    ResponderExcluir
  11. Anderson, mesmo que utilize cabo blindado, não recomendo essa distância, pois pequenos ruídos podem atrapalhar a leitura...

    ResponderExcluir
  12. Galera, eu entendo de web, mas não entendo muito do Arduino ainda.

    Já fiz uma versão de um aplicativo aqui, que envia dados via bluetooth do anrdoid para o arduino, tudo blz..

    mas agora, para mais usuarios poderem ter acesso, estou fazendo com interface web.. para nao recarregar a pagina estou fazendo com AJAX..como a requisição é para outro servidor, eu preciso usar JSONP para funcionar o AJAX... mas o que acontece é que o link que o arduino recebe é tipo assim:

    GET /?parametro=valor&_=1355946144421 HTTP/1.1

    e não simplesmente nos exemplos na web:

    GET /valor HTTP/1.1

    como eu faço para receber e tratar esses dados parametro=valor no arduino?


    obrigado.

    ResponderExcluir
  13. Boa noite amigos, gostaria de enviar dados para uma pagina web e a partir destes dados gerar um gráfico como se fosse de estatística, "obs: em tempo real" , eu ja consegui fazer ele enviar dados para um software que eu mesmo desenvolvi em c++ , porem foi pela com..
    Agora gostaria de almentar o numero de pessoas com acesso a esses dados.
    desde de já agradeço.

    ResponderExcluir
  14. A programação de comunicação da placa de rede é a mesma para placa de rede WIFI arduino?

    ResponderExcluir
  15. Amigo....krk.....exelente post......Vou fazer algo parecido no TCC com controle de cameras e iluminação, so n defini a linguagem pra trabalhar via web....C#.NET ou Java....tem alguma sugestão..

    ResponderExcluir
  16. Olá amigo, muito bom esse tutorial, você sabe de alguns sensor de água para Arduino?

    ResponderExcluir
  17. Muito bom o tutorial, mas estou com um probleminha não consigo rodar meu ethernet shield com micrcontrolador enc28j60, você tem algo pra eu tomar como base.

    Agradeço

    ResponderExcluir
  18. nao consegui compilar o codigo no arduino....

    ResponderExcluir
  19. Cara precisa mesmo ser esse Modulo ??? Ou eu posso usar so o concersor de usb para RJ45 femea ??

    ResponderExcluir
    Respostas
    1. Você pode usar o que quiser! Nesse exemplo usei via TCP/IP, assim como no outro exemplo eu usei pela Serial.

      Excluir
  20. Qual o custo total unitário?

    Eh possível em um mesmo shield colocar mais de um sensor de temperatura?

    ResponderExcluir
  21. estou tentando usar o modulo enc28j60 como cliente so tenho que enviar e receber uma string para um servidor local estou usando a lib ethercard-master
    mais nao estou conseguindo nada alguem pode me ajudar

    ResponderExcluir
  22. É possível utilizar o sensor de temperatura DS18B20 sem depender da porta serial (USB), sendo alimentado somente por u ma fonte externa? Pois vou precisar deixar o sensor e o Arduino em ambiente externo, sujeito a intempéries, longe de um notebook ou desktop. Mas pelo que li, esse sensor é dependente da porta serial....

    ResponderExcluir
  23. Boa tarde amigo, como faria pra colocar 16 sensensores com diferentes mac e ip numa só página web para visualização?

    ResponderExcluir