GuiaTrabajoExaula_LedTricolor_BT Android

Anuncio
UNIVERSIDAD DE EL SALVADOR
FACULTAD DE INGENIERIA Y ARQUITECTURA
ESCUELA DE INGENIERIA DE SISTEMAS INFORMATICOS
PROGRAMACION PARA DISPOSITIVOS MOVILES
PDM115 Ciclo I-2014
GUIA DE PRACTICA (EX Aula opcional)
LED RGB controlado por Arduino
desde un dispositivo movil con SO Android 2.2 o superior.
Objetivos
General:
Implementar la comunicación por medio de bluetooth de un circuito implementado con la placa
Arduino y un dispositivo Android 2.2 o mejor.
Específicos:



Conocer las partes más importantes de un módulo bluetooth compatible con
Arduino.
Identificar y utilizar los pines de Arduino dedicados a la transición y recepción de
datos.
Utilizar una aplicativo Android para controlar un led RGB por medio de bluetooth.
Tabla de contenido
Descripción general del proyecto a implementar: .............................................................................. 1
Precondiciones para la efectiva realización de la siguiente guía: ....................................................... 2
Material necesario para realizar la practica: ....................................................................................... 2
Código fuente para la placa Arduino:.................................................................................................. 2
Solución a nivel de circuitería: ............................................................................................................ 3
Módulo bluetooth HC-07 .................................................................................................................... 4
Diagrama de conexión del led RGB con Arduino y modulo bluetooth HC-07: ................................... 5
Aplicativo bluetooth en Android. ........................................................................................................ 7
Manifest: ......................................................................................................................................... 8
Strings .............................................................................................................................................. 9
Menú ............................................................................................................................................... 9
led_tri_color.xml ......................................................................................................................... 9
desconecta.xml ........................................................................................................................... 9
Layuot .............................................................................................................................................. 9
activity_led_tri_color.xml ........................................................................................................... 9
Clases Principales .......................................................................................................................... 12
ConexionBT.java ........................................................................................................................ 12
LedTriColor.java......................................................................................................................... 20
Detalles importantes del desarrollo de la aplicación. ....................................................................... 27
Como funciona LedTriColor............................................................................................................... 28
Anexos ............................................................................................................................................... 30
Obtener la MAC de un módulo bluetooth. ................................................................................... 31
Descripción general del proyecto a implementar:
En la presente guía se muestra las modificaciones que se deben realizar al circuito elaborado en la
guía anterior para poder manipular un led RGB por medio de un dispositivo móvil con SO Android
2.2 o mejor.
En la guía anterior logramos manipular un led RGB por medio de comandos desde la computadora
gracias a la consola de comunicación serial del IDE de Arduino, en esta guía vamos a llevarlo un
paso más adelante logrando enviar parámetros por bluetooth desde una aplicación en Android la
cual enviara el parámetro que corresponda la presionar el color que deseamos encender.
Hablaremos un poco de lo que son los módulos bluetooth y para qué sirve cada uno de los pines
que nos interesan conocer y así realizar la práctica de la mejor manera posible, evitando así
conectar mal nuestro modulo, asegurándonos así la integridad del mismo.
En la parte de circuitería integraremos un módulo bluetooth a nuestra placa Arduino para que
este se pueda comunicar con el dispositivo móvil que deseemos, y luego la vincularemos a nuestro
dispositivo móvil para que puedan comunicarse entre sí.
En la parte programática desarrollaremos la aplicación por la cual nos comunicaremos con la placa
Arduino, para lograr esto no necesitaremos modificar nuestro sketch ya que la comunicación entre
el modulo bluetooth y la placa Arduino siempre se da por medio del puerto serial de la placa.
1
Precondiciones para la efectiva realización de la siguiente guía:



Haber concluido la guía de implementación de un dispositivo para controlar un led RGB
desde la computadora por medio de la placa Arduino.
Tener el circuito elaborado en la guía anterior.
Conocimiento en la creación de aplicativos para Android.
Material necesario para realizar la practica:



