Send Arduino data to Android (ultrasonic sensor)

Asked

Viewed 1,963 times

3

I made this code to receive data from an ultrasonic sensor on a cell phone Android. After passing the application to the mobile and the code to the Arduino, it can only connect, but does not show the sensor distance data. Could someone help me solve this problem?

//Activity principal que realiza a conexão e mostra os dados do sensor

package com.example.sensor;

import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;

import com.example.appenthernet.R;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;

@SuppressLint("HandlerLeak")
public class MainActivity extends Activity {
	
	 //Handler é parte da estrutura do sistema Android para gerenciar threads. Um manipulador de objeto recebe mensagens e executa o código para 
	//lidar com as mensagens. Normalmente, você cria um manipulador para um novo tópico, mas você também pode criar um manipulador que está conectado
	//a uma linha existente. Quando você conecta um manipulador para o seu segmento interface do usuário, o código que manipula mensagens é executado 
	//no segmento interface do usuário.
	//Ou seja, é a estrutura que manipula as mensagens recebidas por bluetooth pelo ceular
	Handler bluetoothIn;

	  final int handlerState = 0;        			
	  private BluetoothAdapter btAdapter = null;
	  private BluetoothSocket btSocket = null;
	  private StringBuilder recDataString = new StringBuilder();
	  private OutputStream outStream = null;
	  
	  private static final int SolicitaAtivaçao = 1;
	  
	  private static final int SolicitaConexao = 2;

	  //Entrada das informações para fazer a interação entre o celular e o módulo bluetooth
	  private BluetoothAdapter meuBluetooth = null;
	  
	  // SPP UUID service - isso deve funcionar para a maioria dos dispositivos
	  private static final UUID MEU_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
	  
	  // String para o endereço MAC
	  //quando usa lista de dispositivos, se não colocar igual a null da erro
	  private static String MAC = null;
	
	TextView textView1, textViewMedida, textViewString;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		textView1 = (TextView) findViewById(R.id.textView1);
		textViewMedida = (TextView) findViewById(R.id.textViewMedida);
		textViewString = (TextView) findViewById(R.id.textViewString);
		
		//obtém o adaptador local bluetooth
		meuBluetooth = BluetoothAdapter.getDefaultAdapter();
		
		//Verifica se o didpositivo tem bluetooth
				if(meuBluetooth == null){
					//Se não tiver, a mensagem abaixo será mostrada e o programa será encerrado
					Toast.makeText(getApplicationContext(), "Seu dispositivo não possui bluetooth", Toast.LENGTH_LONG).show();
					finish();
					return;
				}
				
