Untitled - TESIUAMI

Anuncio
RESUMEN
En este trabajo plasmamos las acciones para realizar un programa que
controla servomotores con un dispositivo móvil, de la electrónica y de la
programación de android
Con respecto a la electrónica describimos los elementos necesarios para este
proyecto y como conectarlos, también el programa que controla toda la
electrónica, Señalizamos esquemas e imágenes para su mejor compresión.
En la parte de la programación de android, explicamos los requerimientos
mininos para realizarlo, encontraran puntos como instalación de las herramientas
para realizar la tarea, la forma de programar, variables, métodos y llamados.
Insertamos varias imágenes ilustrando los pasos realizados, en la preparación de
las herramientas y en la conformación del programa
En la parte de los anexos están todos los códigos de MPIDE y de ECLIPSE
realizados para completar la meta, solo son códigos no contiene ilustraciones.
1
OBJETIVO.
3
MARCO TEÓRICO
3
DESARROLLO
4
MATERIALES
Placa Chip KIT Uno32
Puerto Bluetooth
Protoboard
Servo motores
Dispositivo Móvil
4
4
4
4
4
4
Programación chip KIT Uno32
Hardware
Software
Bibliotecas
Variables
5
5
5
6
6
Programación Android
13
RESULTADOS
30
CONCLUSIONES
31
BIBLIOGRAFÍA
31
ANEXO
33
Código de Android
33
Codigo MPIDE
42
2
Objetivo.
Disponer de un sistema de software y hardware que permita controlar 5
servomotores con una aplicación desarrollada para un dispositivo móvil con
Sistema operativo Android. Uno de estos motores deberá ser controlado mediante
las señales del acelerómetro del dispositivo móvil.
Marco Teórico
Este proyecto abarca aspectos tanto de electrónica como de computación, ya
que tiene como objetivo controlar servomotores, de manera remota, mediante el
uso de un puerto Bluetooth. La aplicación conjunta los sistemas Android y Arduino.
El sistema Arduino fue programado para recibir y enviar los datos que
permitirán controlar los servomotores. Un dispositivo móvil con Sistema Operativo
Android y con un acelerómetro contiene los programas para enviar la información
de control.
Los programas desarrollados para la aplicación del dispositivo móvil fueron
hechos con el lenguaje de programación Java y con el ambiente de desarrollo
integrado (IDE) Eclipse.
Se usa un chip KIT Uno32, que es completamente compatible con la tarjeta
Arduino, para las funciones de control y comunicación. La aplicación se realizó con
el ambiente de desarrollo multiplataforma Arduino (MPIDE).
La aplicación es bastante eficiente ya que puede controlar hasta 5 servo
motores independientes, y la conexión entre ambos dispositivos es bastante
rápida; uno de los servomotores será controlado con los datos que envía el
dispositivo móvil de acuerdo a la información generada por el acelerómetro.
3
Desarrollo
MATERIALES
Placa Chip KIT Uno32
La placa Chip KIT Uno32, es una herramienta muy útil para la programación y
control de dispositivos electrónicos. Esta es de software libre, no se requiere de
licencias de ningún tipo para hacer uso de ella. Es posible realizar cuantas
aplicaciones necesitemos y funciona con muchas herramientas de los sistemas
Arduino.
Otra ventaja es que existe una gran cantidad de documentación que ayuda en
el desarrollo de aplicaciones.
Puerto Bluetooth
El puerto se denomina HC-06. Este se encuentra en un clico de 9600bps y
está configurado como esclavo; estas opciones se configuran de acuerdo con la
aplicación se está creando. La configuración de sincronización también se puede
personalizar
Protoboard
Necesitamos una placa protoboard para la conexión de los diferentes
dispositivos como los puerto bluetooth, indicadores (led) e interruptores para su
funcionamiento.
Servo motores
Motores que controlan la posición y el sentido de giro. La precisión de la
posición puede variar para distintos servo motores y el rango del movimiento
puede ir de 0 a 180 grados o de 0 a 360 grados.
Dispositivo Móvil
Cualquier dispositivo que tenga el sistema operativo android puede ser una
Tableta o un celular, la aplicación diseñada y programada se ejecuta en cualquier
dispositivo con el Sistema Operativo Android. Empezando en la versión 2.2 hasta
la versión 4.02. El dispositivo debe contar con sensor de acelerómetro ya que la
aplicación aprovecha estos sensores para enviar señales de movimiento a los
servo-motores.
4
Programación chip KIT Uno32
Hardware
Empezaremos explicando los elementos básicos del sistema Arduino. Es una
plataforma dirigida a electrónica la cual ayuda a controlar señales digitales y
analógicas tanto de entrada como de salida, la plataforma contiene un chip en el
cual se realiza la aplicación, se guarda para su uso posterior. Cuenta con 11
entradas analógicas y 39 salidas digitales estas también tienen la opción usarse
como entradas digitales, también cuenta con 5 puertos PWM, los que en versiones
anteriores ejecutan la señal tipo cuadrada que controla servo-motores. En las más
recientes se usa la biblioteca SERVO, de esta forma cualquier puerto de salida
puede controlar servo-motores, no sólo los puertos PWM
La edición del programa utiliza el puerto USB, la alimentación de voltaje es de
5v y 3.3v. Para trabajar con voltaje mayores será necesaria una fuente de
alimentación externa y configurar la tarjeta para aceptar este voltaje.
Software
Usamos la Multiplataforma Arduino IDE(MPIDE) versión libre. Este software
tiene las mismas bibliotecas de funciones y aplicaciones que un programa para
Arduino.
El lenguaje es similar al "Lenguaje C". Usamos la misma sintaxis y para
declarar variables aunque cambia es la forma de definir bibliotecas y constantes.
Para realizar una aplicación necesitamos dos métodos indispensables:
void setup. Donde declaramos variables globales y/o inicializar las variables
que usaremos para el resto del programa, establecemos configuraciones
necesarias para el programa y periféricos para su funcionamiento.
void loop. Método de ciclo infinito lo que se programe aquí se reproducirá
siempre, también podemos contar con variables locales, usar las globales y llamar
a otros métodos.
En este se pueden declarar métodos como en "Lenguaje C", sean procesos
que no regresan resultados o que si regresen algún valor.
5
Bibliotecas
Incluimos la biblioteca de este modo: #include <servo.h>. Esto para construir
objetos de tipo “servo” mismos que se encargan de mandar la señal de onda
cuadrada para el control de movimiento del servo.
Para el puerto Bluetooth no es necesario declarar bibliotecas.
Variables
Tipo char: Las variables “data1” y ”data2” servirán para la recepción de datos
que llegan por el puerto Bluetooth.
Tipo entero: Las variables “motor1”, “motor2”, “motor3”, “motor4”, “motor5” se
inician con valor 0 y sirven para identificar el motor que estamos controlando. Sólo
podemos controlar un motor a la vez.
Tipo entero: Las variables “m1”, “m2”, “m3”, “m4”, “m5” tendrán valor 2, 3, 4, 5
y 6 respectivamente, son puertos de salida digital, permite la salida a los servomotores por la biblioteca anteriormente incluida.
Tipo entero: Las variables “motor1_pos”, “motor2_pos”, “motor3_pos”,
“motor4_pos”, “motor5_pos”, guardarán la última posición de cada servo. Esto
evita algún movimiento no solicitado en los servos y saber cuando el motor
correspondiente llega a su límite.
Tipo servo: “miservo1”, “miservo2”, “miservo3”,”miservo4” y “miservo5” son
para controlar mediante las terminales de salida a los correspondientes servos. Si
utilizamos uno para todos los servo motores existirá una mezcla de posiciones y
movimientos involuntarios, cada objeto mantiene la posición actual de un motor.
La variable “miservoX” deben vincular un puerto de salida al objeto servo
utilizando, por ejemplo, “miservo1.attach(m1)”. Una vez creado el vinculo en el
método setup se inicia la posición de cada motor mediante la sentencia
miservo1.write(pos), en "pos" ponemos la posición en grados. Sólo acepta valores
enteros, en un rango de 0 a 360 grados dependiendo del tipo de motor. Existen
algunos motores que comprenden rango de 0 a 180 grados.
También se declara Serial.begin(9600) esto es la frecuencia de comunicación
del puerto Bluetooth que instalamos en la placa chip KIT Uno32.
6
La declaración del método loop. utilizamos data1 para recibir el primer valor
del puerto Bluetooth como sigue data1=Serial.read(),
El puerto de comunicación toma datos en serie. El dato de entrada lo tenemos
en data1 y es un tipo char, sólo podemos recibir un dato por recepción.
Utilizamos "if" para usar los datos de entrada, si es orden de movimiento
podemos regresar un mensaje de error, en caso de seleccionar un motor
mandaremos llamar un método selector motor
if(data1 == '1'){
Serial.write("0");
}
if(data1 == '2'){
Serial.write("0");
}
else{
selectormotor(data1);
}
Siguiendo la información del dato recibido ejecutamos el proceso adecuado
que controla un motor en particular.
Debemos crear 5 métodos, es decir, un método para cada servo. Los nombres
serán: servo1, servo2, servo3, servo4 y servo5 respectivamente.
El cuerpo de estos procesos será muy similar. Cada uno de ellos contiene un
ciclo infinito para poder ejecutar más de un movimiento, se obtiene el dato de
entrada y se ocupa la condicional "IF" para saber el movimiento a realizar.
Para el dato 1 o 2 procede a hacer rotación. Ésta se realiza de un modo suave
desplazándose 2 grados en cada paso como se muestra a continuación:
delay(2);
while(1){
comprobación();
data2 = Serial.read();
}
if(data2 == '1'){
}
if(motor1_pos < max){
for(i=0;i<N;i++){
motor1_pos +=2;
}
if(data2 == '2'){
if(motor1_pos > min){
miservo1.write(motor1_pos);
for(i=0;i<N;i++){
7
}
motor1_pos -=2;
}
miservo1.write(motor1_pos);
else{
delay(2);
selectormotor(data2);
comprobación();
}
}
}
Lo anterior contempla el ejemplo de mover 10 grados un servo. Estas líneas se
deben repetir en cada subproceso servo.
Mostramos el código para el programa que controla los servos en la chip kit
Uno32.
#include <Servo.h>
pinMode(salida,OUTPUT);
int N=5;
digitalWrite(salida,HIGH);
char data1;
miservo1.attach(m1);
char data2;
miservo2.attach(m2);
int motor1_pos = 0;
miservo3.attach(m3);
int motor2_pos = 0;
miservo4.attach(m4);
int motor3_pos = 0;
miservo5.attach(m5);
int motor4_pos = 0;
miservo1.write(motor1_pos);
int motor5_pos = 0;
miservo2.write(motor2_pos);
int m1 = 2;
miservo3.write(motor3_pos);
int m2 = 3;
miservo4.write(motor4_pos);
int m3 = 4;
miservo5.write(motor5_pos);
int m4 = 5;
int m5 = 6;
}
int max = 180;
void loop(){
int min = 0;
data1 = Serial.read();
int salida = 13;
if(data1 == '1'){
Serial.write("0");
Servo miservo1;
Servo miservo2;
}
Servo miservo3;
if(data1 == '2'){
Serial.write("0");
Servo miservo4;
}
Servo miservo5;
else{
selectormotor(data1);
}
void setup(){
}
void servo1(){
Serial.begin(9600);
int i;
8
comprobación();
while(1){
data2 = Serial.read();
}
if(data2 == '1'){
}
if(motor1_pos < max){
}
for(i=0;i<N;i++){
if(data2 =='2'){
motor1_pos +=2;
if(motor2_pos > min){
miservo1.write(motor1_pos);
for(i=0;i<N;i++){
delay(2);
motor2_pos -=2;
comprobación();
miservo2.write(motor2_pos);
}
delay(2);
}
comprobación();
}
if(data2 == '2'){
}
if(motor1_pos > min){
}
for(i=0;i<N;i++){
}
motor1_pos -=2;
else{
miservo1.write(motor1_pos);
selectormotor(data2);
delay(2);
comprobación();
}
}
}
}
}
}
else{
void servo3(){
selectormotor(data2);
int i;
while(1){
}
data2 = Serial.read();
}
if(data2 == '1'){
}
if(motor3_pos < max){
void servo2(){
for(i=0;i<N;i++){
motor3_pos +=2;
while(1){
miservo3.write(motor3_pos);
int i;
data2 = Serial.read();
delay(2);
if(data2 == '1'){
comprobación();
if(motor2_pos < max){
}
for(i=0;i<N;i++){
}
motor2_pos+=2;
}
miservo2.write(motor2_pos);
if(data2 =='2'){
delay(2);
9
}
if(motor3_pos > min){
}
for(i=0;i<N;i++){
}
motor3_pos -=2;
else{
miservo3.write(motor3_pos);
selectormotor(data2);
delay(2);
comprobación();
}
}
}
}
}
void servo5(){
}
int i;
else{
while(1){
selectormotor(data2);
data2 = Serial.read();
if(data2 == '1'){
}
if(motor5_pos < max){
}
for(i=0;i<N;i++){
}
motor5_pos +=2;
void servo4(){
miservo5.write(motor5_pos);
int i;
delay(2);
while(1){
comprobación();
data2 = Serial.read();
if(data2 == '1'){
}
if(motor4_pos < max){
}
for(i=0;i<N;i++){
motor4_pos +=2;
}
if(data2 =='2'){
miservo4.write(motor4_pos);
if(motor5_pos > min){
delay(2);
for(i=0;i<N;i++){
comprobación();
motor5_pos -=2;
miservo5.write(motor5_pos);
}
delay(2);
}
comprobación();
}
if(data2 =='2'){
}
if(motor4_pos > min){
}
for(i=0;i<N;i++){
motor4_pos -=2;
}
else{
miservo4.write(motor4_pos);
selectormotor(data2);
delay(2);
comprobación();
}
10
break;
}
case '7':
}
servo5();
void selectormotor(char id){
break;
switch(id){
}
case '3':
servo1();
break;
}
void comprobación(){
int i;
case '4':
for(i=0; i<10; i++){
servo2();
digitalWrite(salida,LOW);
break;
delay(20);
case '5':
digitalWrite(salida,HIGH);
servo3();
delay(20);
break;
}
case '6':
servo4();
}
Los métodos que contemplamos son
•
•
•
Movimiento del servo
Selección de servo
Comprobación
Este último envía la señal de confirmación
Procedemos a conectar todos los dispositivos. La placa dispone de puertos de
VCC (corriente) y GND (tierra). La tarjeta se conecta como se muestra a
continuación.
11
La configuración del voltaje de la placa es un paso impostarte cuyo fin es que
las conexiones funcionen, el puerto bluetooth funciona con 3.3v o 5v. El servo
motor, se alimenta de un amperaje mayor al de la placa y por ello debe conectarse
a corriente extra.
12
Programación Android
Para esto ocupamos la versión 2.2 o posteriores, la programación se realiza en
Eclipse IDE, este es libre (sin licencia) y se puede descargar de la página
http://www.eclipse.org/downloads/ donde existen varias versiones.
No requiere instalación. En el directorio hay un archivo ejecutable, el cual se
encargará de la instalación.
Debemos instalar previamente la versión del JDK de Java que podemos
encontrar http://www.oracle.com/technetwork/java/javase/downloads/index.html
Otro requisito será instalar los elementos necesarios para programar en
Android.
Comenzamos la explicación de instalar el SDK de Android en eclipse.
Hacemos un clic en el menú Help y seleccionamos Install new software así
saldrá una ventana como la que sigue
Al Seleccionar Add aparecerá la ventana siguiente:
13
Ponemos el Plugin a instalar Android-SDK, y proporcionaremos una dirección
para que este la descargue e instale, https://dl-ssl.google.com/android/eclipse/.
El sistema muestra lo siguiente:
Selecciona OK. Aparecen dos opciones que hay que seleccionar, para instalar
el Plugin de Android, quedando la siguiente ventana:
14
Hacemos clic en el botón Next, hasta terminar con el proceso de instalación.
Una vez concluido el proceso será necesario reiniciar el IDE Eclipse. La
ventana siguiente es para instalar las herramientas y obtener lo necesario para
programar en versiones de Android hasta 4.1.
Seleccionamos el menú Window y la opción Android SDK manager aparece la
pantalla siguiente:
15
En esta podemos seleccionar las SDK Platform, plataformas de diferentes
versiones de Android, debemos contar con estas para usar las herramientas y
opciones de las últimas versiones de Android.
Con esto terminamos la instalación. Ahora procedemos a realizar la aplicación
para poder lograr una conexión Bluetooth y enviar datos que se registren en
puerto de arduino.
Seleccionamos el menú file, opción new. Aparece la ventana siguiente:
Selecciona Android Application Project, esta opción crea una proyecto de una
aplicación Android y muestra la siguiente ventana
16
En esta ventana debemos proporcionar un nombre así como una versión
mínima de Android para usar la aplicación que vamos a crear seleccionamos
siguiente y aparece la ventana siguiente:
En esta pantalla se puede personalizar el tipo de imagen y el tamaño que
tendrá nuestra aplicación como icono para ser llamado, los que son valores dados
por omisión usan las caritas mismas que pueden cambiar de color.
17
En el siguiente paso aparece la ventana siguiente:
En esta opción podemos cambiar el nombre a la actividad esta es la que
aparece en las siguientes carpetas, como el nombre que tendrá el acceso de la
aplicación, por último presionamos Finish y aparece nuestro proyecto en el
explorador de paquetes
Aparece esta ventana donde se crea el proyecto.
18
La carpeta tiene archivos que explicaremos paso a paso.
Uno de los más importantes, AndroidMainfest.xml es un archivo principal del
proyecto. En él se alojan los permisos para usar las diferentes herramientas, como
nombres de Layout. Los identificadores de estas y los nombres de las actividades.
Se recomienda que este no se altere más de lo necesario, ya que puede causar
errores que serán difíciles de encontrar.
A este debemos agregar las líneas para el permiso de trabajar con dispositivos
Bluetooth y lograr la conexión.
<uses-permission
android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
Estas líneas garantizan que podemos trabajar con adaptadores Bluetooth.
Para el uso del acelerómetro no se requieren permisos adicionales.
La carpeta siguiente es la carpeta Res. En esta habrá varias carpetas como se
muestra en la siguiente imagen:
Las importantes son layout y valúes, en layout se encuentran las ventanas de
salida, las que mostrará nuestra aplicación, se crean tantos archivos layout como
vistas deseamos mostrar, la forma de crear los layout es con clic en el botón
derecho sobre la carpeta layout, seleccionando new other y aparece la ventana
siguiente:
19
Seleccionamos Android XML Layout file, posteriormente hay que dar el
nombre con el cual se conocerá el layout.
Tendiendo las dos vistas que necesitamos, debemos agregar botones y
algunas herramientas. Contaremos con 7 botones como se muestra en la imagen,
así también con un list view para los mensajes del control de la aplicación.
20
Se deberá disponer de otro layout para el menú para que podamos mostrar
todas las conexiones posibles como lo muestra la siguiente imagen:
Esta contiene un list view que sirve para mostrar la lista de los dispositivos que
están vinculados previamente. Con esto programamos el cuerpo de la aplicación
Nos ubicamos en la carpeta SRC es donde se encuentran los archivos de
android java proyecto que será una imagen como la siguiente:
21
En la imagen ubicamos y abrimos el archivo ConexionBluetooth.java esta está
vinculada al layout main.xml que es la principal ventana que se ejecuta cuando
abre la aplicación. Todo lo que realicemos sobre el archivo se ejecuta al inicio de
la aplicación si lo deseamos.
Empezamos a definir las variables globales necesarias para la aplicación.
int curX =0,prevX=0;
int curY=0,prevY=0;
int curZ=0,prevZ=0;
//variables para identificar
movimiento en un tiempo
long
last_update=0,last_movement=0;
private static final String TAG
= "BluetoothChat";
private static final Boolean D =
true;
// tipos de mensaje
public static final int
MESSAGE_STATE_CHANGE = 1;
public static final int
MESSAGE_READ = 2;
public static final int
MESSAGE_WRITE = 3;
public static final int
MESSAGE_DEVICE_NAME = 4;
public static final int
MESSAGE_TOAST = 5;
public static final String
DEVICE_NAME = "device_name";
public static final String TOAST
= "toast";
private static final int
REQUEST_CONNECT_DEVICE = 1;
private static final int
REQUEST_ENABLE_BT = 2;
// la vistas
private TextView mTitle;
private ListView
mConversationView;
//variables de los botones que
controlan y envían
private Button btn_r;
private Button btn_l;
private ToggleButton Servo_1;
private ToggleButton Servo_2;
private ToggleButton Servo_3;
private ToggleButton Servo_4;
private ToggleButton Servo_5;
private int motor_accionado =0;
Integer valor = 0;
private String
mConnectedDeviceName = null;
private ArrayAdapter<String>
mConversationArrayAdapter;
private StringBuffer
mOutStringBuffer;
private BluetoothAdapter
mBluetoothAdapter = null;
private
ConexionBluetoothService
mChatService = null;
Para que se ejecute cuando la aplicación abra sobrescribimos el método
ONSTAR, queda como sigue:
22
public void onStart() {
super.onStart();
if(D) Log.e(TAG, "++ ON START ++");
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
} else {
if (mChatService == null) setupChat();
}
}
Verificamos si hay puerto bluetooth en el móvil, posteriormente hacemos la
activación con el objeto intent luego con uso del starActivityforResult, en este se
pasa como parámetro un intent y una constante que es la necesaria para verificar
si la conexión está activada, después se pone un texto de activación del puerto
Bluetooth del móvil.
Crearemos el menú de opciones con las siguientes líneas.
public Boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.option_menu, menu);
return true;
}
Con esto hacemos que el botón menú tenga función. Si no se declara esto por
más que se oprima no realizará ninguna acción, esto igual para las versiones 4.2
de Android, en las líneas hacemos que el botón aparezca en la aplicación.
public Boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch(item.getItemId()){
case R.id.menu_conexiones:
Intent about = new Intent(this, MenuActivity.class);
startActivity(about);
return true;
}
return false;
}
Seleccionando menú ejecuta la vista activity_conexion_android, para esta se
crea un proyecto java android, lo llamaremos MenuActivity.java, se realiza la
programación para mostrar los bluetooth previamente vinculados al móvil.
23
Pasamos a la creación de MenuActivity.java, mencionamos las variables más
importantes:
private final BluetoothAdapter mAdapter;
mAdapter es de tipo bluetoothAdapter. Es un objeto que tiene los métodos
para conectar y activar los puertos Bluetooth
El siguiente método onCreate, se inicializa al momento de acceder a Device, la
que muestra las conexiones previamente vinculadas.
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_
INDETERMINATE_PROGRESS);
setContentView(R.layout.device_list)
;
setResult(Activity.RESULT_CANCELED);
Button scanButton = (Button)
findViewById(R.id.button_scan);
scanButton.setOnClickListener(new
OnClickListener() {
public void onClick(View
v) {
doDiscovery();
v.setVisibility(View.GONE);
}
});
mPairedDevicesArrayAdapter =
new ArrayAdapter<String>(this,
R.layout.device_name);
mNewDevicesArrayAdapter =
new ArrayAdapter<String>(this,
R.layout.device_name);
ListView pairedListView =
(ListView)
findViewById(R.id.paired_devices);
pairedListView.setAdapter(mPairedDev
icesArrayAdapter);
pairedListView.setOnItemClickListene
r(mDeviceClickListener);
ListView newDevicesListView
= (ListView)
findViewById(R.id.new_devices);
newDevicesListView.setAdapter(mNewDe
vicesArrayAdapter);
newDevicesListView.setOnItemClickLis
tener(mDeviceClickListener);
IntentFilter filter = new
IntentFilter(BluetoothDevice.ACTION_
FOUND);
this.registerReceiver(mReceiver,
filter);
filter = new
IntentFilter(BluetoothAdapter.ACTION
_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver,
filter);
mBtAdapter =
BluetoothAdapter.getDefaultAdapter()
;
Set<BluetoothDevice>
pairedDevices =
mBtAdapter.getBondedDevices();
if (pairedDevices.size() >
0) {
findViewById(R.id.title_paired_devic
es).setVisibility(View.VISIBLE);
for (BluetoothDevice
device : pairedDevices) {
mPairedDevicesArrayAdapter.add(devic
24
e.getName() + "\n" +
device.getAddress());
}
} else {
String noDevices =
getResources().getText(R.string.none
_paired).toString();
mPairedDevicesArrayAdapter.add(noDev
ices);
}
}
Lo anterior realiza un llenado de un array con datos de los puertos que están
vinculados al móvil. Los muestra en orden en un listview. Obtenida la lista creamos
un setonitemclicklistener que es el método que escucha cuando seleccionamos
una opción, se actualización los datos para la conexión. Esta se realiza por hilos
sincronizados, se extiende de thread y debe tener métodos de run, para que su
ejecución.
private class ConnectedThread
extends Thread {
private final
BluetoothSocket mmSocket;
private final InputStream
mainstream;
private final OutputStream
mmOutStream;
public
ConnectedThread(BluetoothSocket
socket) {
Log.d(TAG, "create
ConnectedThread");
mmSocket = socket;
InputStream tmpIn =
null;
OutputStream tmpOut =
null;
try {
tmpIn =
socket.getInputStream();
tmpOut =
socket.getOutputStream();
} catch (IOException e)
{
Log.e(TAG, "temp
sockets not created", e);
}
}
mainstream = tmpIn;
mmOutStream = tmpOut;
public void run() {
Log.i(TAG, "BEGIN
mConnectedThread");
byte[] buffer = new
byte[1024];
int bytes;
while (true) {
try {
bytes = mmInStream.read(buffer);
mHandler.obtainMessage(ConexionBluet
ooth.MESSAGE_READ, bytes, -1,
buffer)
.sendToTarget();
e) {
} catch (IOException
"disconnected", e);
connectionLost();
}
}
Log.e(TAG,
break;
}
Esto crea la conexión y también crea el buffer de entrada y salida para el envío
de datos. Creamos los clic listener de los botones que envían una señal cuando el
usuario da clic en algún botón de la aplicación.
btn_r = (Button)
findViewById(R.id.btn_der);
btn_r.setOnClickListener(new
OnClickListener() {
25
public void
onClick(View v) {
sendMessage("1");
}
});
btn_l = (Button)
findViewById(R.id.btn_izq);
btn_l.setOnClickListener(new
OnClickListener() {
onClick(View v) {
public void
sendMessage("2");
}
});
Servo_1 = (ToggleButton)
findViewById(R.id.Servo_1);
Servo_1.setOnClickListener(new
View.OnClickListener() {
onClick(View v) {
public void
if(Servo_1.isChecked()){
limpiarmotor(motor_accionado);
sendMessage("3");
}
});
Servo_3 = (ToggleButton)
findViewById(R.id.Servo_3);
Servo_3.setOnClickListener(new
View.OnClickListener() {
onClick(View v) {
limpiarmotor(motor_accionado);
sendMessage("5");
motor_accionado = 3;
}
}
});
Servo_4 = (ToggleButton)
findViewById(R.id.Servo_4);
Servo_4.setOnClickListener(new
View.OnClickListener() {
v) {
public void
onClick(View v) {
if(Servo_2.isChecked()){
limpiarmotor(motor_accionado);
public void onClick(View
if(Servo_4.isChecked()){
limpiarmotor(motor_accionado);
}
Servo_2.setOnClickListener(new
View.OnClickListener() {
public void
if(Servo_3.isChecked()){
motor_accionado = 1;
}
});
Servo_2 = (ToggleButton)
findViewById(R.id.Servo_2);
}
sendMessage("6");
motor_accionado = 4;
}
}
});
Servo_5 = (ToggleButton)
findViewById(R.id.Servo_5);
Servo_5.setOnClickListener(new
View.OnClickListener() {
v) {
public void onClick(View
if(Servo_5.isChecked()){
sendMessage("4");
limpiarmotor(motor_accionado);
motor_accionado = 2;
sendMessage("7");
26
motor_accionado = 5;
}
}
});
Envían cada dato usando sendMessage(). Otra acción que realiza es la
condición if(servo_i.ischecked) es para no realizar alguna acción cuando el botón
se encuentra apagado solo cuando esta encendido.
Otra variable es motor_accionado con ella registramos las acciones de los
botones, para reiniciarla usamos el proceso limpiarmotor.
void limpiarmotor(int motor){
switch (motor) {
case 1:
Servo_1.setChecked(false);
break;
case 2:
Servo_2.setChecked(false);
break;
case 3:
Servo_3.setChecked(false);
break;
case 4:
Servo_4.setChecked(false);
break;
case 5:
Servo_5.setChecked(false);
break;
default:
break;
}
}
Los botones que usan el método sendMessage, envían datos previamente
seleccionamos en coordinación con Arduino para mover los servo-motores.
private void sendMessage(String message) {
if (mChatService.getState() != ConexionBluetoothService.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected,
Toast.LENGTH_SHORT).show();
return;
}
if (message.length() > 0) {
byte[] send = message.getBytes();
mChatService.write(send);
mOutStringBuffer.setLength(0);
}
}
Al completar la conexión con arduino contamos con dos vías de comunicación
entrada y salida, por lo que hay comunicación constante confirmando o enviado
errores. Estos mensajes se muestran en las líneas siguientes:
byte[] readBuf = (byte[]) msg.obj;
String readMessage = new String(readBuf, 0, msg.arg1);
mConversationArrayAdapter.add(mConnectedDeviceName+": " + readMessage);
Con esto observamos el mensaje recibido en listview, muestra tanto los datos
enviados como los recibidos. En este punto realizado lo necesario para una
27
aplicación que conecta por Bluetooth y enviar datos necesario para mover servomotores.
Avanzamos un paso ampliamos la aplicación para enviar señales cuando se
activen acelerómetros dentro del dispositivo móvil en los tres ejes "x","y","z"
despacha una señal de movimiento, la selección del motor ocupamos los botones
como se hace normalmente. Empezamos implementando en la clase principal de
la siguiente manera:
public class ConexionBluetooth extends Activity implements
SensorEventListener.
Creamos los métodos necesarios que conllevan la implementación:
public void onAccuracyChanged(Sensor
sensor, int accuracy) {
}
public void
onSensorChanged(SensorEvent event) {
synchronized (this) {
}
long current_time =
event.timestamp;
curX = (int)
event.values[0];
curY = (int)
event.values[1];
curZ = (int)
event.values[2];
if (prevX == 0 && prevY == 0
&& prevZ == 0) {
last_update =
current_time;
last_movement =
current_time;
prevX = curX;
prevY = curY;
prevZ = curZ;
}
long time_difference =
current_time - last_update;
if (time_difference > 0) {
float movement =
Math.abs((curX + curY + curZ) -
(prevX - prevY - prevZ)) /
time_difference;
int limit = 2000;
float min_movement = 1;
if (movement >
min_movement) {
if (current_time last_movement >= limit) {
Toast.makeText(getApplicationContext
(), "Hay movimiento de " + movement,
Toast.LENGTH_SHORT).show();
}
last_movement =
current_time;
}
prevX = curX;
prevY = curY;
prevZ = curZ;
last_update =
current_time;
}
if(curX>3){
sendMessage("1");
}
if(curY>3){
sendMessage("2");
}
}
El único modificamos es onSensorChanged. en el cual las variables permiten
checar movimiento en los sensores, prev almacena el valor del eje x en cualquier
momento, cur guarda el dato del mismo eje después de algún tiempo. La variable
de tiempo current_time es la que determina el espacio cuando se graban las
variables prev y cur las que checan el tiempo es last_update y last_movement.
28
Cuando hay diferencia entre los valores de tiempo, se revisan cambios en los
valores de los ejes si existe se actualiza prev=cur, limit es la que indica la
sensibilidad de los sensores. Existen condicionantes por si hay cambios en cur o
llega a un valor se manda movimiento del motor.
En el sensor Z es difícil de obtener una alteración de este, por el modo del
dispositivo.
Debemos sobrescribir el método onStop para cuando se termina de usar la
aplicación también se apaguen los sensores.
public void onStop() {
super.onStop();
SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
sm.unregisterListener(this);
if(D) Log.e(TAG, "-- ON STOP --");
}
29
Resultados
Se concluyó la primera aplicación que sólo mueve a los servo-motores por
medio de botones y, posteriormente, se realizó otra versión par el uso de los
sensores.
Es muy complicado crear una conexión permanente por lo que nos apoyamos
en ejemplos libres de Android como el Bluetooth chat, porque estos códigos son
libres.
En la parte de Arduino realizamos una gran cantidad de pruebas y concluimos
que es mejor mover los motores de pocos grados; se realizó en ciclo para mover 2
grados a la vez.
Es un proyecto muy divertido y agradable por la posibilidad de aprender
distintas tecnologías que están, en este momento, a la vanguardia.
Se encontraron bastantes problemas para hacer la conexión de estos
elementos, por lo tipos de puertos y la tecnología de HC06 que es el puerto
Bluetooth con el que se trabajó, la conexión a la placa Arduino es cruzada lo que
quiere decir que la conexión Rx del Bluetooth debe conectarse en el Tx de la placa
Arduino y lo mismo con el Tx del bluetooth. En esta parte del proyecto se tomó
mucho tiempo por los problemas de conexión. Así mismo nos encontramos otros
problemas en el proceso de lograr la conexión de envío y recepción de los datos.
Se tuvieron problemas al momento de declarar las variables de Arduino y
realizar la lectura de los datos de entrada. Una vez resuelto esto, se procedió a la
programación en donde también se presentaron algunos detalles en la parte de
visualizar la forma de controlar un motor y posteriormente seleccionar otro servo
sin que se perdiera la posición del servo anterior, y que el nuevo servo
seleccionado no escribiera la posición del servo anterior. Al final todo se solucionó
y se logró el objetivo
30
Conclusiones
Se logró el objetivo de poder mover los motores por medio de la ayuda de los
acelerómetros de los teléfonos inteligentes o las Tabletas.
El problema que tuvimos que resolver fue accionar en una forma continua los
motores, que estos no realicen brincos de muchos grados, encontrar una forma de
que el motor se mueva despacio y con firmeza.
Otro de los conflictos encontrados es la forma de enviar y recibir los datos que
se comparten entre la aplicación y la placa chip KIT, ya que solo se realizó el
trabajo para controlar 5 motores no hubo inconveniente de mandar números, pero
si fueran 100 o 1000 motores se tendría que hacer alguna modificación para
recibir y enviar más de un dato en conjunto.
Bibliografía
http://www.slideshare.net/ykro/trabajando-con-acelermetros-enandroid#btnNext
http://www.sgoliver.net/blog/?p=1363
http://www.maestrosdelweb.com/editorial/curso-android-sensores-trabajar-conacelerometro/
http://www.flu-project.com/curso-de-introduccion-a-android-ii-creando-nuestraprimera-aplicacion.html
http://androideity.com/2012/08/05/sockets-en-android/
http://tcrobotics.blogspot.mx/2011/05/tutorial-arduino-uno-adk-degoogle.html#more
http://www.arduino.cc/
El Gran Libro de Android, de Tomás Gironés, Jesús, Editorial MARCOMBO,
S.A.
ANDROID - CURSO PRÁCTICO PARA TODO LOS NIVELES, de MUñIZ
TROYANO, Editorial Alfaomega, Altaria Editorial
COMO PROGRAMAR EN JAVA, de PAUL J. DEITEL, Editorial PEARSON
31
ELGRAN LIBRO DE ANDROID AVANZADO, de JESUS TOMAS, Editorial
ALFAOMEGA GRUPO EDITOR
ANDROID: DESARROLLO DE APLICACIONES GANADORAS, de LEE WEI
MENG, Editorial ANAYA MULTIMEDIA
32
Anexo
Código de Android
package
com.example.android.BluetoothChat;
import java.util.List;
import
android.annotation.SuppressLint;
import android.app.Activity;
import
android.bluetooth.BluetoothAdapter;
import
android.bluetooth.BluetoothDevice;
import android.content.Intent;
import
android.content.pm.ActivityInfo;
import android.hardware.Sensor;
import
android.hardware.SensorEvent;
import
android.hardware.SensorEventListen
er;
import
android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import
android.view.View.OnClickListener;
import
android.view.inputmethod.EditorInfo;
import
android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import
android.widget.ToggleButton;
@SuppressLint({ "NewApi",
"NewApi", "NewApi" })
public class ConexionBluetooth
extends Activity implements
SensorEventListener {
//variables para el
acelerometro
int curX =0,prevX=0;
int curY=0,prevY=0;
int curZ=0,prevZ=0;
//variables para identificar
movimiento en un tiempo
long
last_update=0,last_movement=0;
private static final String TAG =
"BluetoothChat";
private static final boolean D =
true;
// tipos de mensaje
public static final int
MESSAGE_STATE_CHANGE = 1;
public static final int
MESSAGE_READ = 2;
public static final int
MESSAGE_WRITE = 3;
public static final int
MESSAGE_DEVICE_NAME = 4;
public static final int
MESSAGE_TOAST = 5;
// Key names received from the
BluetoothChatService Handler
public static final String
DEVICE_NAME = "device_name";
public static final String TOAST
= "toast";
// Intent request codes
private static final int
REQUEST_CONNECT_DEVICE = 1;
33
private static final int
REQUEST_ENABLE_BT = 2;
// las vistas
private TextView mTitle;
private ListView
mConversationView;
//variables de los botones
que controlan y envian
private Button btn_r;
private Button btn_l;
private ToggleButton Servo_1;
private ToggleButton Servo_2;
private ToggleButton Servo_3;
private ToggleButton Servo_4;
private ToggleButton Servo_5;
private int motor_accionado =0;
Integer valor = 0;
private String
mConnectedDeviceName = null;
conversation thread
private ArrayAdapter<String>
mConversationArrayAdapter;
messages
private StringBuffer
mOutStringBuffer;
private BluetoothAdapter
mBluetoothAdapter = null;
private
ConexionBluetoothService
mChatService = null;
@Override
public void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRequestedOrientation(ActivityI
nfo.SCREEN_ORIENTATION_PORT
RAIT);
if(D) Log.e(TAG, "+++ ON
CREATE +++");
// Set up the window layout
requestWindowFeature(Window.FEA
TURE_CUSTOM_TITLE);
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.F
EATURE_CUSTOM_TITLE,
R.layout.custom_title);
mTitle = (TextView)
findViewById(R.id.title_left_text);
mTitle.setText(R.string.app_name);
mTitle = (TextView)
findViewById(R.id.title_right_text);
mBluetoothAdapter =
BluetoothAdapter.getDefaultAdapter()
;
Bluetooth is not supported
if (mBluetoothAdapter ==
null) {
Toast.makeText(this,
"Bluetooth is not available",
Toast.LENGTH_LONG).show();
finish();
return;
}
}
@Override
public void onStart() {
super.onStart();
if(D) Log.e(TAG, "++ ON
START ++");
// If BT is not on, request that
it be enabled.
if
(!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new
Intent(BluetoothAdapter.ACTION_RE
QUEST_ENABLE);
startActivityForResult(enableIntent,
REQUEST_ENABLE_BT);
// Otherwise, setup the chat
session
} else {
if (mChatService == null)
setupChat();
}
34
}
@Override//metodo para poder
accionar los sensores del inicio
public synchronized void
onResume() {
super.onResume();
SensorManager sm =
(SensorManager)
getSystemService(SENSOR_SERVIC
E);
List<Sensor> sensors =
sm.getSensorList(Sensor.TYPE_ACC
ELEROMETER);
if (sensors.size() > 0) {
sm.registerListener(this,
sensors.get(0),
SensorManager.SENSOR_DELAY_G
AME);
}
if(D) Log.e(TAG, "+ ON
RESUME +");
// Performing this check in
onResume() covers the case in which
BT was
// not enabled during
onStart(), so we were paused to
enable it...
// onResume() will be called
when ACTION_REQUEST_ENABLE
activity returns.
if (mChatService != null) {
// Only if the state is
STATE_NONE, do we know that we
haven't started already
if
(mChatService.getState() ==
ConexionBluetoothService.STATE_N
ONE) {
// Start the Bluetooth chat
services
mChatService.start();
}
}
}
private void setupChat() {
Log.d(TAG, "setupChat()");
// Initialize the array adapter
for the conversation thread
mConversationArrayAdapter
= new ArrayAdapter<String>(this,
R.layout.message);
mConversationView =
(ListView) findViewById(R.id.in);
mConversationView.setAdapter(mCo
nversationArrayAdapter);
/*
// Initialize the compose field
with a listener for the return key
mOutEditText = (EditText)
findViewById(R.id.edit_text_out);
mOutEditText.setOnEditorActionListe
ner(mWriteListener);
// Initialize the send button
with a listener that for click events
mSendButton = (Button)
findViewById(R.id.button_send);
mSendButton.setOnClickListener(new
OnClickListener() {
public void onClick(View v)
{
// Send a message
using content of the edit text widget
TextView view =
(TextView)
findViewById(R.id.edit_text_out);
String message =
view.getText().toString();
sendMessage(message);
}
});*/
btn_r = (Button)
findViewById(R.id.btn_der);
35
}
btn_r.setOnClickListener(new
OnClickListener() {
public void
onClick(View v) {
// TODO
Auto-generated method stub
}
});
Servo_2 = (ToggleButton)
findViewById(R.id.Servo_2);
Servo_2.setOnClickListener(new
View.OnClickListener() {
sendMessage("1");
public void
}
});
btn_l = (Button)
findViewById(R.id.btn_izq);
btn_l.setOnClickListener(new
OnClickListener() {
onClick(View v) {
// TODO
Auto-generated method stub
if(Servo_2.isChecked()){
limpiarmotor(motor_accionado)
public void
;
onClick(View v) {
sendMessage("4");
// TODO
Auto-generated method stub
motor_accionado = 2;
sendMessage("2");
}
});
Servo_1 = (ToggleButton)
findViewById(R.id.Servo_1);
Servo_1.setOnClickListener(new
View.OnClickListener() {
}
}
});
Servo_3 = (ToggleButton)
findViewById(R.id.Servo_3);
Servo_3.setOnClickListener(new
View.OnClickListener() {
public void
public void
onClick(View v) {
// TODO
Auto-generated method stub
onClick(View v) {
// TODO
Auto-generated method stub
if(Servo_1.isChecked()){
if(Servo_3.isChecked()){
limpiarmotor(motor_accionado)
limpiarmotor(motor_accionado)
;
;
sendMessage("3");
sendMessage("5");
motor_accionado = 1;
motor_accionado = 3;
}
36
}
});
Servo_4 = (ToggleButton)
findViewById(R.id.Servo_4);
Servo_4.setOnClickListener(new
View.OnClickListener() {
public void onClick(View
v) {
// TODO Autogenerated method stub
// Initialize the
BluetoothChatService to perform
bluetooth connections
mChatService = new
ConexionBluetoothService(this,
mHandler);
// Initialize the buffer for
outgoing messages
mOutStringBuffer = new
StringBuffer("");
}
if(Servo_4.isChecked()){
limpiarmotor(motor_accionado)
;
sendMessage("6");
motor_accionado = 4;
}
}
});
Servo_5 = (ToggleButton)
findViewById(R.id.Servo_5);
Servo_5.setOnClickListener(new
View.OnClickListener() {
public void onClick(View
v) {
// TODO Autogenerated method stub
@Override
public synchronized void
onPause() {
super.onPause();
if(D) Log.e(TAG, "- ON
PAUSE -");
}
@Override//metodo para poder
detener los acelerometros y todo lo
de la aplicacion
public void onStop() {
super.onStop();
SensorManager sm =
(SensorManager)
getSystemService(SENSOR_SERVIC
E);
sm.unregisterListener(this);
if(D) Log.e(TAG, "-- ON
STOP --");
}
if(Servo_5.isChecked()){
limpiarmotor(motor_accionado)
;
sendMessage("7");
motor_accionado = 5;
}
}
});
@Override
public void onDestroy() {
super.onDestroy();
// Stop the Bluetooth chat
services
if (mChatService != null)
mChatService.stop();
if(D) Log.e(TAG, "--- ON
DESTROY ---");
}
37
private void
ensureDiscoverable() {
if(D) Log.d(TAG, "ensure
discoverable");
if
(mBluetoothAdapter.getScanMode()
!=
BluetoothAdapter.SCAN_MODE_CO
NNECTABLE_DISCOVERABLE) {
Intent discoverableIntent =
new
Intent(BluetoothAdapter.ACTION_RE
QUEST_DISCOVERABLE);
discoverableIntent.putExtra(Bluetooth
Adapter.EXTRA_DISCOVERABLE_D
URATION, 300);
startActivity(discoverableIntent);
}
}
/**
* Sends a message.
* @param message A string
of text to send.
*/
private void
sendMessage(String message) {
// Check that we're actually
connected before trying anything
if (mChatService.getState()
!=
ConexionBluetoothService.STATE_C
ONNECTED) {
Toast.makeText(this,
R.string.not_connected,
Toast.LENGTH_SHORT).show();
return;
}
// Check that there's actually
something to send
if (message.length() > 0) {
// Get the message bytes
and tell the BluetoothChatService to
write
byte[] send =
message.getBytes();
mChatService.write(send);
// Reset out string buffer to
zero and clear the edit text field
mOutStringBuffer.setLength(0);
//mOutEditText.setText(mOutStringBu
ffer);
}
}
// The action listener for the
EditText widget, to listen for the return
key
private
TextView.OnEditorActionListener
mWriteListener =
new
TextView.OnEditorActionListener() {
public boolean
onEditorAction(TextView view, int
actionId, KeyEvent event) {
// If the action is a key-up
event on the return key, send the
message
if (actionId ==
EditorInfo.IME_NULL &&
event.getAction() ==
KeyEvent.ACTION_UP) {
String message =
view.getText().toString();
sendMessage(message);
}
if(D) Log.i(TAG, "END
onEditorAction");
return true;
}
};
38
// The Handler that gets
information back from the
BluetoothChatService
private final Handler mHandler
= new Handler() {
@Override
public void
handleMessage(Message msg) {
switch (msg.what) {
case
MESSAGE_STATE_CHANGE:
if(D) Log.i(TAG,
"MESSAGE_STATE_CHANGE: " +
msg.arg1);
switch (msg.arg1) {
case
ConexionBluetoothService.STATE_C
ONNECTED:
mTitle.setText(R.string.title_connecte
d_to);
mTitle.append(mConnectedDeviceNa
me);
mConversationArrayAdapter.clear();
break;
case
ConexionBluetoothService.STATE_C
ONNECTING:
mTitle.setText(R.string.title_connectin
g);
break;
case
ConexionBluetoothService.STATE_LI
STEN:
case
ConexionBluetoothService.STATE_N
ONE:
mTitle.setText(R.string.title_not_conn
ected);
break;
}
break;
case MESSAGE_WRITE:
byte[] writeBuf = (byte[])
msg.obj;
// construct a string from
the buffer
String writeMessage =
new String(writeBuf);
mConversationArrayAdapter.add("Me:
" + writeMessage);
break;
case MESSAGE_READ:
byte[] readBuf = (byte[])
msg.obj;
// construct a string from
the valid bytes in the buffer
String readMessage =
new String(readBuf, 0, msg.arg1);
mConversationArrayAdapter.add(mC
onnectedDeviceName+": " +
readMessage);
break;
case
MESSAGE_DEVICE_NAME:
// save the connected
device's name
mConnectedDeviceName =
msg.getData().getString(DEVICE_NA
ME);
Toast.makeText(getApplicationConte
xt(), "Connected to "
+
mConnectedDeviceName,
Toast.LENGTH_SHORT).show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationConte
xt(), msg.getData().getString(TOAST),
Toast.LENGTH_SHORT).show();
break;
}
}
};
39
public void onActivityResult(int
requestCode, int resultCode, Intent
data) {
if(D) Log.d(TAG,
"onActivityResult " + resultCode);
switch (requestCode) {
case
REQUEST_CONNECT_DEVICE:
// When DeviceListActivity
returns with a device to connect
if (resultCode ==
Activity.RESULT_OK) {
// Get the device MAC
address
String address =
data.getExtras()
.getString(DeviceListActivity.EXTRA_
DEVICE_ADDRESS);
// Get the
BLuetoothDevice object
BluetoothDevice device
=
mBluetoothAdapter.getRemoteDevice
(address);
// Attempt to connect to
the device
mChatService.connect(device);
}
break;
case
REQUEST_ENABLE_BT:
// When the request to
enable Bluetooth returns
if (resultCode ==
Activity.RESULT_OK) {
// Bluetooth is now
enabled, so set up a chat session
setupChat();
} else {
// User did not enable
Bluetooth or an error occured
Log.d(TAG, "BT not
enabled");
Toast.makeText(this,
R.string.bt_not_enabled_leaving,
Toast.LENGTH_SHORT).show();
finish();
}
}
}
@Override
public boolean
onCreateOptionsMenu(Menu menu) {
MenuInflater inflater =
getMenuInflater();
inflater.inflate(R.menu.option_menu,
menu);
return true;
}
@Override
public boolean
onOptionsItemSelected(MenuItem
item) {
switch (item.getItemId()) {
case R.id.scan:
// Launch the
DeviceListActivity to see devices and
do scan
Intent serverIntent = new
Intent(this, DeviceListActivity.class);
startActivityForResult(serverIntent,
REQUEST_CONNECT_DEVICE);
return true;
case R.id.discoverable:
// Ensure this device is
discoverable by others
ensureDiscoverable();
return true;
}
return false;
}
void limpiarmotor(int motor){
switch (motor) {
case 1:
Servo_1.setChecked(false);
40
break;
case 2:
Servo_2.setChecked(false);
break;
case 3:
Servo_3.setChecked(false);
break;
case 4:
Servo_4.setChecked(false);
break;
case 5:
Servo_5.setChecked(false);
break;
default:
break;
}
}
public void
onAccuracyChanged(Sensor sensor,
int accuracy) {
// TODO Auto-generated
method stub
}
public void
onSensorChanged(SensorEvent
event) {
// TODO Auto-generated
method stub
synchronized (this) {
}
long current_time =
event.timestamp;
curX = (int)
event.values[0];
curY = (int) event.values[1];
curZ = (int) event.values[2];
if (prevX == 0 && prevY == 0
&& prevZ == 0) {
last_update =
current_time;
last_movement =
current_time;
prevX = curX;
prevY = curY;
prevZ = curZ;
}
long time_difference =
current_time - last_update;
if (time_difference > 0) {
float movement =
Math.abs((curX + curY + curZ) (prevX - prevY - prevZ)) /
time_difference;
int limit = 2000;
float min_movement = 1;
if (movement >
min_movement) {
if (current_time last_movement >= limit) {
Toast.makeText(getApplicationConte
xt(), "Hay movimiento de " +
movement,
Toast.LENGTH_SHORT).show();
}
last_movement =
current_time;
}
prevX = curX;
prevY = curY;
prevZ = curZ;
last_update =
current_time;
}
if(curX>3){
sendMessage("1");
}
if(curY>3){
sendMessage("2");
}
}
41
Codigo MPIDE
/* Programa realizado por
Oswaldo Santander
Este pretende realizar una
conexion bluetooth y llevar el control
de 5 servomotores guardando la
ultima posicion de cada servo, asi
tambien se intenta que el movimiento
de los servo sea progresivo que
no se llegue a la posicion de un golpe
*/
#include <Servo.h>
int N=5;
char data1;
char data2;
int motor1_pos = 0;
int motor2_pos = 0;
int motor3_pos = 0;
int motor4_pos = 0;
int motor5_pos = 0;
int m1 = 2;
int m2 = 3;
int m3 = 4;
int m4 = 5;
int m5 = 6;
int max = 180;
int min = 0;
int salida = 13;
Servo miservo1;
Servo miservo2;
Servo miservo3;
Servo miservo4;
Servo miservo5;
void setup(){
Serial.begin(9600);
pinMode(salida,OUTPUT);
digitalWrite(salida,HIGH);
miservo1.attach(m1);
miservo2.attach(m2);
miservo3.attach(m3);
miservo4.attach(m4);
miservo5.attach(m5);
miservo1.write(motor1_pos);
miservo2.write(motor2_pos);
miservo3.write(motor3_pos);
miservo4.write(motor4_pos);
miservo5.write(motor5_pos);
}
void loop(){
data1 = Serial.read();
if(data1 == '1'){
Serial.write("0");
}
if(data1 == '2'){
Serial.write("0");
}
else{
selectormotor(data1);
}
}
void servo1(){
int i;
while(1){
data2 = Serial.read();
if(data2 == '1'){
if(motor1_pos < max){
for(i=0;i<N;i++){
motor1_pos +=2;
miservo1.write(motor1_pos);
delay(2);
comprobacion();
}
}
}
if(data2 == '2'){
if(motor1_pos > min){
for(i=0;i<N;i++){
motor1_pos -=2;
miservo1.write(motor1_pos);
delay(2);
comprobacion();
}
}
42
}
else{
selectormotor(data2);
if(data2 == '1'){
if(motor3_pos < max){
for(i=0;i<N;i++){
motor3_pos +=2;
}
}
}
void servo2(){
while(1){
int i;
data2 = Serial.read();
if(data2 == '1'){
if(motor2_pos < max){
for(i=0;i<N;i++){
motor2_pos+=2;
miservo2.write(motor2_pos);
delay(2);
comprobacion();
miservo3.write(motor3_pos);
delay(2);
comprobacion();
}
}
}
if(data2 =='2'){
if(motor3_pos > min){
for(i=0;i<N;i++){
motor3_pos -=2;
miservo3.write(motor3_pos);
delay(2);
comprobacion();
}
}
}
}
if(data2 =='2'){
if(motor2_pos > min){
for(i=0;i<N;i++){
motor2_pos -=2;
miservo2.write(motor2_pos);
delay(2);
comprobacion();
}
}
}
else{
selectormotor(data2);
}
}
}
void servo3(){
int i;
while(1){
data2 = Serial.read();
}
}
else{
selectormotor(data2);
}
}
}
void servo4(){
int i;
while(1){
data2 = Serial.read();
if(data2 == '1'){
if(motor4_pos < max){
for(i=0;i<N;i++){
motor4_pos +=2;
miservo4.write(motor4_pos);
delay(2);
comprobacion();
}
}
}
if(data2 =='2'){
43
if(motor4_pos > min){
for(i=0;i<N;i++){
motor4_pos -=2;
miservo4.write(motor4_pos);
delay(2);
comprobacion();
}
}
}
else{
selectormotor(data2);
}
}
}
void servo5(){
int i;
while(1){
data2 = Serial.read();
if(data2 == '1'){
if(motor5_pos < max){
for(i=0;i<N;i++){
motor5_pos +=2;
miservo5.write(motor5_pos);
delay(2);
comprobacion();
}
}
}
if(data2 =='2'){
if(motor5_pos > min){
for(i=0;i<N;i++){
motor5_pos -=2;
}
}
}
void selectormotor(char id){
switch(id){
case '3':
servo1();
break;
case '4':
servo2();
break;
case '5':
servo3();
break;
case '6':
servo4();
break;
case '7':
servo5();
break;
}
}
void comprobacion(){
int i;
for(i=0; i<10; i++){
digitalWrite(salida,LOW);
delay(20);
digitalWrite(salida,HIGH);
delay(20);
}
}
miservo5.write(motor5_pos);
delay(2);
comprobacion();
}
}
}
else{
selectormotor(data2);
44
Descargar