2011-11-02 14 views
25

Estoy trabajando con algunos estudiantes de mi universidad en el desarrollo de una aplicación Bluetooth Android simple que se utilizará para comunicación en serie (RFCOMM) a un microcontrolador Arduino con un módulo Bluetooth conectado.¿Cómo puedo conectar correctamente una aplicación de Android a un socket RFCOMM en un microcontrolador Arduino habilitado para Bluetooth?

Que yo sepa, estoy usando la dirección correcta de Bluetooth y el UUID para RFCOMM/SPP 00001101-0000-1000-8000-00805F9B34FB. Mi aplicación inicia un hilo que intenta conectarse al dispositivo usando BluetoothDevice.createRfcommSocketToServiceRecord(UUID). Pero por una razón u otra, no estamos viendo una conexión exitosa. La operación siempre falla al invocar connect() en el resultado BluetoothSocket que proviene de la invocación anterior.

Cuando se probó en mi HTC Evo, corriendo variante de HTC de Gingerbread, la llamada connect() por lo general produce un error con el mensaje de excepción "Descubrimiento de servicio no se pudo iniciar." Leí un poco y descubrí que algunos decían que la implementación de HTC para RFCOMM en la pila de Bluetooth tenía fallas, así que decidimos probarlo en el Samsung Galaxy S de otro estudiante. La primera vez que se ejecutó el código, todo funcionó perfectamente. El microcontrolador Arduino está conectado a un pequeño motor eléctrico que comenzó a funcionar como se esperaba. No he descartado si el problema podría estar del lado del microcontrolador.

El uso posterior de la aplicación en el dispositivo Samsung falló, ahora con un mensaje que dice "Error en el descubrimiento del servicio". Para mí, parece que tal vez el módulo Bluetooth en el lado del dispositivo cree que el servicio RFCOMM todavía está en uso. Pero hemos reiniciado el microcontrolador y aún hemos visto el mismo resultado.

Acabo de enumerar el código del hilo, ya que es todo lo que es realmente relevante. He leído que hay una solución bastante común (hack) para estos problemas mediante el uso de la reflexión. Mis intentos de hacerlo también han fallado, pero están allí y han sido comentados. Espero que alguien pueda dirigirme en la dirección correcta aquí. También tenga en cuenta que tengo habilitados los permisos necesarios en el manifiesto y, en ambos casos, el dispositivo se emparejó con éxito al Arduino utilizando la interfaz de usuario de Android.

private class ClientThread extends Thread { 

    private String _btAddress; 

    /** 
    * A handle to the local device's Bluetooth adapter hardware. 
    */ 
    private BluetoothAdapter _btAdapter = BluetoothAdapter.getDefaultAdapter(); 

    /** 
    * A handle to the remote device Bluetooth context. 
    */ 
    private BluetoothDevice _btRemoteDevice; 

    /** 
    * A handle to the Bluetooth serial socket. 
    */ 
    private BluetoothSocket _btSocket; 

    /** 
    * Constructor. 
    * @param btAddress The BluetoothHardware address. 
    */ 
    public ClientThread(String btAddress) 
    { 
     _btAddress = btAddress; 
    } 

    public void run() 
    { 
     // Retrieves the device identified by the _btAddress property. 
     _btRemoteDevice = retrieveDevice(); 
     if (_btRemoteDevice == null) 
      sendUIMessage(CONNECTION_BT_DEVICE_NOT_BONDED); 
     else 
      sendBeacon(); 
    } 

    /** 
    * Retrieves the device associated with this client thread. 
    * @return 
    */ 
    private BluetoothDevice retrieveDevice() 
    { 
     Set<BluetoothDevice> btDevices = _btAdapter.getBondedDevices(); 
     for (BluetoothDevice btd : btDevices) 
     { 
      String addr = btd.getAddress(); 
      String name = btd.getName(); 
      if (addr.equalsIgnoreCase(_btAddress)) 
       return btd; 
     } 
     return null; 
    } 

    /** 
    * Sends the beacon to the Bluetooth device. 
    */ 
    private void sendBeacon() 
    { 
     // Holds the output stream of the BluetoothDevice. 
     OutputStream os = null; 

     try 
     { 
      _btSocket = _btRemoteDevice.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")); 

      //Method m = _btRemoteDevice.getClass().getMethod("createInsecureRfcommSocket", new Class[] {int.class}); 
      //_btSocket = (BluetoothSocket) m.invoke(_btRemoteDevice, 1); 
      _btSocket.connect(); 
      os = _btSocket.getOutputStream(); 
      os.write('L'); 
     } 
     catch (IOException e) 
     { 
      String message = e.getMessage(); 
      e.printStackTrace(); 
      sendUIMessage(CONNECTION_FAILURE_IO); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
      sendUIMessage(CONNECTION_FAILURE_UNKNOWN); 
     } 
     finally 
     { 
      try 
      { 
       if (_btSocket != null) 
        _btSocket.close(); 
      } 
      catch (IOException e) 
      { 
       System.out.println("Failed closing Bluetooth output stream."); 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

EDIT: El módulo Bluetooth es una MDFLY RF-BT0417CB. Sé que el código que se está ejecutando en el arduino no es mucho y simplemente se está comunicando con el módulo BT utilizando Serial.available() y Serial.read(). Sin embargo, tengo una nueva información que puede ser de mayor utilidad. Cuando mi aplicación se instaló en el dispositivo Samsung, funcionó solo una vez y falló en pruebas posteriores. Hace un tiempo, el otro estudiante con el que estoy trabajando usó Android App Inventor (una herramienta de GUI para arrastrar y soltar que también puede crear artefactos de trabajo lógicos) para crear una aplicación simple que conecta el mismo módulo BT/placa arduino, que funcionó. Dijo que cuando se instaló mi aplicación, que la otra aplicación no pudo conectarse al módulo BT, lo que me lleva a pensar que el sistema se quedó pensando que el recurso se asignó a mi aplicación. Después de que desinstaló mi aplicación, la otra pudo conectarse. No tiene el código fuente para la otra aplicación, pero voy a probar App Inventor para ver si el código fuente que genera genera algo diferente. Según mi leal saber y entender, estoy cumpliendo con la mayoría de las prácticas estándar definidas en la documentación de Android, así que tal vez sea algo extraño sobre el módulo BT o sobre el hecho de que el código arduino no necesariamente controla programáticamente el módulo BT.

OTRA EDICIÓN: No soy un experto en Bluetooth, pero pudimos encontrar una solución alternativa. Como algunos saben, hay un montón de APIs públicas de BluetoothDevice, ocultas en tiempo de compilación, pero son legalmente públicas en tiempo de ejecución mediante el reflejo. Uno de ellos es createRfCommSocket (int). Esta API no está en la documentación oficial, ya que está oculta, pero puede leerla here.Todavía no lo he probado con la API admitida por la documentación, pero el problema parecía ser un problema de concurrencia entre el teléfono y la placa de serie. El teléfono envió un mensaje, que por supuesto es una llamada de bloqueo, y cuando regresó de allí, cerró la conexión. El escudo en la placa de serie también cerraría la conexión y, por lo tanto, los datos no estaban disponibles para la aplicación arduino. Nos dimos cuenta de esto cuando asistimos a una comunicación exitosa mientras estábamos en modo de depuración en el lado de Android, pero fallamos en el modo de lanzamiento. Agregar un retraso de medio segundo en el lado de Android, entre la transmisión y el cierre del BluetoothSocket solucionó el problema. No puedo decir si este problema fue atribuido por el código arduino o no porque no estoy muy familiarizado con la arquitectura, pero nosotros, como estudiantes, carecemos de experiencia por lo que no me sorprendería.

+0

¿Qué módulo y software bluetooth se está ejecutando en el dispositivo Arduino? ¿Puedes publicar una referencia al dispositivo que estás usando? Además, si puede publicar el registro completo en el lado de Android, lo ayudará. –

+0

Dennis, gracias por su respuesta y acepte mis disculpas por tardar tanto en responderle, los exámenes y otras obligaciones me han estado frenando. Estoy buscando el modelo y las versiones de software del Arduino, pero publiqué información sobre el dispositivo BT y alguna información nueva sobre el problema. –

+0

Hola, tengo un problema similar ... Estoy tratando de conectar un teléfono LG a una TI PAN1315 Dev. placa, obtengo el socket con el mismo UUID, pero connect() siempre arroja una IOException. Al depurar el PAN1315 incorporado, he imprimido algunos registros en la consola, tratando de ver si he alterado algo del diseño original de la aplicación, veo que una solicitud de desconexión hci/acl proviene del teléfono, y no del dispositivo integrado, después de enviar una clave de enlace desde el dispositivo incorporado al teléfono ... ¿podría estar de acuerdo? – TacB0sS

Respuesta

1
[Communication Between Android And Arduino With Bluetooth(1)][1] 

Creo que esto será útil para usted. Puede proporcionar algunos detalles sobre esto. He visto un enlace, puede ver esto también. Déjame saber si esto es útil o no? How to create Insecure RFCOMM Socket in Android?

+0

¿Tienes algo de suerte? Por favor hagamelo saber. – mH16

0

El Amarino Toolkit fue creado específicamente para facilitar la comunicación serial de Bluetooth entre un dispositivo Android y un Arduino con Bluetooth.

Cuestiones relacionadas