quinta-feira, 28 de novembro de 2013

Automação Arduino +App Android Java + Bluetooth por Comando de Voz



Aqui vou explicar um pouco sobre o Projeto que fiz de automação com arduino.


Requisitos de Software

_ IDE arduino.
_ Eclipse com Android SDK Manager Configurado para Desenvolvimento.
_ Java JDK a partir da versão 6

Requisitos de Hardware

_ Arduino Uno, Duemilenove ou Mega
_ Bluetooth Shield
_ Relê +-5 volts
_ 1 Transitor PNP ou NPN
_1 Smartphone ou Tablet Android
_ 1 Adaptador 110v/220v
_ 1 Lâmpada ou outro eletrodoméstico de baixa corrente. 
_ 1 buzzer
_ 1 resistor de 100 ohms (vai depender do tipo de buzzer que estiver usando)

Segue abaixo o esquema do Projeto :




 Descrição:

_ O buzzer foi ligado no pino 13 e ground (observação o meu esquema ficou invertido o com o codigo o buzzer está no 9 e o transistor no 13)

O circuito da Lampada foi ligado da seguinte forma.

Vamos começar pelo

 Transistor

  A base foi ligada com o pino 9 do arduino.
     O ground foi ligado ao Emissor do Transitor (TIP 122)
     E o Coletor foi ligado a uma ao pino de Ativação do Relê



O Relê


No relê temos o coletor do transistor conectado ao pino de ativação, conforme dito acima.
E no outro pino de ativação foi ligado o 5 volts do arduino.
E os pinos que fazem a passagem e interrupção do corrente elétrica de 110 volts, liguei a uma fase entre a tomada e o adaptador.
E a outra fase da tensão de 110 volts é ligada diretamente no adaptador, ao qual é ligada a lâmpada.


E porque precisamos de um transistor e não conectamos o relê direto ao pino do arduino?

É simples, o pino do arduino suporta no máximo 40 mA em cada pino e o relê consomeaproximadamente 40 mA, se colocarmos o relê direto estaríamos "Forçando" o arduino, correndo um grande risco de danifica-ló posteriormente.

Já os pinos de energia do arduino suportam até 200 mA, ou seja, ele suporta com folga o nosso relê. 



O Bluetooth


O Bluetooth deve ser ligado ao 5volts e GND do arduino.
E os pinos de dados devem ser ligados da seguinte forma

_ O Tx do Bluetooth no Rx do Arduino.
_ O Rx do Bluetooth no Tx do Arduino.

O seja o receptor no emissor de dados e vice-versa, um exemplo que pode ajudar a entender seria o telefone, se alguém fala o outro escuta pelo fone e vice-versa.

Obs: Não conecte o Rx e o Tx ainda, o do bluetooth no arduino.
O arduino usará essas 2 interfaces para Upload do programa.





Arduino


Agora vamos carregar o código para o arduino.

Abra o IDE do arduino e copie o seguinte código.



#define WHOLE 1
#define HALF 0.5
#define QUARTER 0.25
#define EIGHTH 0.125
#define SIXTEENTH 0.0625



//constantes e variaveis da canção piratas do caribes
#define NOTA_A3  220
#define NOTA_C4  262
#define NOTA_D4  294
#define NOTA_E4  330
#define NOTA_F4  349
#define NOTA_G4  392
#define NOTA_A4  440
#define NOTA_C5  523
#define NOTA_D5  587
#define NOTA_E5  659
#define NOTA_F5  698
#define NOTA_G5  784
#define NOTA_A5  880

#define NOTA_AS4 466
#define NOTA_CS4 277
#define NOTA_AS5 932
#define NOTA_CS5 554