				//Se o bluetooth não estivver ativado, será solicitada a ativação do mesmo 
				//Através do intent, que inicia uma nova ação
				if(!meuBluetooth.isEnabled()){
					Intent solicita = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);//Cria o intent
					startActivityForResult(solicita,SolicitaAtivaçao);//Starta o intent			
				}		
		
		
	    bluetoothIn = new Handler() {
	        public void handleMessage(android.os.Message msg) {
	            if (msg.what == handlerState) {										//se a mensagem é o que queremos,
	            	String readMessage = (String) msg.obj;                                                                // msg.arg1 = bytes de conexão thread
	                recDataString.append(readMessage);      								//Pega os dados doa sensores até a string '~'
	                int endOfLineIndex = recDataString.indexOf("~");                       // que determina o final de linha
	                if (endOfLineIndex > 0) {                                           
	                    String dataInPrint = recDataString.substring(0, endOfLineIndex);    // extrai a string
	                    textViewString.setText("Data Received = " + dataInPrint);           		
	                    int dataLength = dataInPrint.length();							//Pega o tamanho dos dados recebidos
	                    textView1.setText("String Length = " + String.valueOf(dataLength));
	                    
	                    if (recDataString.charAt(0) == '#')								//se ele começa com # sabemos que é o que estamos procurando
	                    {
	                    	String sensor0 = recDataString.substring(1, 5);             //obtem o valor do sensor entre índices 1-5       	        	

	                    	textViewMedida.setText(" Sensor 0 Voltage = " + sensor0 + "cm");	//coloca o valor recebido no textview
	
	                    }
	                    recDataString.delete(0, recDataString.length()); 					//limpa as strings 
	                   // strIncom =" ";
	                    dataInPrint = " ";
	                }            
	            }
	        }
	    };
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);

		switch(requestCode){
		
		case SolicitaAtivaçao:
			if(resultCode ==Activity.RESULT_OK)//Se o bluetooth for ligado, a mensagem abaixo será mostrada
			{                                   //E o progrma continuará sendo executado
				Toast.makeText(getApplicationContext(), "O BLUETOOTH FOI LIGADO!", Toast.LENGTH_LONG).show();
			}else//Se o bluetooth não foi ativado, a mensagem abaixo será mostrada e o programa será fechado
			{
				Toast.makeText(getApplicationContext(), "O BLUETOOTH NÃO FOI LIGADO!", Toast.LENGTH_LONG).show();
				finish();
			}
			break;
		
		case SolicitaConexao:
			if(resultCode==Activity.RESULT_OK){				
				MAC = data.getExtras().getString(ListadeDispositivos.EnderecoMAC);
				
				//Para se ter um bluetoothdevice é necessário uilizar o BluetoothAdapter.getRemoteDevice(string)
				//Que representa um endereço Mac conhecido, que já foi apresentado no início
				BluetoothDevice device = meuBluetooth.getRemoteDevice(MAC);				
				try{
					//A função device.createRfcommSocketToServiceRecord(MEU_UUID) abre m conexão 
					//Entre o dispositivo e o módulo
					btSocket = device.createRfcommSocketToServiceRecord(MEU_UUID);
					//É iniciada a saída d dados do dispositivo
					btSocket.connect();	
					
					//Se der tudo certo na hora da conexão, irá aparecer a tela do controle
					if(btSocket!=null){
					Toast.makeText(getApplicationContext(), "A CONEXÃO FOI BEM SUCEDIDA!", Toast.LENGTH_LONG).show();
					}
				}catch(IOException e){
					Toast.makeText(getApplicationContext(), "ERRO AO FAZER CONEXÃO", Toast.LENGTH_LONG).show();
				}	
				
			}else{
				Toast.makeText(getApplicationContext(), "Falha ao obter o endereço MAC", Toast.LENGTH_LONG).show();
			}
		break;
		}
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.Conectar) {
			
			conectar();
			
			return true;
		}
		if (id ==R.id.Desconectar){
			
			if(btSocket !=null){
			
			desconectar();
			}else{
				Toast.makeText(MainActivity.this, "O módulo bluetooth não está conectado", Toast.LENGTH_LONG).show();
			}
			
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
	
		//Método que faz o envio de dados, ou seja, envia os caracteres	
		public void dadosEnvio (String data){
			 
			try{
				//Permite a saída de dados a partir de um socket
				outStream = btSocket.getOutputStream();
			}catch(IOException e ){}
			String mensagem = data;
			byte[] msgBuffer = mensagem.getBytes();//Array de bytes que armazena a informação da string 
			try{
				//Envia a mensagem para o módulo
				outStream.write(msgBuffer);
			}catch(IOException e ){}
				}
		
	//Definição da função conectar
	public void conectar(){		
		Intent abreLista = new Intent(MainActivity.this,ListadeDispositivos.class);
		startActivityForResult(abreLista, SolicitaConexao);		
	}
	
	//Definição da função desconectar
	public void desconectar(){
		try{
			btSocket.close();//Fecha a conexão
			btSocket = null;//E a conexão volta a ser nula
									
		}catch(IOException e){
			
		}
	}
}

<!-- begin snippet: js hide: false -->
//Programa do arduino

#include <Ultrasonic.h>

//Define os pinos TRIGGER e ECHO do sensor ultrassonico
#define PINO_TRIGGER 13
#define PINO_ECHO 10

//Inicializa o sensor ultrassonico
Ultrasonic sensor(PINO_TRIGGER, PINO_ECHO);

float cmMsec;//variável que irá armazenar os dados do sensor

void setup() {
  Serial.begin(9600);
}

void loop() {

  valores_para_envio();

  long microsec = sensor.timing();// contabiliza o tempo necessário para o sinal ir e voltar

  cmMsec = sensor.convert(microsec, Ultrasonic::CM);//calcula a distância em centímetros

  delay(1000);
}