Modulo bluetooth compatible con arduino por ejemplo HC-05, HC-06, HC-07 o RN-42.
Dispositivo móvil con bluetooth y SO Android 2.2 o mejor.
Batería de 12v y clavija hembra tipo Jack para alimentar la placa y el modulo bluetooth o si
se posee una fuente DC a 12 voltios también se puede utilizar.
Código fuente para la placa Arduino:
Debido a que la comunicación por parte del módulo bluetooth con la placa Arduino igualmente se
realiza por medio del puerto serie de la misma, no se hará ningún cambio en el código fuente para
que este funcione, por lo que no será necesario modificar el sketch de la guía anterior.
2
Solución a nivel de circuitería:
Debido a que el circuito para controlar el led RGB es el mismo lo único que cambia en la manera
de comunicarnos con la placa, que en esta ocasión es por medio de un módulo bluetooth.
Para poder conectar nuestro modulo bluetooth en los pines correctos es necesario recordar el
siguiente diagrama.
Existe 2 formas de comunicarnos con esta placa Arduino:
1. Por medio del cable USB.
2. A través de los pines de recepción y transmisión de datos que son el Pin 0 (Rx0) y Pin 1 (Tx0)
respectivamente.
Cabe aclarar que en otras placas Arduino como por ejemplo los Atmega 2560 se cuenta con 4
pares de pines Tx y Rx con los que se puede tener diversas fuentes de comunicación.
Una vez teniendo claro cuáles son los pines de comunicación de la placa Arduino procedemos a
explicar algunas generalidades del módulo bluetooth a utilizar y luego procedemos a conectar el
modulo a nuestra placa Arduino.
3
Módulo bluetooth HC-07
Este módulo es de los más comunes para trabajar con Arduino ya que tiene un alcance aceptable y
su precio es muy accesible.
Si usted posee un HC-05 o HC-06, el pinnado es el mismo ya que forman parte de la misma familia,
el funcionamiento de cada uno de los pines se detalla a continuación.
RXD: Es el pin que se encarga de la recepción de los datos que se desean transmitir por medio de
bluetooth. Este pin se conecta directamente al pin TX de la placa Arduino.
TXD: Es el pin que se encarga de la transmisión de los datos que se han recibido por medio del
bluetooth hacia la placa Arduino. Este pin se conecta al RX del Arduino.
GND: Es el pin de Tierra, se conecta a mismo GND del Arduino para cerrar el circuito electrónico.
VCC: Es el pin de alimentación y tiene un margen de alimentación funcional de 3.6v a 6v. Se
conecta al pin de alimentación de nuestro circuito.
Los pines STATE y KEY nos sirven para la respectiva configuración de nuestro modulo, en los casos
que se deseen cambiar los parámetros de fábrica. Cabe mencionar que el modulo debe estar
previamente configurado; normalmente la configuración de fábrica de estos módulos es
suficiente. Aunque hay caso en que se desea cambiar la clave de emparejamiento, el nombre del
módulo, o en un caso especial los baudios de transmisión por defecto son 9600, este proceso no
se explica en esta guía.
4
Diagrama de conexión del led RGB con Arduino y modulo bluetooth HC-07:
5
Los pines del módulo que utilizaremos son los siguientes:




El pin RX (cable amarillo) del módulo HC-07 se conecta al pin TX0 del Arduino.
El pin TX (cable café) del módulo HC-07 se conecta al pin RX0 del Arduino.
El pin VCC (cable anaranjado) del módulo HC-07 se conecta al pin VCC del Arduino.
El pin GND (cable negro) del módulo HC-07 se conecta al GND del Arduino.
Como se puede observar, los otros componentes quedan conectados exactamente igual que en la
guía anterior. Si hay alguna duda revise la guía anterior.
Antes de proceder a alimentar el circuito para hacer una prueba si nuestro modulo bluetooth ha
sido bien conectado, tomémonos el tiempo de revisar las conexiones ya que estos dispositivos son
delicados y podrían sufrir algún daño por cualquier descuido.
Procedemos a alimentar nuestro circuito ya se por medio de una batería de 12v(cuadrada), una
fuete de 12 voltios de por lo menos 1A o por medio del cable usb hacia la computadora, en este
momento el led(Rojo) indicador de nuestro modulo debe estar parpadeante lo que indica que está
listo para aparearse con otro dispositivo bluetooth. Y al momento en que se conecten este led
debe de dejar de parpadear y quedar encendido.
En este momento ya tenemos nuestro circuito listo para conectarnos a él por medio de un
dispositivo con bluetooth, para esta práctica en específico lo haremos desde un dispositivo móvil
con SO Android 2.2 o mejor.
6
Aplicativo bluetooth en Android.
A continuación se presenta el código fuente para realizar la aplicación con la que controlaremos
nuestro led RGB.
Este aplicativo es capaz de funcionar desde dispositivos con Android 2.2 en adelante, aunque cabe
aclarar que en versiones más recientes de Android se pueden utilizar funciones que facilitan el
manejo del bluetooth, pero como el objetivo de esta práctica es abarcar la mayoría de dispositivos
Android no se ha hecho uso de estas funciones.
Android 4.2.2
Android 2.2
7
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ues.fia.eisi.ledtricolor"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<!-- Permisos para utilizar el Bluetooth -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="ues.fia.eisi.ledtricolor.LedTriColor"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
8
Strings
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<resources>
<string name="app_name">LedTriColor</string>
<string name="hello_world">Controlador Led RGB</string>
<string name="bluetooth">Conectar</string>
<string name="Off">Apagar</string>
<string name="Rojo">Rojo</string>
<string name="Verde">Verde</string>
<string name="Azul">Azul</string>
<string name="Desconexion">Desconectar</string>
<string name="mac">00:12:07:13:12:91</string><!--HINT FORMATO DE MAC -->
</resources>
Menú
led_tri_color.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/Conexion"
android:title="@string/bluetooth"
android:orderInCategory="100"
android:showAsAction="never">
</item>
</menu>
desconecta.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/desconexion"
android:title="@string/Desconexion"
android:orderInCategory="100">
</item>
</menu>
Layuot
activity_led_tri_color.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<RelativeLayout
android:layout_width="wrap_content"
9
android:layout_height="wrap_content"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".LedTriColor" >
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello_world"
android:textSize="25sp" />
<EditText
android:id="@+id/mac"
android:layout_width="fill_parent"
android:layout_height="70dp"
android:layout_below="@id/textView1"
android:ems="10"
android:hint="@string/mac"
android:inputType="text|textCapCharacters"
android:maxLength="17"
android:textSize="25sp" >
<requestFocus />
</EditText>
<LinearLayout
android:id="@+id/btnConexion"
android:layout_width="fill_parent"
android:layout_height="80dp"
android:layout_below="@id/mac" >
<Button
android:id="@+id/conectar"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="@string/bluetooth"
android:textSize="20sp" />
<Button
android:id="@+id/desconectar"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="@string/Desconexion"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/botones"
android:layout_width="fill_parent"
10
android:layout_height="100dp"
android:layout_below="@id/btnConexion"
android:layout_marginBottom="20dp"
android:layout_marginTop="20dp"
android:orientation="horizontal" >
<Button
android:id="@+id/Rojo"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="@string/Rojo"
android:textSize="30sp" />
<Button
android:id="@+id/Verde"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="@string/Verde"
android:textSize="30sp" />
<Button
android:id="@+id/Azul"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="@string/Azul"
android:textSize="30sp" />
</LinearLayout>
<Button
android:id="@+id/Off"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_below="@id/botones"
android:text="@string/Off"
android:textSize="30sp" />
</RelativeLayout>
</ScrollView>
11
Clases Principales
Esta clase es la encargada de efectuar todo lo concerniente a la conexión y a la comunicación.
ConexionBT.java
package ues.fia.eisi.ledtricolor;
// Debug Para monitorizar los
eventos
private static final String
TAG = "Servicio_Bluetooth";
private static final boolean
D = true;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import
android.bluetooth.BluetoothAdapte
r;
import
android.bluetooth.BluetoothDevice
;
import
android.bluetooth.BluetoothServer
Socket;
import
android.bluetooth.BluetoothSocket
;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
// Nombre para el registro
SDP cuando el socket sea creado
private static final String
NAME = "BluetoothDEB";
// UUID Identificador unico
de URI para esta aplicacion
private static final UUID
MY_UUID =
UUID.fromString("00001101-00001000-8000-00805F9B34FB");
// UUID para chat con otro
Android
("fa87c0d0-afac11de-8a39-0800200c9a66");
// UUID para modulos BT RN42
("00001101-0000-1000-800000805F9B34FB");
/**
* Esta clase realiza todo el
trabajo para configurar y
administrar la conexion Bluetooth
con otro dispositivo.
* Hay un hilo que esta a la
escucha de conexiones entrantes,
un hilo para conexiones con un
dispositivo y
* un hilo para realizar las
transmisiones una vez que se este
conectado.
*/
public class ConexionBT {
// Campos de coexion
private final
BluetoothAdapter AdaptadorBT;
private final Handler
mHandler;
private AcceptThread
HebraDeAceptacion;
private ConnectThread
HiloDeConexion;
private ConnectedThread
HiloConetado;
private int EstadoActual;
//<<<<<<<<<<<<<<<<<<<<<<<<<
<<<< Definiciones
>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Constantes que indican el
estado de conexion
12
public static final int
STATE_NONE = 0;
// No se
esta haciendo nada
public static final int
STATE_LISTEN = 1;
//
Escuchando por conexiones
entrantes
public static final int
STATE_CONNECTING = 2; //
Iniciando conexion saliente
public static final int
STATE_CONNECTED = 3; //
Conectado con un dispositivo
EstadoActual = estado;
// Le enviamos al Handler el
nuevo estado actual para que se
actualize en la Actividad
mHandler.obtainMessage(LedTriColo
r.Mensaje_Estado_Cambiado,
estado, -1).sendToTarget();
}
/**
* Regresa el estado de la
conexion */
public synchronized int
getState() {
return EstadoActual;
}
//<<<<<<<<<<<<<<<<<<<<<<<<<
<<<< METODOS
>>>>>>>>>>>>>>>>>>>>>>>>>>>
//----<<<<---->>>>----METODOS
NO ALTERADOS----<<<<---->>>>---/**
* Constructor. Prepara una
nueva sesion para la conexion
Bluetooth Smartphone-Dispositivo
* @param context El
identificador UI de la actividad
de context
* @param handler Un Handler
para enviar mensajes de regreso a
la actividad marcada por el UI
*
* */
public ConexionBT(Context
context, Handler handler) {
AdaptadorBT =
BluetoothAdapter.getDefaultAdapte
r();
EstadoActual = STATE_NONE;
mHandler = handler;
}
/**
* Inicia el servicio
bluetooth. Especificamente inicia
la HebradeAceptacion para iniciar
el
* modo de "listening".
LLamado por la Actividad
onResume() */
public synchronized void
start() {
if (D) Log.e(TAG,
"start");
//Cancela cualquier hilo
que quiera hacer una conexion
if (HiloDeConexion !=
null) {HiloDeConexion.cancel();
HiloDeConexion = null;}
//Cancela cualquier hebra
que este corriendo una conexion
if (HiloConetado != null)
{HiloConetado.cancel();
HiloConetado = null;}
/**
* Actualizamos estado de la
conexion BT a la actividad
* @param estado Un entero
definido para cada estado
*/
private synchronized void
setState(int estado) {
// Inicia la hebra que
escuchara listen en el
BluetoothServerSocket
if (HebraDeAceptacion ==
null) {
13
HebraDeAceptacion =
new AcceptThread();
* @param socket El socket
Bt donde se realizara la conexion
* @param device El
dispositivo BT con que se
conectara
*/
public synchronized void
connected(BluetoothSocket socket,
BluetoothDevice device) {
if (D) Log.e(TAG,
"connected");
HebraDeAceptacion.start();
}
setState(STATE_LISTEN);
}
/**
* Inicia el HiloConectado
para iniciar la conexion con un
dispositivo remoto
* @param device -->El
dispositivo BT a conectar
*/
public synchronized void
connect(BluetoothDevice device) {
if (D) Log.e(TAG,
"Conectado con: " + device);
// Cancela el hilo que
completo la conexion
if (HiloDeConexion !=
null) {HiloDeConexion.cancel();
HiloDeConexion = null;}
//Cancela el hilo que
actualmente esta corriendo la
conexion
if (HiloConetado != null)
{HiloConetado.cancel();
HiloConetado = null;}
//Cancela cualquier hilo
que intente realizar una conexion
if (EstadoActual ==
STATE_CONNECTING) {
if (HiloDeConexion !=
null) {HiloDeConexion.cancel();
HiloDeConexion = null;} }
// Cancela la
Hebradeaceptacion debido a que
solo queremos conectar con un
dispositivo**********
if (HebraDeAceptacion !=
null)
{HebraDeAceptacion.cancel();
HebraDeAceptacion = null;}
//Cancela cualquier hilo
que se encuentre corriendo una
conexion
if (HiloConetado != null)
{HiloConetado.cancel();
HiloConetado = null;}
//Inicia el hilo para
administrar la conexion y
realizar transmisiones
HiloConetado = new
ConnectedThread(socket);
HiloConetado.start();
//Inicia el hilo para
conectar con un dispositivo
HiloDeConexion = new
ConnectThread(device);
HiloDeConexion.start();
//Envia el nombre del
dispositivo conectado de vuelta
Message msg =
mHandler.obtainMessage(LedTriColo
r.Mensaje_Nombre_Dispositivo);
Bundle bundle = new
Bundle();
setState(STATE_CONNECTING);
}
/**
* Inicia la hebra conectada
para iniciar la administracion de
la conexión BT
14
if (EstadoActual !=
STATE_CONNECTED) return;
r = HiloConetado; }
// Realizar la escritura
Asincrona
r.write(out);
}
bundle.putString(LedTriColor.DEVI
CE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
}
/**
* Indica que el intento de
conexion fallo y notifica a la
actividad
WidgetProvider/UpdateService
*/
private void
connectionFailed() {
setState(STATE_LISTEN);
//Envia un mensaje de
falla de vuelta a la actividad
Message msg =
mHandler.obtainMessage(LedTriColo
r.Mensaje_TOAST);
Bundle bundle = new
Bundle();
/**
* Para todos los hilos y
pone el estado de STATE_NONE
donde no esta haciendo nada
*/
public synchronized void
stop() {
if (D) Log.e(TAG,
"stop");
if (HiloDeConexion !=
null) {HiloDeConexion.cancel();
HiloDeConexion = null;}
if (HiloConetado != null)
{HiloConetado.cancel();
HiloConetado = null;}
if (HebraDeAceptacion !=
null)
{HebraDeAceptacion.cancel();
HebraDeAceptacion = null;}
setState(STATE_NONE);
}
bundle.putString(LedTriColor.TOAS
T, "Error de conexión");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
/**
* Indica que la conexion se
perdio y notifica a la UI
activity(WidgetProvider/UpdateSEr
vice)
*/
private void connectionLost()
{
setState(STATE_LISTEN);
//Envia un mensaje de
falla de vuelta a la actividad
Message msg =
mHandler.obtainMessage(LedTriColo
r.Mensaje_TOAST);
Bundle bundle = new
Bundle();
/**
* Escribe en el
HiloConectado de manera Asincrona
* @param out Los bytes a
escribir
* @see
ConnectedThread#write(byte[])
*/
public void write(byte[] out)
{
ConnectedThread r;
//Creacion de objeto temporal
// Syncronizar la copia
del HiloConectado
synchronized (this)
{
15
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
public void run() {
if (D) Log.e(TAG,
"Comenzar HiloDeAceptacion " +
this);
bundle.putString(LedTriColor.TOAS
T, "Se perdio conexion");
msg.setData(bundle);
mHandler.sendMessage(msg);
msg =
mHandler.obtainMessage(LedTriColo
r.MESSAGE_Desconectado);
setName("HiloAceptado");
BluetoothSocket
socket = null;
//Escucha al server
socket si no estamos conectados
while (EstadoActual
!= STATE_CONNECTED) {
try {
//Esto es un
bloque donde solo obtendremos una
conexion o una excepcion
socket =
mmServerSocket.accept();
} catch
(IOException e) {
Log.e(TAG,
"accept() failed", e);
break;
}
//Si la conexion
fue aceptada...
if (socket !=
null) {
synchronized
(ConexionBT.this) {
switch
(EstadoActual) {
case
STATE_LISTEN:
case
STATE_CONNECTING:
//
Situation normal. Iniciamos
HebraConectada
mHandler.sendMessage(msg);
}
/**
* Este hilo corre mientras
se este ESCUCHANDO por conexiones
entrantes. Este se
* comporta como el ladoServidor cliente. Corre mientras
la conexion es aceptada(o
cancelada)
*/
private class AcceptThread
extends Thread {
// El soket de servidor
Local
private final
BluetoothServerSocket
mmServerSocket;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
public AcceptThread() {
BluetoothServerSocket
tmp = null;
//Creamos un nuevo
listening server socket
try {
tmp =
AdaptadorBT.listenUsingRfcommWith
ServiceRecord(NAME, MY_UUID);
} catch (IOException
e) {
Log.e(TAG,
"listen() fallo", e);
}
mmServerSocket = tmp;
connected(socket,
socket.getRemoteDevice());
break;
case
STATE_NONE:
16
case
conexion de salida con un
dispositivo.
* Este correra a través de
la conexion ya sea establecida o
fallada
*/
private class ConnectThread
extends Thread {
private final
BluetoothSocket mmSocket;
private final
BluetoothDevice mmDevice;
STATE_CONNECTED:
// O
no esta lista o ya esta
conectado. Termina el nuevo
socket
try
{
socket.close();
}
catch (IOException e) {
Log.e(TAG, "No se pudo cerrar el
socket no deseado", e);
}
public
ConnectThread(BluetoothDevice
device) {
mmDevice = device;
BluetoothSocket tmp =
null;
// Obtiene un
BluetoothSocket para la conexion
con el Dispositivo obtenido
try {
tmp =
device.createRfcommSocketToServic
eRecord(MY_UUID);
} catch (IOException
e) {
Log.e(TAG,
"create() Fallo", e);
}
mmSocket = tmp;
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
public void run() {
Log.e(TAG,
"Comenzando HebraConectada");
break;
}
}
}
}
if (D) Log.e(TAG,
"Fin de HIlodeAceptacion");
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
public void cancel() {
if (D) Log.e(TAG,
"Cancela " + this);
try {
mmServerSocket.close();
} catch (IOException
e) {
Log.e(TAG,
"close() del servidor FAllo", e);
}
}
setName("HiloConectado");
//Siempre cancela la
busqueda debido a que esta hara
lenta la conexion
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
}
AdaptadorBT.cancelDiscovery();
// Realiza la
conexion con el socketBluetooth
try {
/**
* Esta Hebra correra
mientras se intente realizar una
17
// Aqui solo
recibiremos o una conexion
establecida o una excepcion
Log.e(TAG,
"close() of connect socket
failed", e);
}
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
}//fin de conectThread
mmSocket.connect();
} catch (IOException
e) {
connectionFailed();
// Cierra el
socket
try {
/**
* Este hilo corre durante la
conexion con un dispositivo
remoto.
* Este maneja todas las
transmisiones de entrada y
salida.
*/
private class ConnectedThread
extends Thread {
private final
BluetoothSocket BTSocket;
private final InputStream
INPUT_Stream;
private final
OutputStream OUTPUT_Stream;
mmSocket.close();
} catch
(IOException e2) {
Log.e(TAG,
"Imposible cerrar el socket
durante la falla de conexion",
e2);
}
// Inicia el
servicio a traves de reiniciar el
modo de listening
ConexionBT.this.start();
return;
}
// Resetea el
HiloConectado pues ya lo hemos
usado
synchronized
(ConexionBT.this) {
HiloDeConexion =
null;
}
// Inicia el
hiloconectado
connected(mmSocket,
mmDevice);
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
public void cancel() {
try {
mmSocket.close();
} catch (IOException
e) {
public
ConnectedThread(BluetoothSocket
socket) {
Log.d(TAG, "Creacion
de HiloConectado");
BTSocket = socket;
InputStream tmpIn =
null;
OutputStream tmpOut =
null;
// Obtencion del
BluetoothSocket de entrada y
saldida
try {
tmpIn =
socket.getInputStream();
tmpOut =
socket.getOutputStream();
} catch (IOException
e) {
18
Log.e(TAG,
"Sockets temporales No creados",
e);
}
INPUT_Stream = tmpIn;
OUTPUT_Stream =
tmpOut;
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
/**
* Escribe al Stream de
salida conectado
* @param buffer Los
bytes a escribir
*/
public void write(byte[]
buffer) {
try {
public void run() {
Log.e(TAG, "Comenzar
Hebraconectada");
byte[] buffer = new
byte[1024];
int bytes;
while (true) {
//Mantiene escuchando el
InputStream mientras este
conectado
try {
//Lee desde el
InputStream
bytes =
INPUT_Stream.read(buffer);
// byte[] readBufX = (byte[])
buffer; //Construye un String
desde los bytes validos en el
buffer
// String readMessageX = new
String(readBufX, 0, bytes);//Se
envia el readNessagexxx en lugar
del buffer pues ya se PARSEO
OUTPUT_Stream.write(buffer)
; //Compartir el mensaje enviado
con la UI activity
mHandler.obtainMessage(LedTriColo
r.Mensaje_Escrito, -1, -1,
buffer).sendToTarget();
} catch (IOException
e) {Log.e(TAG, "Exception during
write", e);}
}//FIN DE WRITE
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
public void cancel() {
try {
mHandler.obtainMessage(LedTriColo
r.Mensaje_Leido, bytes, -1,
buffer).sendToTarget();
//readMessageX por buffer
} catch (IOException e)
{Log.e(TAG, "disconnected",
e);connectionLost();break; }
}//_____________----FIN DE WHILE (TRUE)----_________________
BTSocket.close();
} catch (IOException
}//**************_________FIN DE
PUBLIC VOID
RUN__________**************
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
e) {
Log.e(TAG,
"close() del socket conectado
Fallo", e);
}
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
}//-------------------*****FIN de la clase
ConnectedThread*****------------------
19
>>>_____FIN DE LA CLASE
CONEXIONBT_____<<<<<_____>>>>>___
_<<<<<_____>>>>>
}
//<<<<<____>>>>>_____<<<<<_____>>
LedTriColor.java
Esta es nuestra clase principal y desde donde utilizaremos la clase ConexionBT.
package ues.fia.eisi.ledtricolor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import
android.annotation.SuppressLint;
import android.app.Activity;
import
android.bluetooth.BluetoothAdapte
r;
import
android.bluetooth.BluetoothDevice
;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public static final int
Mensaje_Leido = 2;
public static final int
Mensaje_Escrito = 3;
public static final int
Mensaje_Nombre_Dispositivo = 4;
public static final int
Mensaje_TOAST = 5;
public static final int
MESSAGE_Desconectado = 6;
public static final int
REQUEST_ENABLE_BT = 7;
public static final String
DEVICE_NAME = "device_name";
public static final String TOAST
= "toast";
//Nombre del dispositivo
conectado
private String
mConnectedDeviceName = null;
// Adaptador local Bluetooth
private BluetoothAdapter
AdaptadorBT = null;
//Objeto miembro para el servicio
de ConexionBT
private ConexionBT Servicio_BT =
null;
//variables para el Menu de
conexión
private boolean
seleccionador=false;
public int
Opcion=R.menu.led_tri_color;
private EditText dirMac;
/*-----------------------------------------------------------------------------------------------*/
@Override
public void onCreate(Bundle
savedInstanceState){
@SuppressLint("HandlerLeak"
)
public class LedTriColor
extends Activity {
/*---------------------------------------------------------------------------------------------*/
// Debugging
public static final
String TAG = "LedTriColor";
public static final boolean D =
true;
// Tipos de mensaje enviados y
recibidos desde el Handler de
ConexionBT
public static final int
Mensaje_Estado_Cambiado = 1;
20
super.onCreate(savedInstanceState
);
Desconectar.setOnClickListe
ner(onclick);
setContentView(R.layout.activity_
led_tri_color);
Button
Azul,Verde,Rojo,oFF,Conectar,Desc
onectar;
dirMac=(EditText)findViewBy
Id(R.id.mac);
}
Azul=(Button)findViewById(R.id.Az
ul);
View.OnClickListener
onclick= new
View.OnClickListener() {
Azul.setOnClickListener(onc
lick);
@Override
public
Verde=(Button)findViewById(
R.id.Verde);
void onClick(View v) {
//
TODO Apéndice de método generado
automáticamente
Verde.setOnClickListener(on
click);
switch(v.getId()){
case
Rojo=(Button)findViewById(R
.id.Rojo);
R.id.Azul:
if(D) Log.e("BotonLed",
"Encendiendo..");
Rojo.setOnClickListener(onc
lick);
sendMessage("A");
oFF=(Button)findViewById(R.
id.Off);
break;
oFF.setOnClickListener(oncl
case
ick);
R.id.Verde:
if(D) Log.e("BotonLed",
"Encendiendo..");
Conectar=(Button)findViewBy
Id(R.id.conectar);
sendMessage("V");
Conectar.setOnClickListener
(onclick);
break;
Desconectar=(Button)findVie
wById(R.id.desconectar);
case
R.id.Rojo:
21
if(D) Log.e("BotonLed",
"Encendiendo..");
if(seleccionador)// Esta
conectado?
sendMessage("R");
{
sendMessage("x");
break;
case
desconectar();
R.id.Off:
}
if(D) Log.e("BotonLed",
"Apagando..");
else {
sendMessage("x");
Toast.makeText(LedTriColor.
this,"NO ESTA
CONECTADO",Toast.LENGTH_LONG).sho
w();
break;
case
R.id.conectar:
}
if(D) Log.e("BotonLed",
"Conectado!!!.....!!!");
break;
}
if(!seleccionador) //Esta
desconectado?
}
};
public
iniciarConexion();
void onStart()
{
super.onStart();
ConfigBT();
else {
}
Toast.makeText(LedTriColor.
this,"ESTA
CONECTADO!!",Toast.LENGTH_LONG).s
how();
@Override
public void
onDestroy(){
super.onDestroy();
if (Servicio_BT !=
null)
Servicio_BT.stop();//Detenemos
servicio
}
}
break;
case
R.id.desconectar:
public void ConfigBT(){
// Obtenemos el
adaptador de bluetooth
if(D) Log.e("BotonLed",
"Conectado!!!.....!!!");
22
AdaptadorBT =
BluetoothAdapter.getDefaultAdapte
r();
if
(AdaptadorBT.isEnabled()) //Si el
BT esta encendido
{
if
(Servicio_BT == null) //y el
Servicio_BT es nulo, invocamos el
Servicio_BT
{
Activity.RESULT_OK) {//BT esta
activado,iniciamos servicio
ConfigBT();
}
else {//No se activo BT, salimos
de la app
Toast.makeText(this,"ENCIEN
DA EL BT!!!
",Toast.LENGTH_LONG).show();
finish(); //Fin de la APP
Servicio_BT = new
ConexionBT(this, mHandler);
}
}
}
else{
}//fin de switch case
if(D) Log.e("Setup",
"Bluetooth apagado...");
//Mensaje para el log
}//fin de
onActivityResult
Intent enableBluetooth =
new
Intent(BluetoothAdapter.ACTION_RE
QUEST_ENABLE);
@Override
public boolean
onPrepareOptionsMenu(Menu menux){
startActivityForResult(enab
leBluetooth, REQUEST_ENABLE_BT);
}
}
menux.clear();//limpiamos menu
actual
if
(seleccionador==false)
public void
onActivityResult(int requestCode,
int resultCode, Intent data){
//Una vez que se
ha realizado una actividad
regresa un "resultado"...
switch
(requestCode) {
Opcion=R.menu.led_tri_color
;//dependiendo las necesidades
if
(seleccionador==true)
Opcion=R.menu.desconecta;
// crearemos un menu diferente
case
REQUEST_ENABLE_BT://Respuesta al
intento de encendido de BT
if
(resultCode ==
getMenuInflater().inflate(O
pcion, menux);
return
super.onPrepareOptionsMenu(menux)
;
}
23
@Override
public boolean
onOptionsItemSelected(MenuItem
item) {
switch
(item.getItemId()) {
case R.id.Conexion:
if(D)
Log.e("conexion",
"conectandonos");
if(!dirMac.getText().toStri
ng().equals(""))
Toast.makeText(this,"MAC
ERRONEA",
Toast.LENGTH_LONG).show();
direccion="00:12:07:1
3:12:91"; //Direccion MAC
default.
}
iniciarConexion();
return direccion;
}
public void
iniciarConexion(){
return true;
String
direccionMac=obtenerMac();//Extra
emos la direccion
try {
case
R.id.desconexion:
sendMessage("x");
BluetoothDevice device =
AdaptadorBT.getRemoteDevice(direc
cionMac);
desconectar();
return true;
}//fin de swtich de
opciones
return false;
}//fin de metodo
onOptionsItemSelected
Servicio_BT.connect(device);
} catch
(Exception e) {
//
TODO: handle exception
}
public String
obtenerMac(){
String direccion="";
}
public void
desconectar(){
if(dirMac.getText().toStrin
g().length()==17){
if (Servicio_BT
!= null)
direccion=dirMac.getText().
toString();
}
else
{
Servicio_BT.stop();//Detene
mos la comunicacion BT.
}
24
public void
sendMessage(String message) {
if
(Servicio_BT.getState() ==
ConexionBT.STATE_CONNECTED)
{//checa si estamos conectados a
BT
if
(message.length() > 0) {
//
checa si hay algo que enviar
byte[] send =
message.getBytes();//Obtenemos
bytes del mensaje
if(D)
Log.e(TAG, "Mensaje enviado:"+
message);
if(D) Log.e(TAG, "Message_write
=w= "+ writeMessage);
break;
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>
case
Mensaje_Leido:
byte[] readBuf = (byte[])
msg.obj;//buffer de lectura...
//Construye un String de los
bytes validos en el buffer
Servicio_BT.write(send);
//Mandamos a escribir el mensaje
}
} else
Toast.makeText(this, "No
conectado",
Toast.LENGTH_SHORT).show();
}//fin de
sendMessage
String readMessage = new
String(readBuf, 0, msg.arg1);
if(D) Log.e(TAG, "Message_read
=w= "+ readMessage);
break;
final Handler mHandler
= new Handler() {
@Override
public void
handleMessage(Message msg) {
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>
case
Mensaje_Nombre_Dispositivo:
switch
(msg.what) {
mConnectedDeviceName =
msg.getData().getString(DEVICE_NA
ME); //Guardamos nombre del
dispositivo
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>
case
Mensaje_Escrito:
Toast.makeText(getApplicationCont
ext(), "Conectado con "+
mConnectedDeviceName,
Toast.LENGTH_SHORT).show();
byte[] writeBuf = (byte[])
msg.obj;//buffer de escritura...
seleccionador=true;
// Construye un String del Buffer
break;
String writeMessage = new
String(writeBuf);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
25
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>
case
Mensaje_TOAST:
Log.e("Conexion","DESConectados")
;
seleccionador=false;
break;
Toast.makeText(getApplicationCont
ext(),
msg.getData().getString(TOAST),
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>
Toast.LENGTH_SHORT).show();
break;
}//FIN DE SWITCH CASE PRIMARIO
DEL HANDLER
}//FIN DE
METODO INTERNO handleMessage
};//Fin de
Handler
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>
case
MESSAGE_Desconectado:
}//Fin LedTriColor
if(D)
26
Detalles importantes del desarrollo de la aplicación.

Para que código anterior no se necesita ningún otro tipo de extensión, jar o cualquier otra
configuración especial, basta con el código presentado.

El código de la aplicación está documentado por si tiene alguna duda, se le invita a seguir
la lógica del mismo y si fuese necesario se puede apoyar del ciclo de vida de una
aplicación Android.

La dirección MAC (siglas en inglés de media access control; en español "control de
acceso al medio") es un identificador de 48 bits (6 bloques hexadecimales) que
corresponde de forma única a una tarjeta o dispositivo de red. Se conoce también
como dirección física, y es única para cada dispositivo.
Por medio de esta dirección MAC nos conectamos a nuestro modulo bluetooth, si dentro
de LedTricolor.java buscamos direccion="00:12:07:13:12:91", ahí se encuentra la dirección
por default a la cual la aplicación intentara conectarse, si no encontrará ninguna dirección
ingresada en el Editext o si la dirección ingresada es errónea. Motivo por el cual se le invita
a cambiarla por la dirección de su módulo bluetooth y por cuestiones estéticas a cambiar
el hint del Editext.
Si no sabe cómo obtener la dirección MAC de su módulo bluetooth se le recomienda ver
los anexos.
27
Como funciona LedTriColor
Al correr la aplicación, si no tenemos encendido el servicio de bluetooth esta automáticamente
nos pedirá permiso para encenderlo, si aceptamos nos activara el servicio, pero no lo activamos
cierra la aplicación.
Luego si corregimos la dirección MAC en el código anterior para que por defecto funcionase la de
nuestra preferencia directamente podemos intentar conectarnos, o si intenta conectarse a otro
modulo que no sea el suyo debe de ingresar la dirección en el Editext principal y luego en
conectar.
28
En este momento procedemos a alimentar nuestro circuito, para que al momento de intentar
conectar con nuestro modulo este sea encontrado. Recuerde que el led del módulo bluetooth
debe estar parpadeado (color rojo) y al momento en que nuestros dispositivos se conecten este
indicador quedara directo.
Puede conectarse de 2 formas diferentes, por medio del botón conectar o abriendo el menú y
seleccionando conectar y de las misma manera para desconectarse. En este momento al presionar
conectar, nos enviará una notificación de vinculación de dispositivos en la cual debemos ingresar
la clave de vinculación del módulo bluetooth, si esta no ha sido cambiada normalmente es 1234 o
0000 ya que son las claves que traen de fábrica.
Si ingresamos la clave correcta procederá a intentar la conexión, con lo cual podemos estar seguro
que los dispositivos están vinculados y si no vuelva a intentar de nuevo con otra clave. La
vinculación solo se da la primera vez que se intentan conectar dos dispositivos bluetooth.
Si la conexión fue exitosa nos informara junto con el nombre del módulo bluetooth al que nos
hemos conectado, en nuestro caso el modulo se ha nombrado “linvor”.
Los mismos comandos que enviamos en la guía anterior son
enviados por esta aplicación al momento de presionar
cualquiera de los botones. Ya sea Rojo envía “r”, o Azul envía
“a” y estos datos son recibidos por la placa Arduino y esta se
encarga de encender el led correspondiente.
29
Anexos
30
Obtener la MAC de un módulo bluetooth.
Se puede obtener con los métodos siguientes, siempre y cuando nuestro modulo bluetooth este
encendido.

Por medio de un dispositivo móvil BlackBerry:
o Primero debemos vincular los dispositivos.
o Una vez estén vinculados, nos dirigimos al panel de configuración del bluetooth.
o Luego buscamos los dispositivos bluetooth activos.
o Y ubicamos nuestro modulo y ahí aparece el nombre, lo seleccionamos y entramos
a las propiedades ahí encontraremos la dirección MAC con el siguiente formato:
##:##:##:##:##:##.

Instalando una aplicación de consola bluetooth para nuestro dispositivo Android:
o En este caso instalaremos BlueTerm (buscar en la playstore).
o Una vez instalada la abrimos y luego desde el menú de opciones.
o Seleccionamos “Conectarse a un dispositivo” y ahí nos aparecerá la lista de
dispositivos bluetooth cercanos con su respectivo nombre y dirección MAC.

Si disponemos con una maquina con dispositivo bluetooth:
o Vinculamos el modulo.
o Una vez vinculado, localizamos el dispositivo bluetooth de nuestro interés.
o Abrimos las propiedades del dispositivo vinculado y ahí encontraremos la
dirección MAC.
31
Descargar