int tunePirata[] = {NOTA_A3, NOTA_C4, NOTA_D4, NOTA_D4, NOTA_D4, NOTA_E4,
              NOTA_F4, NOTA_F4, NOTA_F4, NOTA_G4, NOTA_E4, NOTA_E4,
              NOTA_D4, NOTA_C4, NOTA_D4, NOTA_A3, NOTA_C4, NOTA_D4,
              NOTA_D4, NOTA_D4, NOTA_E4, NOTA_F4, NOTA_F4, NOTA_F4,
              NOTA_G4, NOTA_E4, NOTA_E4, NOTA_D4, NOTA_C4, NOTA_D4,
              NOTA_A3, NOTA_C4, NOTA_D4, NOTA_D4, NOTA_D4, NOTA_F4,
              NOTA_G4, NOTA_G4, NOTA_G4, NOTA_A4, NOTA_AS4, NOTA_AS4,
              NOTA_A4, NOTA_G4, NOTA_A4, NOTA_D4, NOTA_D4, NOTA_E4,
              NOTA_F4, NOTA_F4, NOTA_G4, NOTA_A4, NOTA_D4, NOTA_D4,
              NOTA_F4, NOTA_E4, NOTA_D4, NOTA_CS4, NOTA_D4, NOTA_A4,
              NOTA_C5, NOTA_D5, NOTA_D5, NOTA_D5, NOTA_E5, NOTA_F5,
              NOTA_F5, NOTA_F5, NOTA_G5, NOTA_E5, NOTA_E5, NOTA_D5,
              NOTA_C5, NOTA_D5, NOTA_A4, NOTA_C5, NOTA_D5, NOTA_D5,
              NOTA_D5, NOTA_E5, NOTA_F5, NOTA_F5, NOTA_F5, NOTA_G5,
              NOTA_E5, NOTA_E5, NOTA_D5, NOTA_C5, NOTA_D5, NOTA_A4,
              NOTA_C5, NOTA_D5, NOTA_D5, NOTA_D5, NOTA_F5, NOTA_G5,
              NOTA_G5, NOTA_G5, NOTA_A5, NOTA_AS5, NOTA_AS5, NOTA_A5,
              NOTA_G5, NOTA_A5, NOTA_D5, NOTA_D5, NOTA_E5, NOTA_F5,
              NOTA_F5, NOTA_G5, NOTA_A5, NOTA_D5, NOTA_D5, NOTA_F5,
              NOTA_E5, NOTA_E5, NOTA_D5, NOTA_CS5, NOTA_D5};
             


  int lengthPirata;
//constantes e variaveis da canção piratas do caribes-------------------



// String onde é guardada as msgs recebidas
char c= ' ';

int pinoLed =13;



int index =0;


void setup() {

  pinMode(pinoLed,OUTPUT);
 

  pinMode(9, OUTPUT);
  lengthPirata = sizeof(tunePirata) / sizeof(tunePirata[0]);
  Serial.begin(9600);

}


void loop() {
 
  if (Serial.available() > 0){ 
   
     c = Serial.read();

   if(c =='1'){
   
     digitalWrite(pinoLed, HIGH);
    
   }else if(c =='0'){
        
      digitalWrite(pinoLed, LOW);
  
   }
  
    if(c =='3'){
       tocarMarioBros();
    }
   

    if(c =='5'){
       pirata();
    }
     
     

    delay(10);
   

    }
}
      
       //MUSICA DE MARIO BROS
     void tocarMarioBros(){
      
      

//NOTA 01
noTone(9);
tone(9, 660, 100);
delay(150);

//NOTA 02
noTone(9);
tone(9, 660, 100);
delay(150);

//NOTA 03
noTone(9);
tone(9, 660, 100);
delay(300);

//NOTA 04
noTone(9);
tone(9, 660, 100);
delay(300);

//NOTA 05
noTone(9);
tone(9, 660, 100);
delay(100);

//NOTA 06
noTone(9);
tone(9, 770, 100);
delay(300);

//NOTA 07
noTone(9);
tone(9, 380, 100);
delay(550);

//NOTA 08
noTone(9);
tone(9, 510, 100);
delay(574);

//NOTA 09
noTone(9);
tone(9, 380, 100);
delay(450);

//NOTA 10
noTone(9);
tone(9, 320, 100);
delay(400);

//NOTA 11
noTone(9);
tone(9, 440, 100);
delay(500);

//NOTA 12
noTone(9);
tone(9, 480, 80);
delay(300);

//NOTA 13
noTone(9);
tone(9, 450, 100);
delay(330);

//NOTA 14
noTone(9);
tone(9, 430, 100);
delay(150);

//NOTA 15
noTone(9);
tone(9, 380, 100);
delay(300);

//NOTA 16
noTone(9);
tone(9, 660, 80);
delay(200);
//”””””””””””””’
//NOTA 17
noTone(9);
tone(9, 760, 50);
delay(200);
//”””””””””””””’
//NOTA 18
noTone(9);
tone(9, 860, 100);
delay(150);

//NOTA 19
noTone(9);
tone(9, 700, 80);
delay(300);

//NOTA 20
noTone(9);
tone(9, 760, 50);
delay(150);

//NOTA 21
noTone(9);
tone(9, 660, 80);
delay(350);

//NOTA 22
noTone(9);
tone(9, 520, 80);
delay(300);

//NOTA 23
noTone(9);
tone(9, 580, 80);
delay(150);

//NOTA 24
noTone(9);
tone(9, 480, 80);
delay(150);

//NOTA 25
noTone(9);
tone(9, 510, 100);
delay(350);

//NOTA 26
noTone(9);
tone(9, 380, 100);
delay(550);

//NOTA 27
noTone(9);
tone(9, 320, 100);
delay(400);

//NOTA 28
noTone(9);
tone(9, 440, 100);
delay(500);

//NOTA 29
noTone(9);
tone(9, 480, 80);
delay(300);

//NOTA 30
noTone(9);
tone(9, 450, 100);
delay(330);

//NOTA 31
noTone(9);
tone(9, 430, 100);
delay(150);

//NOTA 32
noTone(9);
tone(9, 380, 100);
delay(300);

//NOTA 33
noTone(9);
tone(9, 660, 80);
delay(200);

//NOTA 34
noTone(9);
tone(9,
760, 50);
delay(200);

noTone(9);
tone(9, 860,100);
delay(150);

noTone(9);
tone(9,700,80);
delay(300);

tone(9,760,50);
delay(150);
noTone(9);

tone(9,660,80);
delay(350);
noTone(9);

tone(9,520,80);
delay(300);
noTone(9);

tone(9,580,80);
delay(150);
noTone(9);

tone(9,480,80);
delay(150);
noTone(9);

tone(9,500,100);
delay(500);
noTone(9);

tone(9,760,100);
delay(300);
noTone(9);

tone(9,720,100);
delay(100);
noTone(9);

tone(9,680,100);
delay(150);
noTone(9);

tone(9,620,150);
delay(150);
noTone(9);

tone(9,650,150);
delay(300);
noTone(9);

tone(9,380,100);
delay(300);
noTone(9);

tone(9,430,100);
delay(150);
noTone(9);

tone(9,500,100);
delay(150);
noTone(9);

tone(9,430,100);
delay(300);
noTone(9);

tone(9,500,100);
delay(150);
noTone(9);

delay(100);tone(9,570,100);
delay(220);tone(9,500,100);
delay(300);tone(9,760,100);
delay(100);tone(9,720,100);
delay(150);tone(9,680,100);
delay(150);tone(9,620,150);
delay(300);tone(9,650,200);
delay(300);tone(9,1020,80);
delay(300);tone(9,1020,80);
delay(150);tone(9,1020,80);
delay(300);tone(9,380,100);
delay(300);tone(9,500,100);
delay(300);tone(9,760,100);
delay(100);tone(9,720,100);
delay(150);tone(9,680,100);
delay(150);tone(9,620,150);
delay(300);tone(9,650,150);
delay(300);tone(9,380,100);
delay(150);tone(9,430,100);
delay(150);tone(9,500,100);
delay(300);tone(9,430,100);
delay(150);tone(9,500,100);
delay(100);tone(9,570,100);
delay(220);tone(9,500,100);
delay(300);tone(9,760,100);
delay(100);tone(9,720,100);
delay(150);tone(9,680,100);
delay(150);tone(9,620,150);
delay(300);tone(9,650,200);
delay(300);tone(9,1020,80);
delay(300);tone(9,1020,80);
delay(150);tone(9,1020,80);
delay(300);tone(9,380,100);
delay(300);tone(9,500,100);
delay(300);tone(9,760,100);
delay(100);tone(9,720,100);
delay(150);tone(9,680,100);
delay(150);tone(9,620,150);
delay(300);tone(9,650,150);
delay(300);tone(9,380,100);
delay(150);tone(9,430,100);
delay(150);tone(9,500,100);
delay(300);tone(9,430,100);
delay(150);tone(9,500,100);
delay(100);tone(9,570,100);
delay(420);tone(9,585,100);
delay(550);tone(9,550,100);
delay(420);tone(9,500,100);
delay(360);tone(9,380,100);
delay(300);tone(9,500,100);
delay(300);tone(9,500,100);
delay(150);tone(9,500,100);
delay(300);tone(9,500,60);
delay(150);tone(9,500,80);
delay(300);tone(9,500,60);
delay(350);tone(9,500,80);
delay(150);tone(9,580,80);
delay(350);tone(9,660,80);
delay(150);tone(9,500,80);
delay(300);tone(9,430,80);
delay(150);tone(9,380,80);
delay(600);tone(9,500,60);
delay(150);tone(9,500,80);
delay(300);tone(9,500,60);
delay(350);tone(9,500,80);
delay(150);tone(9,580,80);
delay(150);tone(9,660,80);
delay(450);tone(9,870,80);
delay(324);tone(9,760,80);
delay(600);tone(9,500,60);
delay(150);tone(9,500,80);
delay(300);tone(9,500,60);
delay(350);tone(9,500,80);
delay(150);tone(9,580,80);
delay(350);tone(9,660,80);
delay(150);tone(9,500,80);
delay(300);tone(9,430,80);
delay(150);tone(9,380,80);
delay(600);tone(9,660,100);
delay(150);tone(9,660,100);
delay(300);tone(9,660,100);
delay(300);tone(9,510,100);
delay(100);tone(9,660,100);
delay(300);tone(9,770,100);
delay(450);tone(9,380,100);

delay(2000);
tone(9,440,200);
delay(400);
delay(400);
tone(9,440,400);
delay(400);
delay(400);
delay(10000);

    }
   

   