void valores_para_envio() {

  //indica que a comunicação foi iniciada
  Serial.print("#");
  //Envia o valor medido pelo sensor
  Serial.print(cmMsec);
  //Usado para identificar o fim da trasmissão
  Serial.print('~');
  Serial.println();
  delay(10);

}

//Activity para a lista de dispositivos 

package com.example.sensor;

import java.util.Set;

import android.app.ListActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class ListadeDispositivos extends ListActivity {

    private BluetoothAdapter meuBluetooth;
    static String  EnderecoMAC = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        ArrayAdapter<String> ArrayBluetooth = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);

        //obtem o bluetooth local do dispositivo
        meuBluetooth= BluetoothAdapter.getDefaultAdapter();

        //Pega os dispositivos paredaos 
        Set<BluetoothDevice> dispositivospareados = meuBluetooth.getBondedDevices();

        //Se o tamanho dos dispositivos for maior que zero, serão adicionados os dispositivos na lista
        if(dispositivospareados.size()>0){
            for (BluetoothDevice bluetoothDevice : dispositivospareados) {
                String nome = bluetoothDevice.getName();
                String mac = bluetoothDevice.getAddress();

                ArrayBluetooth.add(nome +"\n"+mac);

            }
        }

        setListAdapter(ArrayBluetooth);     
    }

    //Método de click na lista
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        // TODO Auto-generated method stub
        super.onListItemClick(l, v, position, id);

        //Obtém todos os dados do item que foi clicado
        String InfoGeral = ((TextView)v).getText().toString();

        //Retira o endereço MAC que são os ultimos 17 caracteres da informação
        String mac = InfoGeral.substring(InfoGeral.length()-17);

        Intent retornaMac = new Intent();
        retornaMac.putExtra(EnderecoMAC, mac);

        //Atribui o resultado como OK e fecha a lista
        setResult(RESULT_OK,retornaMac);
        finish();
    }




}
  • If you use the Serial Monitor of the Arduino IDE itself configured with 9600 speed, can you get the data from the Arduino? Another suggestion: There is a program for Android (I can’t remember the name now) that allows you to connect on Bluetooth devices and receive/send data. I’ve tried an Arduino with a Bluetooth adapter this way and it worked. Anyway, what I’m proposing is that you first test the Arduino + Adatapdor Bluetooth on something that you’re sure will work. If all goes well, then you start evaluating your program.

1 answer

1

In fact, as far as I can tell, you’re not reading received data, since you don’t do it anywhere:

InputStream in = bluetoothkSocket.getInputStream();

What you need to do is create another thread that will loop waiting for your sensor uploads in the Arduino, something like this:

// Faça isso a partir do momento que o seu bluetooth socket for diferente de null
    // Que é quando você tem a conexão
    final InputStream in = bluetoothkSocket.getInputStream();

    new Thread(new Runnable() {
        @Override
        public void run() {
            byte[] bytes = new byte[1024];
            int length;
            while (running) {
                try {
                    length = in.read(bytes);
                    // Isso supondo que a mensagem que você envia seja uma string
                    String msg = new String(bytes, 0, length);
                    // Método para atualizar a interface
                    msgReceived(msg);
                } catch (Exception e) {
                    running = false;
                }
            }
        }
    }).start();

Only the Thread UI can update the screen on android:

private void msgReceived(final String msg) {
        // Vai rodar na UI Thread.
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // Faça o que quiser com a msg. Atualizar um textView, por exemplo.
            }
        });
    }

As said, don’t forget that all this needs to be done in another Thread.

As for the part of sending the information on Arduino, if it is being done correctly, I can’t tell you.

Edit:

Remembering that the method in.read(bytes);, It’s blocking, which means he’ll be stuck in this method until an answer comes. According to the Java documentation on the method itself:

This method Blocks until input data is available, end of file is Detected, or an Exception is thrown.

What makes it clearer the importance of using another Thread to wait for the answer.

  • What do you mean another thread? Where would I add it? !!

  • I updated my answer, take a look.

  • Dude, I don’t get it. ?

  • Soon I add this code in your and update here.

  • Right. Thank you very much!!

  • the msgreceived and the running could not understand them. Can you add in my code?

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.