terça-feira, 26 de novembro de 2013

Projeto Arduino + Ethernet Shield + Sensor + Aplicação Web (Java)







Olá Pessoal, conforme prometido estou fazendo um passo a passo do Projeto Arduino + Ethernet Shield + Sensor + Aplicação Web (Java)  


Requisitos de Softwares

_ IDE do Arduino (Preferível a versão 1.0.3).
_ Mysql 5 ou Superior.
_ JDK 6.
_ Netbeans 7.X ou Eclipse (versão para desenvolvimento Web).
_ Apache TomCat ou outro Container de sua preferência que seja compatível.
_ Biblioteca DTH11.

Requisitos de Hardware

_ Arduino Uno, Mega ou Duemilanove.
_ Ethernet Shield Compativel. (No meu caso usei HanRun W5100).

_ Sensor de Temperatura e Umidade DHT11.
_ Jumpers Machos e/ou Fêmeas
_ E um resistor de 100 Ohms caso haja necessidade






Primeiramente gostaria de deixar o esquema de montagem:


O fio vermelho é o 5 volts
O fio preto é o ground
O fio azul é o 3 digital (no meu caso usei o 2)

Simples não ?!
Caso haja necessidade poderá conectar um  resistor de 100 ohms no Ground.


Mais antes de começarmos a codificar, temos que baixar a biblioteca do Sensor DHT11 para o arduino.



1º Passo (Requisitos)

Pode ocorrer de haver a necessidade de ter que baixar a Biblioteca do Ethernet para o arduino, mas em geral essa biblioteca já vem com o IDE


Links
http://www.seucurso.com.br/downloads/DHT11.zip
ou monte os arquivos conforme indicado no site oficial do arduino
http://playground.arduino.cc/main/DHT11Lib

baixe o driver do MySQL. (Em muitos casos pode não ser necessário bastando apenas importar o dado do NetBeans, mais se estiver usando Eclipse, esta etapa é necessário).

http://code.google.com/p/nearbuy/downloads/detail?name=mysql-connector-java-5.1.13-bin.jar&can=2&q=


Baixado a biblioteca do DHT11, descompacte os arquivos e copie para a pasta libraries do diretório onde está instalado o seu IDE do Arduino


2º Passo (Arduino)

Abra o IDE do Arduino e copie o código abaixo.


#include            //Biblioteca para função de Ethernet
#include              //Biblioteca para função de Cliente
#include                 //Biblioteca para função do EthernetShield W5100  
#include             //Biblioteca do DHT11

uint8_t hwaddr[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xBE}; // mac-adress do arduino
uint8_t ipaddr[4] = {192, 168, 0, 177};    // Endereço de IP do arduino (vai depender do seu gateway)
//uint8_t gwaddr[4] = {192, 168, 0, 1};  // Endereço de IO do seu Gateway (Não necessario para este Exemplo)
//uint8_t subnet[4] = {255, 255, 255, 0};                   // mascara da rede   (Não necessario para este Exemplo)

IPAddress serverip(192, 168, 0, 183);                   //Endereço de IP do Servidor

int serverport = 8084;     // a porta do Tomcat/Glassfish que esta sendo usada, no meu caso uso 8084

EthernetClient client;                                 //Instancia do Cliente para Conexao com Web Server



int pinoDHT11 = 2; //pino digital para comunicação
int numeroInterruptorDHT11 = 0; //numero de interrupção (Default para o instancia DHT11 )
//declaração
void dht11_wrapper();

// Instacia da Biblioteca DHT11
idDHT11 DHT11(pinoDHT11,numeroInterruptorDHT11,dht11_wrapper);

   
                                                      
void setup(void)                   // setup função que é iniciada quando o arduino é ligado (Executa 1 vez)
{

//Inicia a Serial 
Serial.begin(9600);  

                                  
Serial.println("Iniciando Ethernet.");
Ethernet. begin(hwaddr, ipaddr);                          // inicia a ethernet



}