//toca piratas do caribe (ou pelo menos tento rs)   
      void pirata(){
       
       
                      float durationPirata[] = {HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF,
                                  HALF, HALF, HALF, HALF, WHOLE, HALF, HALF, HALF, HALF, HALF,
                                  HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, WHOLE,
                                  HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF,
                                  HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF,
                                  HALF, HALF, HALF, HALF, HALF, HALF, WHOLE, HALF, HALF, HALF,
                                  HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF,
                                  HALF, HALF, HALF, WHOLE, HALF, HALF, HALF, HALF, HALF, HALF,
                                  HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF,
                                  HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF,
                                  HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF, HALF,
                                  HALF, HALF, HALF, HALF, HALF};
                           
                           
    for (int x=0; x      tone(9, tunePirata[x]);
      delay(550 * durationPirata[x]);
      noTone(9);
    }
      delay(5000);

 }
 


Ufa! ficou grande não é?
resumindo, no Buzzer ele toca a canção de 2 maneiras a primeira é usando um array com as notas e a intensidade fixadas neste array, e é chamado o metodo Tone() que é bastante usado em exemplo de arduino. Na segunda escrevemos nota por nota sem usar array.

O arduino vai aguardar do android apenas 1 caractere, é mais fácil trabalhar com ele desta maneira, pois não teremos que concatenar os dados recebidos, o arduino sempre recebe caractere por caractere, mesmo que receba uma String.

'1','0', '3' ou '5'

1- liga a Lâmpada
0- desliga a Lâmpada 
3- toca a música do Mario Bros
5- toca piratas do Caribe (ou pelo menos tenta)

Ok, a parte do arduino está pronta. Agora poderá conectar o Tx e o Rx do bluetooth no arduino conforme explicação acima.



Vamos para o Android.


Primeiramente abra o Eclipse e crie um novo Projeto Arduino, dê o nome que quiser.
No meu caso usei a versão 2.2 do android, mais se quise usar outra que seja compatível com o seu dispositivo fique avontade.

Vamos primeiramente adicionar as permissões necessária ao nosso Aplicativo Android para podermos usar o Bluetooth e a Internet (Para o Sintetizador de Voz) eu recomendo fazer antes para não esquecer, é muito comum rodar um aplicativo sem as permissão na fase de Desenvolvimento.

Abra o seu AndroidManisfest 


  <?-xml version="1.0" encoding="UTF-8"-?>
<-manifest android:versionName="1.0" android:versionCode="1" package="com.example.androidarduinocomandovoz" xmlns:android="http://schemas.android.com/apk/res/android"-><-uses-sdk android:targetSdkVersion="18" android:minSdkVersion="8"/><uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>         <-uses-permission android:name="android.permission.WRITE_OWNER_DATA"/>  -       <-uses-permission android:name="android.permission.READ_OWNER_DATA"/><uses-permission android:name="android.permission.WAKE_LOCK"/><uses-permission android:name="android.permission.VIBRATE"/><uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>          <-uses-permission android:name="android.permission.BLUETOOTH"> </uses-permission><-application android:theme="@style/AppTheme" android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:allowBackup="true"-><-activity android:name="com.example.androidarduinocomandovoz.Menu" android:label="@string/app_name"-><-intent-filter-><-action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></-intent-filter-></-activity-></-application-></-manifest-> 

 Adicione o texto em azul.As seguintes permissões INTERNET, BLUETOOTH_ADMIN, BLUUETOOTH.    Ok, vamos criar a nossa tela agora. abra um layout xml, na pasta res/layout, no meu caso o meu layout nomeie demenu.xml Vamos cria-ló com o seguinte código  

                                                                                                                                                                           <?-xml version="1.0"-?>
<-RelativeLayout tools:context=".Menu" android:paddingTop="@dimen/activity_vertical_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingBottom="@dimen/activity_vertical_margin" android:layout_height="match_parent" android:layout_width="match_parent" xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android"->
<-Button android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="Sintetizador" android:layout_marginBottom="25dp" android:layout_centerHorizontal="true" android:layout_alignParentBottom="true" android:id="@+id/botaoSintetizador"-/>
<-EditText android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_centerHorizontal="true" android:id="@+id/editText1" android:layout_marginTop="16dp" android:layout_alignParentTop="true" android:ems="10"-/></-RelativeLayout->  


Ok, nosso layout basicamente tem, 1 EditText (Caixa de Texto) e 2 Button (Botão).É possível ver em modo design.     Vamos criar nossa Activity agora que vai controlar nosso layout.  Você poderá usar a Activity (Classe) criada automaticamente pelo Eclispse, o mesmo se aplica ao layout acima.  Copie o código para a Classe Java criada.No meu caso ela chama-seMenu.javapodendo ser alterada conforme necessidade    




import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.UUID;
import android.os.Bundle;
import android.os.Handler;
import android.speech.RecognizerIntent;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.util.Log;


public class Menu extends Activity implements OnClickListener{
  
    //Variavel do Sintetizador de Voz---------------
     private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;
    
    
    
     //Tag para o log d do android
     private static final String TAG = "Thiago";
    
     //Variaveis da Conexao Bluetooth--------------
     private BluetoothAdapter mBluetoothAdapter = null;
     private BluetoothSocket btSocket = null;
     private OutputStream outStream = null;
   
     //endereco de conexao BT a ser pareado do arduino
     private static String address = "20:13:01:24:02:08";
     //meu id do android
     private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");




     //inputStream para armazenar as entradas
     private InputStream inStream = null;
   
     //Thread do Android
     Handler handler = new Handler();
   
     //delimitador fr Bits a serem enviados
     byte delimiter = 10;
   
     boolean stopWorker = false;
   
     //ponteiro para leitura do Buffer
     int readBufferPosition = 0;
   
     //Buffer de Bits
     byte[] readBuffer = new byte[1024];
   
     //boolean para conexão
     boolean conetado =false;
    
    
   
       //Variavel que armazena o dado a ser enviado
       String dadoEnviarSintetizador = "";
     
       //variavel que armazena o dado apos o tratamento (validação)
       String dadoSintetizado ="";
   
     //Componentes Android
        Button botaoConectar;
        Button botaoSintetizador;  
        EditText edit;
  
      
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      
        super.onCreate(savedInstanceState);
        //chama o XML da Activity
        setContentView(R.layout.menu);
      
      
        //cria o Alias para os componentes do XML
        edit = (EditText) findViewById(R.id.editText1);      
        botaoConectar = (Button) findViewById(R.id.botaoConectar);
        botaoSintetizador = (Button) findViewById(R.id.botaoSintetizador);

      
      
        //Implementa On Click Listenner para o botão de conexao
        //por ser mais estavel para esta tarefa de conexão
        botaoConectar.setOnClickListener(this);
      
        //seta o botão Sintetizador como desativado
        //para não tentar enviar os dados antes de conectar
         botaoSintetizador.setEnabled(false);
         edit.setEnabled(false);
      

      
            
            

                try{
                //checa o bluetooth
                CheckBt();
                //inicia a paridade
                BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
                Log.e("Teste", device.toString());

                }catch (Exception e) {
                    // TODO: handle exception
                }
      
           try{
            //Listener do botao do Sintetizador de Voz 
            botaoSintetizador.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    //chama o metodo que é responsavel pela sintetização
                    startVoiceRecognitionActivity();
                  
                  
                }
            });
         
           }catch (Exception e) {
                // TODO: handle exception
           }
         
         
           try{
                //Evento para Enviar o dado via BT pelo edit (Sem Sintetizador)
                  edit.setOnLongClickListener(new View.OnLongClickListener() {
                        public boolean onLongClick(View v) {
                          
                                //Captura o Conteudo do edit
                                String enviaDadoEdit = edit.getText().toString();
                              
                                //envia para o metodo de validação antes de enviar para o proximo dispositivo
                                validaDados(enviaDadoEdit);
                                //envia o dado para o dispositivo Client
                                writeData(dadoEnviarSintetizador);
      
                          
                            return true;
                        }
                    });
                }catch (Exception e) {
                    // TODO: handle exception
                }

      
    }

  
    //Metodos para input de Voz
    //*************************************************
    /**
     * Fire an intent to start the speech recognition activity.
     */
    private void startVoiceRecognitionActivity() {
        try{
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speech recognition demo");
        startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
      
        }catch (Exception e) {
            Toast.makeText(getApplicationContext(), "Bluetooth Desativado ou não Pareado!",
                    Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * Handle the results from the recognition activity.
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) {
            // Fill the list view with the strings the recognizer thought it could have heard
            ArrayList<String> matches = data.getStringArrayListExtra(
                    RecognizerIntent.EXTRA_RESULTS);
          
            dadoEnviarSintetizador =" ";
          
        
            //verifica String Salva no Sintezador de Voz
           for(int index =0; index < matches.size(); index++){

              if(!dadoEnviarSintetizador.equalsIgnoreCase("1") && !dadoEnviarSintetizador.equalsIgnoreCase("0")
                      && !dadoEnviarSintetizador.equalsIgnoreCase("3")  && !dadoEnviarSintetizador.equalsIgnoreCase("4")
                      && !dadoEnviarSintetizador.equalsIgnoreCase("5")){
              
                edit.setText(matches.get(index).toString());
                  validaDados(matches.get(index).toString());
                
              
              }
          
        

           }
        }

        super.onActivityResult(requestCode, resultCode, data);
      
        writeData(dadoEnviarSintetizador);
    
  
  
    }
  
  //Metodos para input de Voz
    //*************************************************
  
  
  
  
  
    //trata os dado para posteriormente enviar para o dispositivo (arduino)
    //o arduino le os dados byte por byte, a maneira mais viavel é tratalo e enviar apenas 1 carater
    public void validaDados(String dadoBruto){
      
        //se a frase falada ou digitada, for algumas dessas abaixo, é gravado a condição na variavel envia
        // dadoEnviarSintetizador que posteriormente é enviado para o arduino
      
        if(dadoBruto.equalsIgnoreCase("Ligar") || dadoBruto.equalsIgnoreCase("Ativar") || dadoBruto.equalsIgnoreCase("Acender")){
           dadoEnviarSintetizador ="1";

     
       }else if(dadoBruto.equalsIgnoreCase("Desligar")|| dadoBruto.equalsIgnoreCase("Desativar") || dadoBruto.equalsIgnoreCase("Apagar")){
           dadoEnviarSintetizador ="0";
        
       }else if(dadoBruto.equalsIgnoreCase("Mario")|| dadoBruto.equalsIgnoreCase("Mario Bross")|| dadoBruto.equalsIgnoreCase("Mario Bros")){
         
           dadoEnviarSintetizador ="3";
     
       }else if(dadoBruto.equalsIgnoreCase("Piratas do Caribe")|| dadoBruto.equalsIgnoreCase("Piratas do Karibe")|| dadoBruto.equalsIgnoreCase("Piratas") || dadoBruto.equalsIgnoreCase("Medo do Escuro")){
         
           dadoEnviarSintetizador ="5";
       }else {
           dadoEnviarSintetizador ="";
       }
      
    }
  
  
 
  
    //metodo do Listenner do botao de conexao bluetooth
    @Override
    public void onClick(View control) {

            switch (control.getId()) {
            case R.id.botaoConectar:
                    try{
                     conetado = Connect();
                   
                     if(conetado){
                         botaoConectar.setEnabled(false);
                         botaoSintetizador.setEnabled(true);
                         edit.setEnabled(true);
                     }else{
                        
                         botaoConectar.setEnabled(true);
                         botaoSintetizador.setEnabled(false);
                         edit.setEnabled(true);
                     }
                    }catch(Exception ex){
                      
                    }
                    break;
            }
    }
  
  
    //Metodos para Conexao Bluetooth----------------------------------------
    //*************************************************
 
    //checa se o BT esta ligado
    private void CheckBt() {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
      

        if (!mBluetoothAdapter.isEnabled()) {
                Toast.makeText(getApplicationContext(), "Bluetooth Desativado !",
                                Toast.LENGTH_SHORT).show();
                mBluetoothAdapter.enable();
        }

        if (mBluetoothAdapter == null) {
                Toast.makeText(getApplicationContext(),
                                "Bluetooth null !", Toast.LENGTH_SHORT)
                                .show();
        }
}
        //metodo de conexão
        public boolean Connect() {
             try{
                Log.d(TAG, address);
                //pega o adress do bluetooth para iniciar a pariedade
                BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
              
                Log.d(TAG, "Connecting to ... " + device);
              
                //cancela a busca apos armazenar no BluetoothDevice
                mBluetoothAdapter.cancelDiscovery();
                try {
                        //envia para o Socket a ID do dispositivo local
                        btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
                        //requisita a conexão
                        btSocket.connect();
                      
                        Log.d(TAG, "Conexão Realizada!.");
                      
                        //chama o metodo que inicia a transferencia dos dados
                        beginListenForData();
              
                } catch (IOException e) {
                        try {
                                //fecha o socket caso ocorra algum erro
                                btSocket.close();
                                return false;
                        } catch (IOException e2) {
                                Log.d(TAG, "Unable to end the connection");
                                return false;
                        }
                      
                 
                }
                return true;
              
             }catch (Exception e) {
                 return false;
            }
              
           
        
        }
      
      
//metodo para escreve no BT
private void writeData(String data) {
        try {
                outStream = btSocket.getOutputStream();
        } catch (IOException e) {
                Log.d(TAG, "Bug BEFORE Sending stuff", e);
        }




        try {
          
                String message = data;
                byte[] msgBuffer = message.getBytes();
                outStream.write(msgBuffer);
        } catch (IOException e) {
                Log.d(TAG, "Bug while sending stuff", e);
        }
}

@Override

//encerra a conexao apos o envio dos dados
//(Não é necessario) mais é padrao do Android
protected void onDestroy() {
    super.onDestroy();

            try {
                    btSocket.close();
            } catch (IOException e) {
            }
}


// inicia a transferencia dos dados
public void beginListenForData()   {
         try {
                        inStream = btSocket.getInputStream();
                } catch (IOException e) {
                }
       
        Thread workerThread = new Thread(new Runnable()
        {
            public void run()
            {              
               while(!Thread.currentThread().isInterrupted() && !stopWorker)
               {
                    try
                    {
                        int bytesAvailable = inStream.available();                      
                        if(bytesAvailable > 0)
                        {
                            byte[] packetBytes = new byte[bytesAvailable];
                            inStream.read(packetBytes);
                            for(int i=0;i<bytesAvailable;i++)
                            {
                                byte b = packetBytes[i];
                                if(b == delimiter)
                                {
                                    byte[] encodedBytes = new byte[readBufferPosition];
                                    System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
                                    final String data = new String(encodedBytes, "US-ASCII");
                                    readBufferPosition = 0;
                                    handler.post(new Runnable()
                                    {
                                        public void run()
                                        {

                                             
                                        }
                                    });
                                }
                                else
                                {
                                    readBuffer[readBufferPosition++] = b;
                                }
                            }
                        }
                    }
                    catch (IOException ex)
                    {
                        stopWorker = true;
                    }
               }
            }
        });

    }
}

 O Projeto está pronto.Salve o Projeto no Eclipse, export o APK e instale no SmartPhone.  Sugiro que antes de abrir o Aplicativo ligue o buetooth e ative o Wireless.  Poderá ocorrer erros dependendo da versão do android se abri-ló se o bluetooth não estiver ativo   O Wireless não é necessário se não for usar o Sintetizador.   



Espero ter ajudado, até mais.

 









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.