Buenas este es el primer tutorial enlazado a mis segundo blog CursoAndroidStudio.
Este tutorial consiste conectar a través de una conexión bluetooth tu dispositivo Android con el Arduino.
Vamos a enviar y recibir información.
Desde el celular Android, vamos a tener dos botones. ON OFF que van encender o apagar respectivamente
Desde el Arduino vamos a enviar 1, 2,3, 4. Ahora utilizamos estos numeros pero podría ser cualquier tipo de información como la temperatura y la humedad de un DHT11
Todos los demás botones es puramente demostrativo que otras funcionalidades se le pueden agregar.
Un dato importante si usamos el hc06 en el ARDUINO UNO y queremos subir el programa, debemos desconectar el HC06 porque utiliza el mismo puerto serie, que de comunicación. O sea, el puerto usb computadora a arduino es el mismo que del arduino al hc06
Pero si usamos el ARDUINO MEGA, ya tiene varios puertos TX0 RX0, TX1 RX1, TX2 RX2, TX3 RX3.
Entonces lo que hacemos dejamos el puerto 0 (TX0 y RX0) para la comunicación en serie y usamos el TX1 y RX1 para estas conectando y desconectando el VCC del HC06 (agregando si no hacemos esto podrías quemar el arduino o nuestra pc)
Para poder solucionarlo
MultiSerialMega
Vamos a hacer dos declaraciones
Serial.begin(9600);
Serial1.begin(9600);
y cambiaremos todos los Serial
if (Serial.available() > 0)
{
inbyte = Serial.read();
por Seria1.if (Serial1.available() > 0)
{
inbyte = Serial1.read();
etc....Pero para nuestro ejemplo trabajeremos el ARDUINO UNO, y como tiene un solo puerto habrá que desconectarlo el VCC del HC06 para subir el programa, luego de esto le volvemos a dar alimentación al VCC para poder enviar y recibir información
Fuentes: wingoodharry arduino
Configurar HC06
Comencemos con arduino
//#include "DHT.h"
//#define DHTPIN 7
//#define DHTTYPE DHT11
//DHT dht(DHTPIN, DHTTYPE);
int led = 13; //led Rojo de prueba de conexión
float voltageValue[4] = {0,0,0,0};
char inbyte = 0; //Char para leer el led
void setup() {
// initialise serial communications at 9600 bps:
Serial.begin(9600);
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
//dht.begin();
}
void loop() {
getVoltageValue();
//when serial values have been received this will be true
if (Serial.available() > 0)
{
inbyte = Serial.read();
Serial.println(inbyte);
if (inbyte == '2')
{
digitalWrite(led, LOW); //LED off
voltageValue[0] = 0;
}
if (inbyte == '1')
{
digitalWrite(led, HIGH); //LED on
voltageValue[0] = 1;
}
}
sendAndroidValues();
delay(2000);
}
void getVoltageValue()
{
voltageValue[0] = 1; //led
voltageValue[1] = 2;
voltageValue[2] = 3;
voltageValue[3] = 4;
}
//enviar los valores por el dipositivo android por el modulo Bluetooth
void sendAndroidValues()
{
Serial.print('#'); //hay que poner # para el comienzo de los datos, así Android sabe que empieza el String de datos
for(int k=0; k<4; k++)
{
Serial.print(voltageValue[k]);
Serial.print('+'); //separamos los datos con el +, así no es más fácil debuggear la información que enviamos
}
Serial.print('~'); //con esto damos a conocer la finalización del String de datos
Serial.println();
delay(10); //agregamos este delay para eliminar tramisiones faltantes
}
Ahora la conexión.
Nota: En código anterior no declaramos el TX y RX (recibir e enviar información) porque vamos a usar D0 y D1. En caso contrario deberíamos declararlo como en el siguiente ejemplo (ver)
SoftwareSerial BT(10,11); //10 RX, 11 TX.
- TXD: Transmisión de datos.
- RXD: Recepción de datos a un voltaje de 3,3V.
Muestro dos opciones. Ambas funcionan.
Lo más importante, cual es muy fácil de equivocarse si uno trabajo apurado, rápido.
Es que
- el RXD hc06 va con el TX0 del arduino
- el TXD hc06 va con el RX0 del arduino
como muestro en las imágenes
Fotos reales
Y sin mas preámbulos a los que nos interesa el código de Android
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tatoado.ramabluewingood" > <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".DeviceListActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".MainActivity"></activity> </application> </manifest>
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp" android:padding="5dp"> </TextView>
<Button
android:id="@+id/buttonOn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LED ON" />
<Button
android:id="@+id/buttonOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LED OFF />
<TextView
android:id="@+id/sensorView0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/sensorView1
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/sensorView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/sensorView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
device_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView android:id="@+id/title_paired_devices"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Seleccione un dispositivo btSerial "
android:visibility="gone"
android:background="#666"
android:textColor="#fff"
android:paddingLeft="5dp"
/>
<ListView android:id="@+id/paired_devices"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stackFromBottom="false"
android:layout_weight="1"
/>
<TextView
android:id="@+id/connecting"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/infoText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Si no hay dispositivos en la lista, por favor enlaza tu dispositivo en la configuración de Android"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_margin="5dp"
android:textSize="18dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
</LinearLayout>
</LinearLayout>
MainActivity.java
package com.tatoado.ramabluewingood;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
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.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
Button btnOn, btnOff;
TextView txtArduino, txtString, txtStringLength, sensorView0, sensorView1, sensorView2, sensorView3;
TextView txtSendorLDR;
Handler bluetoothIn;
final int handlerState = 0; //used to identify handler message
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private StringBuilder recDataString = new StringBuilder();
private ConnectedThread mConnectedThread;
// SPP UUID service - this should work for most devices
private static final UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// String for MAC address
private static String address = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Link the buttons and textViews to respective views
btnOn = (Button) findViewById(R.id.buttonOn);
btnOff = (Button) findViewById(R.id.buttonOff);
txtString = (TextView) findViewById(R.id.txtString);
txtStringLength = (TextView) findViewById(R.id.testView1);
sensorView0 = (TextView) findViewById(R.id.sensorView0);
sensorView1 = (TextView) findViewById(R.id.sensorView1);
sensorView2 = (TextView) findViewById(R.id.sensorView2);
sensorView3 = (TextView) findViewById(R.id.sensorView3);
txtSendorLDR = (TextView) findViewById(R.id.tv_sendorldr);
bluetoothIn = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) { //if message is what we want
String readMessage = (String) msg.obj; // msg.arg1 = bytes from connect thread
recDataString.append(readMessage); //keep appending to string until ~
int endOfLineIndex = recDataString.indexOf("~"); // determine the end-of-line
if (endOfLineIndex > 0) { // make sure there data before ~
String dataInPrint = recDataString.substring(0, endOfLineIndex); // extract string
txtString.setText("Datos recibidos = " + dataInPrint);
int dataLength = dataInPrint.length(); //get length of data received
txtStringLength.setText("Tamaño del String = " + String.valueOf(dataLength));
if (recDataString.charAt(0) == '#') //if it starts with # we know it is what we are looking for
{
String sensor0 = recDataString.substring(1, 5); //get sensor value from string between indices 1-5
String sensor1 = recDataString.substring(6, 10); //same again...
String sensor2 = recDataString.substring(11, 15);
String sensor3 = recDataString.substring(16, 20);
if(sensor0.equals("1.00"))
sensorView0.setText("Encendido"); //update the textviews with sensor values
else
sensorView0.setText("Apagado"); //update the textviews with sensor values
sensorView1.setText(sensor1);
sensorView2.setText(sensor2);
sensorView3.setText(sensor3);
//sensorView3.setText(" Sensor 3 Voltage = " + sensor3 + "V");
}
recDataString.delete(0, recDataString.length()); //clear all string data
// strIncom =" ";
dataInPrint = " ";
}
}
}
};
btAdapter = BluetoothAdapter.getDefaultAdapter(); // get Bluetooth adapter
checkBTState();
// Set up onClick listeners for buttons to send 1 or 0 to turn on/off LED
btnOff.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mConnectedThread.write("2"); // Send "0" via Bluetooth
Toast.makeText(getBaseContext(), "Apagar el LED", Toast.LENGTH_SHORT).show();
}
});
btnOn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mConnectedThread.write("1"); // Send "1" via Bluetooth
Toast.makeText(getBaseContext(), "Encender el LED", Toast.LENGTH_SHORT).show();
}
});
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
//creates secure outgoing connecetion with BT device using UUID
}
@Override
public void onResume() {
super.onResume();
//Get MAC address from DeviceListActivity via intent
Intent intent = getIntent();
//Get the MAC address from the DeviceListActivty via EXTRA
address = intent.getStringExtra(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
//create device and set the MAC address
//Log.i("ramiro", "adress : " + address);
BluetoothDevice device = btAdapter.getRemoteDevice(address);
try {
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
Toast.makeText(getBaseContext(), "La creacción del Socket fallo", Toast.LENGTH_LONG).show();
}
// Establish the Bluetooth socket connection.
try
{
btSocket.connect();
} catch (IOException e) {
try
{
btSocket.close();
} catch (IOException e2)
{
//insert code to deal with this
}
}
mConnectedThread = new ConnectedThread(btSocket);
mConnectedThread.start();
//I send a character when resuming.beginning transmission to check device is connected
//If it is not an exception will be thrown in the write method and finish() will be called
mConnectedThread.write("x");
}
@Override
public void onPause()
{
super.onPause();
try
{
//Don't leave Bluetooth sockets open when leaving activity
btSocket.close();
} catch (IOException e2) {
//insert code to deal with this
}
}
//Checks that the Android device Bluetooth is available and prompts to be turned on if off
private void checkBTState() {
if(btAdapter==null) {
Toast.makeText(getBaseContext(), "El dispositivo no soporta bluetooth", Toast.LENGTH_LONG).show();
} else {
if (btAdapter.isEnabled()) {
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}
//create new class for connect thread
private class ConnectedThread extends Thread {
private final InputStream mmInStream;
private final OutputStream mmOutStream;
//creation of the connect thread
public ConnectedThread(BluetoothSocket socket) {
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
//Create I/O streams for connection
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[256];
int bytes;
// Keep looping to listen for received messages
while (true) {
try {
bytes = mmInStream.read(buffer); //read bytes from input buffer
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity via handler
bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
break;
}
}
}
//write method
public void write(String input) {
byte[] msgBuffer = input.getBytes(); //converts entered String into bytes
try {
mmOutStream.write(msgBuffer); //write bytes over BT connection via outstream
} catch (IOException e) {
//if you cannot write, close the application
Toast.makeText(getBaseContext(), "La Conexión fallo", Toast.LENGTH_LONG).show();
finish();
}
}
}
}
DeviceListActivity.java
package com.tatoado.ramabluewingood;
import java.util.Set;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class DeviceListActivity extends Activity {
// Debugging for LOGCAT
private static final String TAG = "DeviceListActivity";
private static final boolean D = true;
// declare button for launching website and textview for connection status
Button tlbutton;
TextView textView1;
// EXTRA string to send on to mainactivity
public static String EXTRA_DEVICE_ADDRESS = "device_address";
// Member fields
private BluetoothAdapter mBtAdapter;
private ArrayAdapter mPairedDevicesArrayAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.device_list);
}
@Override
public void onResume()
{
super.onResume();
//***************
checkBTState();
textView1 = (TextView) findViewById(R.id.connecting);
textView1.setTextSize(40);
textView1.setText(" ");
// Initialize array adapter for paired devices
mPairedDevicesArrayAdapter = new ArrayAdapter(this, R.layout.device_name);
// Find and set up the ListView for paired devices
ListView pairedListView = (ListView) findViewById(R.id.paired_devices);
pairedListView.setAdapter(mPairedDevicesArrayAdapter);
pairedListView.setOnItemClickListener(mDeviceClickListener);
// Get the local Bluetooth adapter
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
// Get a set of currently paired devices and append to 'pairedDevices'
Set pairedDevices = mBtAdapter.getBondedDevices();
// Add previosuly paired devices to the array
if (pairedDevices.size() > 0) {
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);//make title viewable
for (BluetoothDevice device : pairedDevices) {
mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
} else {
String noDevices = "Ningun dispositivo pudo ser emparejado";
mPairedDevicesArrayAdapter.add(noDevices);
}
}
// Set up on-click listener for the list (nicked this - unsure)
private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
public void onItemClick(AdapterView av, View v, int arg2, long arg3) {
textView1.setText("Conectando...");
// Get the device MAC address, which is the last 17 chars in the View
String info = ((TextView) v).getText().toString();
String address = info.substring(info.length() - 17);
// Make an intent to start next activity while taking an extra which is the MAC address.
Intent i = new Intent(DeviceListActivity.this, MainActivity.class);
i.putExtra(EXTRA_DEVICE_ADDRESS, address);
startActivity(i);
}
};
private void checkBTState() {
// Check device has Bluetooth and that it is turned on
mBtAdapter=BluetoothAdapter.getDefaultAdapter(); // CHECK THIS OUT THAT IT WORKS!!!
if(mBtAdapter==null) {
Toast.makeText(getBaseContext(), "El dispositivo no soporta Bluetooth", Toast.LENGTH_SHORT).show();
} else {
if (mBtAdapter.isEnabled()) {
Log.d(TAG, "...Bluetooth Activado...");
} else {
//Prompt user to turn on Bluetooth
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}
}
HOla me gustaría que lo hiciera con arduino uno + blouttton + sensor de humedad + android y que me muestre la humedad a cuanto va a la medida que valla tocando mas el agua y que envié mensaje indicando el numero de humedad cada 5 minutos.. mi correo es abirca93@hotmail.com
ResponderEliminarhola una duda el programa que usas para programar android es eclipse o android estudio
ResponderEliminarandroid studio
EliminarHola, excelente aporte, mil gracias, pero tengo una duda, las resistencias de que capasidad son cada una ?
ResponderEliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarHola,
ResponderEliminarGracias por la recomendación. En el caso del Arduino Mega, si conectamos al Serial1 y cambiamos todos los Serial.print a Serial1.print, puedo ver en terminal de mi Android toda la información, pero ya no la puedo ver en la PC a través del monitor serial. ¿Tendré que poner ambas instrucciones? Tanto ¿Serial.print, como Serial1 print? Anteriormente conectaba como comentas todo a TX0 y RX0 y con eso podía ver todo tando en Android como en PC, pero me recomendaron cambiarlo. Gracias.