void loop(void){
 
 
  DHT11.acquire();         //metodo default da biblioteca DHT11 para iniciar a leitura do Sensor
 
  //verifica possiveis erros na leitura do status no laço
  while (DHT11.acquiring())
    ;
  int result = DHT11.getStatus();
  switch (result)
  {
  case IDDHTLIB_OK:
    //Serial.println("OK");
    break;
  case IDDHTLIB_ERROR_CHECKSUM:
    Serial.println("Error\n\r\tChecksum error");
    break;
  case IDDHTLIB_ERROR_TIMEOUT:
    Serial.println("Error\n\r\tTime out error");
    break;
  case IDDHTLIB_ERROR_ACQUIRING:
    Serial.println("Error\n\r\tAcquiring");
    break;
  case IDDHTLIB_ERROR_DELTA:
    Serial.println("Error\n\r\tDelta time to small");
    break;
  case IDDHTLIB_ERROR_NOTSTARTED:
    Serial.println("Error\n\r\tNot started");
    break;
  default:
    Serial.println("Unknown error");
    break;
  }
                             
Serial.println("Estabelecendo conexão com o Servidor.");

 
//Tenta estabelecer a conexão senão envia o erro client.connect(ip do servidor, porta do servidor)
if(client.connect(serverip, serverport)){  
//Envia a URL + os parametros para o servidor
Serial.println("Enviado dados para o Servidor: ");     
client.print("GET /ArduinoWeb/insereTemperaturaUmidade.jsp?temperatura=");            //Envia a url + o parametro para o Servidor Apache TomCat atraves da pagina jsp insereTemperaturaUmidade.jsp que aguarda os parametros temperatura e umidade
Serial.print("GET /ArduinoWeb/insereTemperaturaUmidade.jsp?temperatura=");           
client.print(DHT11.getCelsius(), 2);                                          // Envia o dado de temperatura lido do Sensor naquele momento
Serial.print(DHT11.getCelsius(), 2);
client.print("&umidade=");           
Serial.print("&umidade=");           
client.print(DHT11.getHumidity(), 2);   //Envia o dado de umidade lido do Sensor naquele momento
Serial.print(DHT11.getHumidity(), 2);

client.println(" HTTP/1.1");                  //script padrão para o protocolo HTTP
Serial.println(" HTTP/1.1");                  //
client.println("Host: www.arduinoHuno.com");    //
Serial.println("Host: www.arduinoHuno.com");    //
client.println("User-Agent: Arduino");        //
Serial.println("User-Agent: Arduino");        //
client.println("Accept: text/html");          //
Serial.println("Accept: text/html");          //

client.println();                             //
Serial.println();

}else{
  //Se a Conexão Falhar envia a informação de Erro para Serial
  client.println("Erro ao Estabelecer Conexão");
}




if(client.connected() && client.available()) {        // Quando a conexão é feita e está disponivel:
  char c = client.read();                                   // Le a reposta do Servidor e imprime na tela
  Serial.print(c);                                        
}                                                        
  Serial.println();                                        
  client.stop();   //  termina a conexao

delay(15000);  //delay de 15 segundos para recomeçar o loop


}


//metodo padrao para a Biblioteca DHT11
void dht11_wrapper() {
  DHT11.isrCallback();
}




Note que no código há parte escritas em vermelho, neste caso é que possivelmente pode ser diferente do meu caso, vai depender das configurações da sua maquina, e do seu Servidor, posteriormente irei mostrar como verificar as configurações.

Segue aqui os links que usei como referência para a Conexão Ethernet
http://arduino.cc/en/Tutorial/WebClient
https://www.jfkreuter.com/?p=9 


3º Passo (Banco de dados)



Agora vai criar o banco de dados para receber os dados do arduino.

No meu caso uso GUI MySQL Query Browser para gerenciar os dados no banco, está aplicação é opcional.

Usei como:
  User: root
  Password: root

Crie um Schema com o nome Arduino.




Faça o Schema arduino default.

Agora crie a seguinte tabela dentro dele:

CREATE TABLE  `arduino`.`tabelasensor` (
  `hora` varchar(30) NOT NULL,
  `temperatura` decimal(4,2) NOT NULL,
  `umidade` varchar(8) NOT NULL,
  PRIMARY KEY (`hora`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;







4º Passo (Web Server)


Abra o NetBeans (ou Eclipse) e crie um projeto Java Web com o nome ArduinoWeb.

Importe a biblioteca do MySQL para o projeto.

Se quiser criar algum pacote para colocar as classe, sinta-se a vontade.
Crie a seguinte classe para conexão com o banco de dados:




import java.sql.*;



public class DAO{
   
   
    private Connection connection;
    private Statement  statement;
    private String username;
    private String password;
    private String url;
    private String driver;
    public void setUsername( String username){
        this.username = username;
    }
    public String getUsername(){
        return this.username;
    } 
       
        public void setPassword( String password){
          this.password = password;
      }
      public String getPassword(){
          return this.password;
      }
        public void setUrl( String url){
          this.url = url;
      }
      public String getUrl(){
          return this.url;
      }
       
        public void setDriver( String driver){
          this.driver = driver;
      }
      public String getDriver(){
          return this.driver;
      }
        public Connection getConnection() {
        return this.connection;
    }
    public Statement getStatement(){
        return this.statement;
    }
       
        public void Banco(){
        try {
           
             setDriver("com.mysql.jdbc.Driver");       
             setUrl("jdbc:mysql://localhost/");       
             setUsername("root");       
             setPassword("root");  
 
               
           
            Class.forName( getDriver() );
        }
        catch( Exception error) {
            //System.out.println( "Database Contrutor Default(...)");   
        }

    }
       
        public void open() {
      try {
         
          connection = DriverManager.getConnection( getUrl(),getUsername(),getPassword() );
          statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE) ;
          //statement = connection.createStatement() ;
            } catch(Exception error ){           
 
        }
        }
       
        public void close() {
        try {
            connection.close() ;           
        } catch(Exception error ){           
            //System.out.println( "close" );   
        }
       }

        public ResultSet executeQuery(String sql){
        ResultSet rs=null;
        try {
                  rs = statement.executeQuery( sql );
        } catch(Exception error ){           
            //System.out.println( "executeQuery : ");   
        }
        return rs;               
    }
       
        public int executeUpdate( String sql ) throws Exception{
            int result=0;
          try {
              result = statement.executeUpdate( sql );
          } catch(Exception error ){           
            System.out.println( "executeUpdate : ");   
        }
        return result;
      }
    
}


Notem que o usuario e senha deixei em vermelho, pois pode ser alterado conforme a configuração feita na sua maquina.

Agora vamos criar a JSP responsável por inserir os dados.

insereTemperaturaUmidade.jsp


 <%-@page import="java.text.SimpleDateFormat"-%>
<%-@page import="java.util.Date"-%>
 <%-@page contentType="text/html" pageEncoding="UTF-8"-%>

<%-
//Instacia a classe responsavel pelo banco
banco.DAO dao =new banco.DAO();

           //Armazena a Data de hoje em String
           Date data = new Date(System.currentTimeMillis());   
           //SimpleDateFormat formatarDate = new SimpleDateFormat("yyyy-MM-dd");  
           SimpleDateFormat formatarDate = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss  ");  
           String strData = formatarDate.format(data);

      //abre o banco e envia para o driver para a conexão
      dao.Banco(); 
      dao.open();

try{     
             //Query para Inserção no Banco de Dados e os parametros recebidos via GET
             String sql ="Insert into arduino.TabelaSensor(hora, temperatura, umidade) values('"+strData+"',"+request.getParameter("temperatura")+",'"+request.getParameter("umidade")+"')"; 

            //executa a query, note que uso o metodo executeUpdate() que pode ser usado para Inserir, Update ou Excluir
           //retorna um inteiro 1 caso a transição seja realizada com sucesso ou 0 caso haja algum erro            
            int reg = dao.executeUpdate(sql);
            if(reg != 0) {
                  out.print("Dados Incluido com Sucesso!");  
            //fecha a conexão
                  dao.close();
           }else{
               out.print("Erro ao Incluir Usuario");
               //fecha a conexão
               dao.close();
           }
}catch(Exception ex){
    out.print(ex);
}
-%>

E a JSP que exibe os dados na tela.

listarTemperaturaUmidade.jsp


 
 
 <%-@page contentType="text/html" pageEncoding="UTF-8"-%>
<%-@ page import ="java.sql.*" -%>

<%-
    String usuario = "root";
    String senha  = "root";
    String driver ="com.mysql.jdbc.Driver";      
    String url ="jdbc:mysql://localhost/arduino";
        Connection conexao;
        Statement statement;
        ResultSet resultSet;

      
        try{
            Class.forName(driver);
            conexao = DriverManager.getConnection(url, usuario, senha);
            statement  = conexao.createStatement();
          
             resultSet = statement.executeQuery("Select * From tabelasensor ORDER BY hora DESC LIMIT 10");

            while(resultSet.next()){  
-%>
           

           <-body -="" bgcolor="black">>
                <-cente-r>
          
                  <-table -="" border="1"> 
                <-tr-><-td->
               <-font -="" size="10">
            <-font -="" color="#0000FF">    Data :


            <-font -="" color="#FFFFFF"> <% out.println(resultSet.getString(1));  %> <- fon-t=""> <-br->
            <-font -="" color="#0000FF"> Temperatura Celsius : <- fon-t="">
            <-font -="" color="#FFFFFF"> <% out.println(resultSet.getString(2)); %> <- fon-t=""> <-br->
            <-font -="" color="#0000FF"> Umidade % :
            <-font -="" color="#FFFFFF"> <% out.println(resultSet.getString(3)); %>
                 
                 <- font-="">
                <- td-=""> <- tr-=""> 
                <- table-="">
       
               <- center-="">

               <-br-> <-br->
             
               <- body-=""><%-
            }    
        }catch(ClassNotFoundException exDriver){
            out.print("Erro Driver : " +exDriver);
        }catch (SQLException ex){
            out.print("Erro  : " +ex);
        } 
-%>


Percebam em vermelho que fiz a conexão com o Banco de dados direto na JSP é uma opção interessante de conhecermos, mas não é recomendada para aplicação onde segurança é um fator importante por isso é recomendado fazer as conexão na Classe. Mais fica a dica para aprendizado.

Observação : Remova os traços "-" entre as Tags HTML e JSP após copiar o código.

  

5º Passo (Configuração do Servidor)



 Agora temos que checar as configurações do servidor antes de colocar para funcionar.

Abra o CMD do windows (ou se estiver usando Linux abra o Console)

E digite
Windows : ipconfig

Linux: ifconfig


 Aparecerá suas configurações de IP e gateway.






No meu caso o IP do meu servidor é 192.168.0.183.


Precisamos agora da porta que o Tomcat está utilizado,  para isso execute a aplicação Java.

O Navegador abrirá.

Cheque a porta usada depois da palavra localhost:, no meu caso é usado a 8084



 6º Passo (Configuração finais)



Use os dados do 5º Passo no arduino.

Precisará alterar os seguintes dados no código arduino

_ IP que o arduino irá receber, conforme o seu Gateway
 uint8_t ipaddr[4] = {192, 168, 0, 177};    // Endereço de IP do arduino (vai depender do seu gateway)
 


_ O IP do Servidor, é o mesmo que foi checado no Console do PC
IPAddress serverip(192, 168, 0, 183);                   //Endereço de IP do Servidor


_ A porta utilizada pelo TomCat ou Glassfish
int serverport = 8084;     // a porta do Tomcat/Glassfish que esta sendo usada, no meu caso uso 8084 
O TomCat geralmente usa a 8080 até a 8084.

 _ A url (caso haja a necessidade)
client.print("GET /ArduinoWeb/insereTemperaturaUmidade.jsp");            //Envia a url


Após as alterações feitas faça o Upload para o arduino.


Sua Aplicação estará pronta para iniciar.



Observações 

O projeto é apenas didático com o mas pode ser utilizado para monitoramento específicos, inclusive utilizando outros tipos de Sensores.

Isto mostra a ampla utilização possivel para o arduino.

Obrigado, espero ter ajudado, em breve estarei publicando mais artigos.







 

        








2 comentários: