Android + Processing + Bluetooth

A finales de 2009 los creadores de Processing anunciaron que iban a dar soporte a la plataforma de Android. La verdad es que fue una noticia muy buena, ya que el famoso entorno de creación de gráficos animados iba a poder ejecutar sketchs dentro de móviles que tuviesen a Android como sistema operativo. Pero no se han quedado ahí y además admite la posibilidad de usar las características embebidas en los dispositivos móviles como el GPS, la brújula electrónica, enviar y recibir sms, etc y por supuesto bluetooth.

Lo que explicaré en este artículo son los pasos que he seguido para crear una conexión desde mi teléfono Android con un dispositivo bluetooth y poder enviarle información a la par que recibirla dibujando los resultados de una forma gráfica con Processing para Android.

Ya en su momento me dediqué a programar en symbian algo parecido:

Sin embargo finalmente lo deseché porque la plataforma de symbian tiene ya poco futuro y porque las APIS eran confusas, mal explicadas y no se puede acceder a todos los elementos de hardware con ellas.

Por otra parte no hay que compararlo con Amarino, ya que Amarino es una aplicación ya hecha para Android con una interfaz definida y está pensado para usarse con Arduino, sin embargo aquí vamos a programar nuestra propia aplicación con su propia interfaz para cualquier dispositivo que tenga un controlador bluetooth.

Dicho esto lo primero es necesario instalar todo el entorno de desarrollo, aquí viene bien explicado en castellano por lo que no considero necesario añadir más.

Antes de empezar, sería interesante que echarais un vistazo a dos páginas para entender mejor lo que viene a continuación. Por una parte la API de Android para bluetooth para comprender qué posibilidades nos ofrece. Por otra parte unos conceptos y un ejemplo de cómo usar Android y gestionar el hardware con Processing. A los que hayáis programado en Processing puede resultar extraño que además de poder usar las funciones básicas del entorno, se puedan incluir librerias y código de Java y la API Android. Esto es debido a que tanto Android como Processing tienen una fuerte vinculación con el lenguaje de programación Java y su unión ha creado una suerte de mescolanza que reúne lo mejor de ambos mundos.

El objetivo es que podamos crear una interfaz completa para que nos muestre los dispositivos bluetooth que hay alrededor, a continuación podamos elegir uno de ellos y finalmente conectarnos a este para enviar y recibir datos. En este caso en concreto voy a conectar mi móvil HTC Wildfire S con una placa Arduino a través de un módulo bluetooth. La placa Arduino enviará a mi móvil cada segundo un valor comprendido entre 0 y 39 y este lo mostrará en su pantalla. En el móvil habrá dibujado un botón que cuando se pulse enviará un 0 a la placa Arduino para encender o apagar el led del pin 13.

Este es el código fuente del sketch para la placa Arduino:

boolean estado;
 
void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  randomSeed(analogRead(0));
  estado = false;
}
 
void loop()
{
    delay(1000);
    Serial.write(random(40));
    while(Serial.available() > 0)
    {
      Serial.read();
      estado = !estado;
      digitalWrite(13, estado);
    }
}

Ahora la parte de Android y Processing. A partir de aquí iré explicando los conceptos a medida que publico el código fuente para comentar los aspectos que considero que son más relevantes y finalmente pondré el código fuente integro.

Para poder programar el bluetooth de nuestro dispositivo basado en Android junto con Processing empezaremos por crear un sketch, daremos los permisos BLUETOOTH y BLUETOOTH_ADMIN en el menú Android/Sketch Permissions e importaremos las clases necesarias para que todo funcione:

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import java.util.ArrayList;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;

Hay algunas librerías que, como veremos más adelante, podemos prescindir de ellas dependiendo de lo que queremos hacer y lo bien o mal que nos funcione.

A continuación vamos a añadir los métodos típicos de un sketch de Processing: setup y draw:

void setup() {
  size(320,480);
  frameRate(25);
  f1 = createFont("Arial",20,true);
  f2 = createFont("Arial",15,true);
  stroke(255);
}
 
void draw() {
  switch(estado)
  {
    case 0:
      listaDispositivos("BUSCANDO DISPOSITIVOS", color(255, 0, 0));
      break;
    case 1:
      listaDispositivos("ELIJA DISPOSITIVO", color(0, 255, 0));
      break;
    case 2:
      conectaDispositivo();
      break;
    case 3:
      muestraDatos();
      break;
    case 4:
      muestraError();
      break;
  }
}

En el método setup forzamos a que la resolución de la pantalla sea de 320 píxeles de ancho x 480 píxeles de alto (HVGA), ya que es una configuración muy extendida dentro del mundo de los móviles. Establecemos que la frecuencia de refresco sea de 25 fps. Creamos dos tipos de fuentes con las que dibujar después los textos que queramos.

En el método draw vamos a simular varias ventanas dependiendo del estado en el que se encuentre nuestra aplicación en cada momento. Así nada más empezar se muestra la ventana de búsqueda de dispositivos, a continuación se ofrece al usuario que seleccione uno de los dispositivos mostrados:

Después se intenta conectar con el dispositivo elegido y finalmente si tiene éxito se muestra la ventana con los datos enviados por Arduino y con el botón que mencionaba antes:

Si algo falla se muestra el error en una ventana:

Un sketch de Proccesing para Arduino se trata como una Activity, por eso se puede inicializar todo en el evento OnStart cuando es llamado al arrancar la aplicación (OnCreate no es llamado).

void onStart()
{
  super.onStart();
  println("onStart");
  adaptador = BluetoothAdapter.getDefaultAdapter();
  if (adaptador != null)
  {
    if (!adaptador.isEnabled())
    {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
    }
    else
    {
      empieza();
    }
  }
}

En el evento OnStart primero debemos llamar al método onStart de la clase padre para inicializar correctamente. Después recuperamos el adaptador bluetooth del móvil y comprobamos si está activo. Si está activo empezamos a mostrar la lista de dispositivos. Si no lo está, lanzamos una petición para activarlo. En esta petición Android nos mostrará un mensaje similar a este en el móvil para activar el bluetooth:

Pulsemos la opción que pulsemos, se llamará al evento onActivityResult:

void onActivityResult (int requestCode, int resultCode, Intent data)
{
  println("onActivityResult");
  if(resultCode == RESULT_OK)
  {
    println("RESULT_OK");
    empieza();
  }
  else
  {
    println("RESULT_CANCELED");
    estado = 4;
    error = "No se ha activado el bluetooth";
  }
}

Si hemos pulsado Si entonces empezaremos a mostrar la lista de dispositivos, si hemos pulsado No iremos directamente a la pantalla de error.

Cuando se abandona la aplicación se llama al evento onStop (onDestroy no es llamado)  y aquí se pueden liberar los recursos que hayamos utilizado antes de terminar definitivamente.

void onStop()
{
  println("onStop");
  /*
  if(registrado)
  {
    unregisterReceiver(receptor);
  }
  */
 
  if(socket != null)
  {
    try
    {
      socket.close();
    }
    catch(IOException ex)
    {
      println(ex);
    }
  }
  super.onStop();
}

En el evento OnStop vamos a hacer dos cosas, aunque una de ellas está comentada por una razón que explicaré más adelante. Lo que se ve es que se cierra un socket que no es otra cosa que la conexión que hayamos establecido con nuestro dispositivo para poder liberar los recursos asociados a este. Finalmente se llama al método onStop de la clase padre para cerrar correctamente la aplicación.

El método empieza sirve para rellenar la lista de dispositivos bluetooth que más tarde mostraremos al usuario.

void empieza()
{
    dispositivos = new ArrayList();
    /*
    registerReceiver(receptor, new IntentFilter(BluetoothDevice.ACTION_FOUND));
    registerReceiver(receptor, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED));
    registerReceiver(receptor, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));
    registrado = true;
    adaptador.startDiscovery();
    */
    for (BluetoothDevice dispositivo : adaptador.getBondedDevices())
    {
        dispositivos.add(dispositivo);
    }
    estado = 1;
}

Inicializamos un array que rellenaremos de objetos BluetoothDevice. Aquí comento una problemática que me he encontrado: Puedes incluir los dispositivos que hay alrededor del móvil o bien incluir los que previamente se hayan emparejado. La parte que está comentada (y por tanto la del método onStop que desregistra el Receiver) se usa para lanzar un proceso de búsqueda de dispositivos bluetooth que estén cerca de nuestro móvil: se registra el empiece, cada dispositivo que se encuentre y el final de la búsqueda. Para manejar estos eventos se usa una clase del tipo BroadcastReceiver ya inicializada:

BroadcastReceiver receptor = new BroadcastReceiver()
{
    public void onReceive(Context context, Intent intent)
    {
        println("onReceive");
        String accion = intent.getAction();
 
        if (BluetoothDevice.ACTION_FOUND.equals(accion))
        {
            BluetoothDevice dispositivo = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            println(dispositivo.getName() + " " + dispositivo.getAddress());
            dispositivos.add(dispositivo);
        }
        else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(accion))
        {
          estado = 0;
          println("Empieza búsqueda");
        }
        else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(accion))
        {
          estado = 1;
          println("Termina búsqueda");
        }
    }
};

Cuando se empieza la búsqueda se encuentra en el estado 0 para mostrar la lista de dispositivos a medida que van apareciendo. Por cada dispositivo bluetooth que se encuentre se añade al array de dispositivos bluetooth, Cuando termina la búsqueda se pasa al estado 1 para que el usuario seleccione el dispositivo al que quiere conectarse.

El hacerlo de esta forma provoca que más adelante cuando se conecte al dispositivo bluetooth se tenga que mostrar una ventana preguntando por un código de emparejamiento para vincular el móvil con este.El problema es que esa ventana no se visualiza cuando están los gráficos mostrándose y el proceso de conexión dará finalmente un error. Por eso la otra alternativa que he encontrado es emparejar el dispositivo bluetooth a mano con el móvil y rellenar la lista de dispositivos con los que ya están vinculados en el móvil, así no pedirá el código de emparejamiento y se conectará con el dispositivo bluetooth directamente.

En varias ocasiones hay que capturar donde pulsa el dedo del usuario para saber qué acción quiere realizar. Esto se consigue con el evento mouseReleased:

void mouseReleased()
{
  switch(estado)
  {
    case 0:
      /*
      if(registrado)
      {
        adaptador.cancelDiscovery();
      }
      */
      break;
    case 1:
      compruebaEleccion();
      break;
    case 3:
      compruebaBoton();
      break;
  }
}

Depende del estado en el que encontremos hará una acción diferente. Cuando estamos en el estado 0 y si se usara la búsqueda de dispositivos bluetooth (pero no es así por los motivos que he comentado) al pulsar en la pantalla cancelaría la búsqueda y lanzaría un ACTION_DISCOVERY_FINISHED al BroadCastReceiver visto anteriormente. Si estamos en el estado 1 se buscaría qué dispositivo bluetooth de la lista ha pulsado el usuario para conectarse a el. Si estamos en el estado 3 se comprueba si se ha pulsado el botón que envía un byte al dispositivo bluetooth.

El método que comprueba que elección ha hecho el usuario en el estado 1 es compruebaEleccion:

void compruebaEleccion()
{
  int elegido = (mouseY - 50) / 55;
  if(elegido < dispositivos.size())
  {
    dispositivo = (BluetoothDevice) dispositivos.get(elegido);
    println(dispositivo.getName());
    estado = 2;
  }
}

Con una sencilla fórmula matemática se puede sacar el dispositivo bluetooth que el usuario ha elegido en base a en qué parte de la pantalla ha pulsado. Después se pasa al estado 2 (Conexión al dispositivo bluetooth).

La lista de dispostivos bluetooth se hace con el método listaDispositivos:

void listaDispositivos(String texto, color c)
{
  background(0);
  textFont(f1);
  fill(c);
  text(texto,0, 20);
  if(dispositivos != null)
  {
    for(int indice = 0; indice < dispositivos.size(); indice++)
    {
      BluetoothDevice dispositivo = (BluetoothDevice) dispositivos.get(indice);
      fill(255,255,0);
      int posicion = 50 + (indice * 55);
      if(dispositivo.getName() != null)
      {
        text(dispositivo.getName(),0, posicion);
      }
      fill(180,180,255);
      text(dispositivo.getAddress(),0, posicion + 20);
      fill(255);
      line(0, posicion + 30, 319, posicion + 30);
    }
  }
}

Se recorre el array de dispositivos bluetooth mostrando su nombre y su dirección MAC. Es usada tanto en el estado 0 (listado de dispositivos bluetooth a medida que van apareciendo en la búsqueda) como en el estado 1 (selección del dispositivo bluetooth al que conectarse).

La conexión con el dispositivo bluetooth se hace con el método conectaDispositivo:

void conectaDispositivo()
{
  try
  {
    socket = dispositivo.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
    /*
    Method m = dispositivo.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
    socket = (BluetoothSocket) m.invoke(dispositivo, 1);
    */
    socket.connect();
    ins = socket.getInputStream();
    ons = socket.getOutputStream();
    estado = 3;
  }
  catch(Exception ex)
  {
    estado = 4;
    error = ex.toString();
    println(error);
  }
}

Aquí ocurre un caso especial. Para conectar con el dispositivo bluetooth se debe crear un socket con el dispositivo y después hacer la conexión propiamente dicha con el método connect. Sin embargo dependiendo de con qué dispositivo se conecte puede dar problemas el método que se use para obtener ese socket. La versión normal es la que está en el metodo y se supone que es la estándar, pero a mi me dio problemas al conectar al blueooth de un PC y tuve que usar las dos líneas que aparecen comentadas . Sin embargo con el módulo bluetooth de Sure la línea que aparece actualmente ha funcionado sin problemas. Como estamos creando una conexión SPP (como si fuese un puerto serie virtual) a través del protocolo RFCOMM, debemos obtener el socket que conecta con el servicio 00001101-0000-1000-8000-00805F9B34FB, que es el identificador único de servicio para SPP en el estandar Bluetooth. El método connect es bloqueante por lo que dejará la aplicación paralizada hasta que se conecte realmente o surja un error. Google dice que se debe usar un thread para separar el hilo de ejecución principal con el de la conexión, pero creo que está solución es más sencilla. Una vez se ha conectado se pueden recuperar el stream de entrada y el de salida para recibir y enviar datos respectivamente con el dispositivo bluetooth. A continuación se pasa al estado 3 (Visualización de datos e interacción con el botón). Si hubiese algún error se pasaría al estado 4 mostrando qué lo ha provocado.

El método que muestra los datos enviados desde el dispositivo bluetooth es muestraDatos:

void muestraDatos()
{
  try
  {
    while(ins.available() > 0)
    {
      valor = (byte)ins.read();
    }
  }
  catch(Exception ex)
  {
    estado = 4;
    error = ex.toString();
    println(error);
  }
  background(0);
  fill(255);
  text(valor, width / 2, height / 2);
  stroke(255, 255, 0);
  fill(255, 0, 0);
  rect(120, 400, 80, 40);
  fill(255, 255, 0);
  text("Botón", 135, 425);
}

Simplemente comprueba si se ha recibido algún byte y lo muestra. También muestra el botón ficticio que puede pulsar el usuario.

El método que se ejecuta cuando el usuario pulsa el botón es compruebaBoton:

void compruebaBoton()
{
  if(mouseX > 120 && mouseX < 200 && mouseY > 400 && mouseY < 440)
  {
    try
    {
        ons.write(0);
    }
    catch(Exception ex)
    {
      estado = 4;
      error = ex.toString();
      println(error);
    }
  }
}

Si se comprueba que el usuario ha pulsado en el área del botón se envía un byte con valor 0 al dispositivo bluetooth, que actualmente lo que hace es encender o apagar el led de la placa Arduino. Si hubiese algún error se pasaría al estado 4 mostrando qué lo ha provocado.

Finalmente el método que muestra los errores es muestraError:

void muestraError()
{
  background(255, 0, 0);
  fill(255, 255, 0);
  textFont(f2);
  textAlign(CENTER);
  translate(width / 2, height / 2);
  rotate(3 * PI / 2);
  text(error, 0, 0);
}

Simplemente muestra el texto del error de forma apaisada para mostrar cadenas largas.

Dejo el código fuente entero:

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import java.util.ArrayList;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
 
private static final int REQUEST_ENABLE_BT = 3;
ArrayList dispositivos;
BluetoothAdapter adaptador;
BluetoothDevice dispositivo;
BluetoothSocket socket;
InputStream ins;
OutputStream ons;
boolean registrado = false;
PFont f1;
PFont f2;
int estado;
String error;
byte valor;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
BroadcastReceiver receptor = new BroadcastReceiver()
{
    public void onReceive(Context context, Intent intent)
    {
        println("onReceive");
        String accion = intent.getAction();
 
        if (BluetoothDevice.ACTION_FOUND.equals(accion))
        {
            BluetoothDevice dispositivo = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            println(dispositivo.getName() + " " + dispositivo.getAddress());
            dispositivos.add(dispositivo);
        }
        else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(accion))
        {
          estado = 0;
          println("Empieza búsqueda");
        }
        else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(accion))
        {
          estado = 1;
          println("Termina búsqueda");
        }
 
    }
};
 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
  //size(320,480);
  frameRate(25);
  f1 = createFont("Arial",20,true);
  f2 = createFont("Arial",15,true);
  stroke(255);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void draw() {
  switch(estado)
  {
    case 0:
      listaDispositivos("BUSCANDO DISPOSITIVOS", color(255, 0, 0));
      break;
    case 1:
      listaDispositivos("ELIJA DISPOSITIVO", color(0, 255, 0));
      break;
    case 2:
      conectaDispositivo();
      break;
    case 3:
      muestraDatos();
      break;
    case 4:
      muestraError();
      break;
  }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void onStart()
{
  super.onStart();
  println("onStart");
  adaptador = BluetoothAdapter.getDefaultAdapter();
  if (adaptador != null)
  {
    if (!adaptador.isEnabled())
    {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
    }
    else
    {
      empieza();
    }
  }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void onStop()
{
  println("onStop");
  /*
  if(registrado)
  {
    unregisterReceiver(receptor);
  }
  */
 
  if(socket != null)
  {
    try
    {
      socket.close();
    }
    catch(IOException ex)
    {
      println(ex);
    }
  }
  super.onStop();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void onActivityResult (int requestCode, int resultCode, Intent data)
{
  println("onActivityResult");
  if(resultCode == RESULT_OK)
  {
    println("RESULT_OK");
    empieza();
  }
  else
  {
    println("RESULT_CANCELED");
    estado = 4;
    error = "No se ha activado el bluetooth";
  }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseReleased()
{
  switch(estado)
  {
    case 0:
      /*
      if(registrado)
      {
        adaptador.cancelDiscovery();
      }
      */
      break;
    case 1:
      compruebaEleccion();
      break;
    case 3:
      compruebaBoton();
      break;
  }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void empieza()
{
    dispositivos = new ArrayList();
    /*
    registerReceiver(receptor, new IntentFilter(BluetoothDevice.ACTION_FOUND));
    registerReceiver(receptor, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED));
    registerReceiver(receptor, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));
    registrado = true;
    adaptador.startDiscovery();
    */
    for (BluetoothDevice dispositivo : adaptador.getBondedDevices())
    {
        dispositivos.add(dispositivo);
    }
    estado = 1;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void listaDispositivos(String texto, color c)
{
  background(0);
  textFont(f1);
  fill(c);
  text(texto,0, 20);
  if(dispositivos != null)
  {
    for(int indice = 0; indice < dispositivos.size(); indice++)
    {
      BluetoothDevice dispositivo = (BluetoothDevice) dispositivos.get(indice);
      fill(255,255,0);
      int posicion = 50 + (indice * 55);
      if(dispositivo.getName() != null)
      {
        text(dispositivo.getName(),0, posicion);
      }
      fill(180,180,255);
      text(dispositivo.getAddress(),0, posicion + 20);
      fill(255);
      line(0, posicion + 30, 319, posicion + 30);
    }
  }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void compruebaEleccion()
{
  int elegido = (mouseY - 50) / 55;
  if(elegido < dispositivos.size())   
  {     
    dispositivo = (BluetoothDevice) dispositivos.get(elegido);     
    println(dispositivo.getName());     
    estado = 2;   
  } 
} 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
void conectaDispositivo() 
{   
  try   
  {     
    socket = dispositivo.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
    /*     
      Method m = dispositivo.getClass().getMethod("createRfcommSocket", new Class[] { int.class });     
      socket = (BluetoothSocket) m.invoke(dispositivo, 1);             
    */     
    socket.connect();     
    ins = socket.getInputStream();     
    ons = socket.getOutputStream();     
    estado = 3;   
  }   
  catch(Exception ex)   
  {     
    estado = 4;     
    error = ex.toString();     
    println(error);   
  } 
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
void muestraDatos() 
{   
  try
  {     
    while(ins.available() > 0)
    {
      valor = (byte)ins.read();
    }
  }
  catch(Exception ex)
  {
    estado = 4;
    error = ex.toString();
    println(error);
  }
  background(0);
  fill(255);
  text(valor, width / 2, height / 2);
  stroke(255, 255, 0);
  fill(255, 0, 0);
  rect(120, 400, 80, 40);
  fill(255, 255, 0);
  text("Botón", 135, 425);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void compruebaBoton()
{
  if(mouseX > 120 && mouseX < 200 && mouseY > 400 && mouseY < 440)
  {
    try
    {
        ons.write(0);
    }
    catch(Exception ex)
    {
      estado = 4;
      error = ex.toString();
      println(error);
    }
  }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void muestraError()
{
  background(255, 0, 0);
  fill(255, 255, 0);
  textFont(f2);
  textAlign(CENTER);
  translate(width / 2, height / 2);
  rotate(3 * PI / 2);
  text(error, 0, 0);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Visitas :94129
You can leave a response, or trackback from your own site.

185 Responses to “Android + Processing + Bluetooth”

  1. Angel MA says:

    It is an amazing job, so I couldn’t wait to try it, unfortunately there was a problem when attempting to run the application that says that it suddenly stopped due to a process related to classes.processing.android\test.bluetooth_android. I hope you have bumped into this problem and could give a possible reason as well as a posible solution.
    Many thanks.

    • Oscar says:

      Hi

      I need more info about it. Normally a stack trace is showed in processing window when an error appears.

      • Angel MA says:

        Ohhh. it was configuration mistakes, I should have declared the permissions from the beginning, that was the problem, now i have sent some data to a PIC and viceversa. Thanks a lot and once more: AMAZING JOB!!!!!

  2. Pedro says:

    Está muy bien, te lo has currado!
    Yo te recomendaría hacer más uso de las facilidades que tiene Android como los ListView (http://developer.android.com/resources/tutorials/views/hello-listview.html) para pintar los dispositivos BT. Y para ahorrarte el trauma de calcular si un dedo a pulsado un botón podrías hacerlo añadiendo un Button. Además así valdría para cualquier pantalla ;)
    Donde ando un poco perdido es en la parte del arduino.
    I Like!

  3. David Asensio Cañas says:

    Hola, me parece muy interesante, pero no puedo compilar-lo, te importaría enviarme los archivos al correo creo que es por alguna tontería de código, Y así comparo :D gracias de antemano!

    • Oscar says:

      Hola

      En el código fuente completo que había publicado no se por qué se me cambiaron algunas líneas a una sola y posiblemente ese fuese el error que te estaba dando, lo he cambiado, por lo que prueba a copiar de nuevo el código fuente y compilalo a ver si ahora te funciona.

  4. David Asensio Cañas says:

    Muchisimas gracias ;) , me es super util, estoy haciendo un robot humanoide con arduino y lo quiero controlar con un android, así que me sirve de mucho, Merci!

  5. David Asensio Cañas says:

    Ahora funciona perfecto :) muchisiimas gracias

  6. Alan says:

    Hola Oscar,
    Esto es genial!
    que es el módulo bluetooth? which bluetooth module is it?
    Gracias,
    Alan.

  7. Alex says:

    Hola,

    This looks amazing!

    Which versions of the Android SDKs and tools did you use? I am having trouble compiling the Processing code in Processing 1.5.1 with Android API 7 tools.

    Thanks
    Alex

  8. Oscar says:

    Hi

    The API 7 is the correct. What compile errors do you have?

    • Alex says:

      Oscar
      Ahora esta functionando, despues de un poco mas trabajo – un proyecto increible – muchas gracias!

      Alex

  9. Sophie says:

    Hello,

    I am very excited about your project. I would like to do something similar.
    Is it possible that you download the entire Eclipse project files up?

    Thank you,
    Sophie

  10. David Asensio Cañas says:

    Una pregunta, la conexión al modulo la haces directamente al 3.3v del arduino y directamente al tx/rx o le pones alguna resistencia diodo o algo?

  11. David Asensio Cañas says:

    103 ohms?

    • JM says:

      103 en smd significa 10000 ohmios, el último número es el número de ceros. Por otro lado 10^3 = 1000 que puede ser lo que haya querido poner el chino que ha hecho ese datasheet.

      http://webdelcire.com/wordpress/archives/135 Si lees la entrada verás que dice 1000 ohmios, ante la duda prueba con 10k ya que esa resistencia se encarga de limitar la corriente que pasa por los diodos de protección interna

  12. David Asensio Cañas says:

    Gracias :=)

  13. joe says:

    Hola, excelente trabajo!

    que cambios tendria que hacer para que la aplicación acepte conexiones por el método startActivityForResult(Intent, int) ? saludos!

  14. joe says:

    Gracias por tu respuesta tan rápida! correcto estoy leyendo esa parte, sin embargo como soy nuevo programando android estoy bien confundido, básicamente la necesidad que tengo de que el telefono se comporte como servidor es porque la comunicacion blue2 la estoy realizando desde del telefono a la pc (WIN7), y de esa manera la pc no me deja iniciar la comunicacion, dice no puede abrir puerto CON, lo mismo me pasa con los programas que son terminales blue, siempre la computadora tiene que iniciar la comunicación.

    • Oscar says:

      Bien. Tenga en cuenta que el artículo habla de conectarse a un módulo bluetooth que actua como servidor. Lo que no entiendo es por qué el PC no le deja actuar como servidor y que el móvil se conecte a este. ¿Con qué programa abre el puerto COM en el PC?

  15. joe says:

    De antemano muchas gracias por tu colaboración!

    estoy usando Teraterm, hyperterminal y el emulador de terminal que trae el software del arduino, como no poseo un modulo quiero probar primero enviando datos desde la pc, el celular se conecta y muestra la pantalla esperando recibir datos, igual el dongle bluetooth que tengo conectado a la pc titila en senial de que inicio conexión pero al abrir alguno de estos programas para enviar datos no abre el puerto COM12 que es el que tomo el celular al vincularse con la pc, esto mismo me pasa con los emuladores de terminal del celular solo me permite conectar si la comunicación la inicia la PC, colocando al celular en modo “discoverable”

    • Oscar says:

      Bien

      Vamos a hacer lo siguiente. Primero abra el programa hyperterminal y después conecte el móvil al pc.

      Si no funciona vaya al administrador de dispositivos, puertos COM y cambie el puerto COM12 por el puerto COM4 y repita el punto anterior.

      Si no funciona intente ejecutar el primer paso con distintas velocidades (9600, 19200, 57600, 115200)

  16. joe says:

    No funciona, veo que cuando la pc asepta la conexion para la toma como un si fuera un moden “dial up service”

  17. joe says:

    Actualizo, ya lo pude hacer funcionar conectando a una computadora con win XP. Parce que es un tema de seguridad en win7 que no deja que otros dispositivos inicien la comunicación..

  18. jesus says:

    Hola esta muy bueno lo que haz hecho, me gustaria saber en que cambiaria el codigo para el caso de que yo desee usar el celular como controlador , por ejemplo el mandar a encender el led desde el celular

    • Oscar says:

      Como puede ver en el vídeo Joe, el móvil es el que manda que se encienda el led o se apague. No hace falta cambiar ningún codigo.

  19. Joshua says:

    Thanks for this tutorial! The main problem I encountered was that I was not able to get my Android phone to receive or send values to the Bluetooth modem until I set the baud rate on the Arduino sketch to 115200.

    I am not sure if the issue I encountered is a result of my hardware or software, so here are the versions of my hardware and software. Hopefully this will help someone else!
    Arduino 0022
    Processing 2.0a4
    T-Mobile G1 running Cyanogenmod 6
    Bluetooth Mate Silver (http://www.sparkfun.com/products/10393)

  20. Electronicguy says:

    Hi, I love your post just one problem: It doesnt work well with my phone its hard to select a bluetooth device. I dont need to search for devices pair with them, etc. Can you please show me how to modify code to bare minimum and automatically set the adress of the bluetooth device to “00:11:11:XX:XX:XX”(and automatically connect). So far I cant compile because I cant compare bluetooth to a string.

    Thanks

  21. Luca says:

    Hi,
    before to start, i would say thank you for the great tutorial.
    Then, i have a question for you.
    I need to make a project for the University: i have to make an android application that use the accelerometer, saves datas in files and sends them via bluetooth!
    I developed the first part, now i will send the files via bluetooth!
    How can i integrate this code with mine?

    In attachment i leave you my code, i hope that you can help me…

    Again, thank you!
    …and everybody “Excuse me” for my bad English!

    See you soon!

    Luca.

    http://dl.dropbox.com/u/47779079/Acc.zip

  22. fray says:

    HOLA tu codigo me parece muy util
    pero por orto lado megustaria saber que se necesita para conectar una impresora (PB2 y PB3 Impresoras Portátiles de Recibos) la idea es mediante la aplicacion android poder imprimir una factura

  23. fray says:

    Si ya que se configuran atravéz de un puerto COM de salida

  24. Theelectronicguy says:

    You gotta fix that reply probrem :D . So lets say that I send a value of 100 to the arduino. First time it connects, the arduino receives the value 100(tested with an led). Then if I immediatelly go from 100 to 50(in steps of 5), I wait ten seconds and the the led starts to go from 100 to 50 in a split second. Now, I put a println(`DATA SENT`) just before the ons.write() and on the computer, I receive DATA SENT a few times per second. So my guess is that its a problem with ons.write(). Any idea?

    • Theelectronicguy says:

      Ok, I have found the solution, I had to put a 200 millisecond delay and write ons.flush(); after each write. Thank you Oscar for making this tutorial :D .

  25. Martin says:

    Hola, tu codigo esta muy bien planteado y la explicacion mas, pero tengo una duda: en processing como exporto la aplicacion para el android, espero que me puedas ayudar

  26. Martin says:

    jajaja ya vi, automaticamente crea la aplicacion dentro del dispositivo android, no?

  27. Martin says:

    Hola de nuevo, oye amigo de donde aprendiste a utilizar los recursos para manipular el bluetooth? Existe algun manual o libro donde venga las funciones del bluetooth?

  28. Oscar says:

    Pues la de processing es porque se está usando la API de Android para bluetooth y en este mismo artículo está el enlace donde está la documentación. En cuanto a Arduino no hay que explciar mucho ya que se trata de usar el puerto serie con un módulo bluetooth que puede ver como funciona en este artículo http://webdelcire.com/wordpress/archives/135

    • Martin says:

      OK, ya vi lo de android, para transferir datos del arduino hacia el modulo bluetooth, se utilizan las mismas instrucciones que la de comunicacion serial?

      • Oscar says:

        Realmente no hay instrucciones para comunicaciones serie, ya que se trata de enviar y recibir datos, incluso los comandos Hayes son datos que se envían y se reciben aunque en el caso concreto de este módulo bluetooth no se aplica.

  29. Oscarcv says:

    Hola, es genial, ya lo he probado.

    Tengo terminado un programa en VBasic para el PC, y estoy intentando hacerlo para la tablet.En este proceso me he topado con que no puedo introducir delay`s, Es por algún motivo en especial.
    un saludo.

  30. Greg says:

    Hello thank you for the incredible effort your post has been very informative and helpful… still working on getting the sketch to run on my phone. I am planning to use Android Processing to control several servos with my phones accelerometer via bluetooth through my computer as your sketch does. My question for you is in regards to the Ketai Library… I’ve just discovered that they have several bluetooth functions that might simplify your code. Are you familiar with Ketai? What do you think of the idea…

    I must say that I am in the learn by doing phase of programing as such examples are ‘king’ thank you!

    http://www.danielsauter.com/display.php?project_id=113

    Cheers,
    Greg

    • Greg says:

      Any ideas why the program would be force stopping whenever I run the sketch on my phone, Motorola Atrix? It runs in my emulator though it doesn’t recognize any devices… but whenever I load the sketch onto my phone is doesn’t open or run.

    • Oscar says:

      Hi Greg

      This post was published on August 13th, 2011, however the Ketai library with bluetooth support was released on Mar 10, 2012 ( http://code.google.com/p/ketai/downloads/detail?name=Ketai_v4.zip&can=2&q= ) So in that time I had not any libraries for bluetooth with Arduino and Processing, then I studied the Android API to explain everybody how to make it works.

      I think that a library like Ketai is good for developers who wants to abstract from low level code.

      Regards.

      • Greg says:

        Thanks for the reply… seems like the Bluetooth Ketai library is still experimental so don’t think I’ll use it yet… just thought I’d mention it for those online searching for ways to connect via Bluetooth and Processing to Arduino.

        Cheers,
        Greg

  31. Conor says:

    Where in the code do you print the incoming bluetooth packets to the middle of the screen? Also, is there a place where I can get all of the source code in the order it was written in? For me, the source code at the bottom of your post has a lot of the text removed (and placed above).

    • Conor says:

      Nevermind. I just discovered that when I translate the page from Spanish to English large chunks of the source code are removed. Hope this helps anyone else that uses the automatic translate option of Google Chrome’s browser.

      Cheers. Great Tutorial!

  32. [...] with Processing, but I had trouble with my app crashing.  I tried going through this tutorial: http://webdelcire.com/wordpress/archives/1045 on Processing, Android, and Arduino- but ran into similar phone freezing issues.   One issue I [...]

  33. gas says:

    Good morning, I have a question: it’s possible to connect at the same time to two bluetooth modules, driven by two microcontrollers, that send data to the same sketch on Android phone?
    Thank you

  34. gas says:

    Thank you Oscar for your reply. I have an Android version 2.3 and so I see that it’s possible to obtain a connection with other two bluetooth modules (drived by two pic24fxx). I want to ask if you can tell me if there are any source code (better in in Processing language…) to realize the control of this dual simultaneous communications.
    Thanks in advance

    • Oscar says:

      Sorry, but I don’t know if there is any code to do that. However the bluetooth code in Processing is the same for Android, so you can look for any Android code in Internet and then implements it in a Processing sketch like this article.

  35. [...] this article, basic information on how to build an android phone that can be connected to the Bluetooth device can be found.Read on to know more about [...]

  36. [...] my initial research, I found an example (Android + Processing + Bluetooth | C.I.r.E.) that uses the Android SDK calls in a Processing sketch to handle a Bluetooth connection to an [...]

  37. Julio César says:

    Hola Oscar

    Muy buena explicación de tu código y excelente applicación para empezar a conectar arduino con android via bluetooth, tengo un problema que copie todo el código que proporcionas a eclipse pero me salen varios errores, no se si de favor pudieras subir la carpeta de tu proyecto donde desarrollaste el código para eclipse, ya que en la carpeta que se desarrolla para eclipse para cualquier programa siempre se incluye carpetas como bin, gen, src, etc. gracias saludos.

    • Oscar says:

      El proyecto lo desarrollé en processing, no en eclipse, por eso no hay ningún proyecto para el entorno de desarrollo.

  38. Alex says:

    Hola Oscar

    Estoy programando una app en android mediante eclipse. Una parte de ella está centrada en encontrar los dispositivos bluetooth que tengo alrededor y conectarme uno por uno para enviar y recibir datos entre el dispositivo conectado y el mio propio. Me falta la parte de la conexión, he visto que has ido explicando el código, lo que es de gran ayuda, con lo cual si yo implemento en mi app esa parte de la conexión, o parte de ella, debería de funcionar a pesar de que lo desarrollaste en processing ¿no?.

    Muchas gracias de antemano.
    Un saludo.

    • Oscar says:

      Si, así es. El código es para Android por lo que da igual que esté en processing que en eclipse.

  39. gas says:

    Hi Oscar,
    I wish to connect a microcontroller with Android 2.3.4 via usb, using processing: can you suggest any example?
    Thank you

    • Oscar says:

      What kind of microcontroller? If the microcontoller doen’t support USB Host you can’t connect it directly to Android.

      • gas says:

        Microcontroller of family pic24fjxxx. In my case is pic24fj64gb002, that suppoprts usb.

        • Oscar says:

          In that case the microcontoller can act as usb Host. The next question is: can you enable a serial communication between your Android mobile and the pic24?

          • gas says:

            I’m not sure to understand your question. Now I only can communicate between pic and PC or Android and PC via usb…

  40. Oscar says:

    As you mentioned above, you want to communicate between pic and android directly, don’t you? So The first step is to program the microcontroller as a CDC Host, have you tried it succesfully that issue?

    • gas says:

      Yes, I do.

      • Oscar says:

        Ok, now when you connect you device to Android you should have a serial port. Make an .apk with the next source code for Processing:

        import processing.serial.*;

        void setup()
        {
        size(240, 320);
        PFont font = createFont(“Arial”, 16, true); // Arial, 16 point, anti-aliasing on
        textFont(font);
        fill(255);
        background(0);
        String vector[] = Serial.list();

        for(int index = 0; index < vector.length; index++)
        {
        text(vector[index], 5, 50 * index + 16);
        }

        }

        And tell me the results

  41. gas says:

    Hi Oscar,
    I try, but Processing compiler send me the message:”unexpected char:”\”". Did you know the meaning?

  42. gas says:

    Now I’d manually write the code and the compiler write: “No library found for processing.serial” in the first line. Where can I find this library?

  43. gas says:

    No, my board is a explorer 16 and I try to use the application “CE370 Explorer16 USB Bulk Out Demo without USB PICTail” of Microchip. It’s good for usb communication PCboard, but I’m not able to replace my phone with the Pc. In every case, I’ll examine your suggestions and I’ll tell you

  44. romelapj says:

    Estoy probando el programa con una galaxy tab 10.1-y me molesta bastante para la conexion y envia la informacion al arduino en el momento que toco el boton…cualquier sugerencia la tendre en cuenta gracias

    • Oscar says:

      No entiendo lo de “y me molesta bastante para la conexion”, ¿Qué te molesta?.

      En cuanto a que te envíe la información en el momento que tocas el botón, prueba a quitar la línea delay(1000)

  45. romelapj says:

    Lo que sucede es q estoy implementando el codigo en android(eclipse)
    y no entiendo el porque no me comunica…te agradeceria mucho si miraras el codigo, de ante mano te doy gracias y te felicito por el tutorial y si no puedes ayudarme entendere :D

  46. self says:

    hola:
    oye me aparece esto cuando le doy en run
    lost connection with device while launching. Try again

  47. Andreita says:

    :( no me muestra los aleatorios, se enciende el le pero no muestra los aleatorios

    • Oscar says:

      Prueba a hacerlo desde el bluetooth de un PC a ver si ocurre lo mismo. Tiene pinta de que el no está bien conectado el pin RX del módulo bluetooth al pin TX del microcontrolador.

  48. Usco says:

    Hola, es que intento hacer este mismo ejercicio, pero me resulta un error a la hora de dar play, ya que sigue sin reconocerme las librerias de bluetooth, no se ya que hacer, ya le di a todos los permisos de sketch en android y nada… me podrias ayudar, trabajo en Mac OS X. pero es casi lo mismo. ya tengo el sdk de andorid completo.

  49. mistery says:

    Hi,
    First off all I want to thank you for this code it is great, simple and working :)
    And second I have one question.
    I can connect to my bluetooth and recieve sendt data, I can even send data with ons.write(0x..) in hex but now i have to send byte, how can i convert sone variable that I have let say it is
    byte a;
    and send it thrue bluetooth
    I tried
    ons.write(a);
    and
    ons.write(hex(a));
    but it did not work.
    I think i tried to send
    int a;
    ons.write(a);
    and this did not work to.
    So if you can please explain me a little more how to send different types of variable.
    Thank you so much

    • Oscar says:

      If you use ons.write(a) (where a is byte) it will send only a byte, if you need to send other types you will have to convert them into array and then send. For example:

      long data;
      .
      .
      .
      ByteBuffer bb = ByteBuffer.allocate(8);
      byte vector[] = bb.putLong(data).array();
      ons.write(vector);

  50. mistery says:

    All working I had an error in other part of code.
    Thank you

  51. SimonC says:

    Hello Oscar!

    I’m really excited about your project! I need to read data emitted bluetooth loop with an Android device (samsung galaxy tab 2) inspired me and I would like your project to the reception party bluetooth.
    But as soon as I copy your code I get small defects:

    No library found for android.bluetooth
    No library found for android.bluetooth
    No library found for android.bluetooth
    No library found for android.content
    No library found for android.content
    No library found for android.content
    No library found for android.content
    Android SDK Tools Revision 21
    Installed at C:\Users\Simon\AppData\Local\Android\android-sdk
    Project Type: Application
    Project Target: Android 2.3.3
    API level: 10
    Library dependencies:
    No Libraries

    ——————
    API<=15: Adding annotations.jar to the classpath.
    Merging AndroidManifest files into one.
    Manifest merger disabled. Using project manifest only.
    No AIDL files to compile.
    No RenderScript files to compile.
    Generating resource IDs…
    Generating BuildConfig class.

    BUILD FAILED
    C:\Users\Simon\AppData\Local\Android\android-sdk\tools\ant\build.xml:705: The following error occurred while executing this line:
    C:\Users\Simon\AppData\Local\Android\android-sdk\tools\ant\build.xml:718: Compile failed; see the compiler error output for details.

    Total time: 3 seconds

    I tried to find information on the missing libraries and it is said that they are supposed to be downloaded with the SDK. (I download all MAJs SDK) I work with a processing configuration 2.0.b3 vista

    I need help, please!
    Thank you in advance

    • Oscar says:

      Did you give BLUETOOTH and BLUETOOTH_ADMIN permissions in Android/Sketch Permissions menu?

      • SimonC says:

        Yes, android/sketch permissions is okay. Now in Sketch/add file… I search the android API and bluetooth’s library are ok. But now, after this when I compile it’s fail again :s

        Thanks again

      • SimonC says:

        I followed bluetooth mode of your program, as well as other websites but when I want to just separate blutooth I have a compilation error.

        The all libraries (the header).

        BroadcastReceiver Receiver = new BroadcastReceiver ()
        {
        public void onReceive (Context context, Intent intent)
        {
        println (“onReceive”);
        String action = intent. GetAction ();

        if (BluetoothDevice. ACTION_FOUND. equals (action))
        {
        BluetoothDevice device = intent. GetParcelableExtra (BluetoothDevice. EXTRA_DEVICE);
        println (dispositivo. getName () + “” + device. getAddress ());
        devices. add (device);
        }
        else if (BluetoothAdapter. ACTION_DISCOVERY_STARTED. equals (action))
        {
        status = 0;
        println (“Lancer la recherche”);
        }
        else if (BluetoothAdapter. ACTION_DISCOVERY_FINISHED. equals (action))
        {
        status = 1;
        println (“Fin de la recherche”);
        }

        }
        };

        Thanks again

  52. Laura says:

    Me señala esta línea

    socket = dispositivo.createRfcommSocketToServiceRecord(UUID.fromString(“00001101-0000-1000-8000-00805F9B34FB”));

    • GRACIEL says:

      Me sata error en este línea tu ayuda por favor.
      socket = dispositivo.createRfcommSocketToServiceRecord(UUID.fromString(“00001101-0000-1000-8000-00805F9B34FB”));

  53. Laura says:

    De nuevo yo, incluyendo esta línea ya no saca el error. No estaba reconociendo el UUID.

    import java.util.UUID;

    Gracias de nuevo

  54. gonzalo says:

    Hola, alguien pordria decirme donde descargar todas las librerias??.

    import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import java.util.ArrayList; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Method;

    Llevo toda la mañana buscando…

  55. Gonzalo says:

    Hola, instale SDK de Android y sigo sin poder hacer correr el programa, me salen los siguientes errores:
    No library found for android.bluetooth
    No library found for android.bluetooth
    No library found for android.bluetooth
    No library found for android.content
    No library found for android.content
    No library found for android.content
    No library found for android.content
    Libraries must be installed in a folder named ‘libraries’inside the ‘sketchbook’ folder.

    Utilizo processing 2.0b7

  56. gonzalo says:

    Ya consegui que encontrara las librerias. No tenia el processing en modo Android. Que bobada ¿verdad?. Los principios son duros!!.

  57. Parita says:

    Hey!
    I found your code really helpful in understanding the bluetooth library so thank you so much!
    Would just like to add that the line:
    socket=dispositivo.createRfcommSocketToServiceRecord(UUID.fromString(“00001101-0000-1000-8000-00805F9B34FB”));

    gave me errors too and I used the commented lines instead like you said. But then I figured that the error was because we needed to import UUID package. I added this line:
    import java.util.UUID;
    and it worked just fine :)

    Thanks again :)

  58. Lisergio says:

    Estoy probando el sketch en el simulador y arranca, pero lo quiero instalar en un samsung galaxy con la version 2.2.1 Froyo….

    En el emulador si selecciono la version 2.2 NO funciona ….. si selecciono 2.3.3 Si ….

    me sale el siguiente error…

    Lost connection with device while installing. Try again

    debug:
    Failure [INSTALL_FAILED_OLDER_SDK]
    Shutting down any existing adb server..

    imagino que habra que cambiar el sdk usado para compilarlo,,,, pero donde se cambia….??

  59. Alicia says:

    Hola. Apenas estoy empezando a programar en Java y no entiendo muy bien la parte del código. ¿Cada uno va en una clase por separado o todo eso va en el main? Saludos

  60. Alicia says:

    Soy nueva en java. Leí en comentarios que puede sustituirse el Processing con botones, cómo se hace eso?

  61. prof.buchi says:

    Hello !
    Very nice job but I get an error during the processing compilation : “cannot find symbol” and the line : “socket = dispositivo.createRfcommSocketToServiceRecord(UUID.fromString(“00001101-0000-1000-8000-00805F9B34FB”));” is highlighted
    Can you help me ?
    Prof.buchi, Strasbourg (France)

  62. Lisergio says:

    Buenas otra vez….
    Después de hacer varias pruebas y actualizar mi samsung galaxy a la versión 2.3.3, ya funciona correctamente… Muchisimas gracias por el trabajo…

    Quiero enviar otro dato desde el arduino al teléfono, pero no lo consigo.
    quiero enviar en primer lugar un long, de millis y mostrarlo en el teléfono,( para mostrarlo después en el formato 00:00:000 ) pero no llega bien… he probado a enviar cada 100 milis un numero y al llegar a 255 empieza de cero otra vez…

    y luego me gustaría enviar algun texto también …

    alguna idea?? gracias

    • Oscar says:

      Un long son 4 bytes, tendrás que descomponerlo en arduino y enviarlos uno por uno , luego en processing los recuperas uno por uno y lo vuelves a componer.

      • Lisergio says:

        ok!

        gracias,, pruebo y te cuento… a ver si soy capaz de enviarlos separados en tres y volver a mostrarlos después…

        un saludo.

      • Lisergio says:

        Buenas otra vez….

        He descompuesto el tiempo, en todos los valore… Es decir ..
        MM:SS,DDD en 9 valores, y hago un serial.write de cada uno de ellos para enviarlos al telefono,
        Pero no se como unirlos para mostrarlos…

        Podrias orientarme? Gracias

        • Oscar says:

          No, envía los 4 bytes del millis:

          unsigned long valor = millis();
          Serial.write((valor & 0xFF000000) >> 24);
          Serial.write((valor & 0xFF0000) >> 16);
          Serial.write((valor & 0xFF00) >> 8);
          Serial.write(valor & 0xFF);

          Y luego ya en el sketch de Processing los vas recuperando:

          unsigned long valor = ins.read() << 24;
          valor |= ins.read() << 16;
          valor |= ins.read() << 8;
          valor |= ins.read();

          Así tienes en tu móvil la variable valor con el número que arduino te ha enviado. Ya sólo te falta formatear ese número en processing para mostrar HH:MM:SS,DDD

  63. Juanp-or says:

    una pregunta, podria conectar dos smartphones con este programa sin ninguna modificacion y mostrar en pantalla de cada uno el byte mandado en este caso para encender el led del arduino? o qué modificacion habria que hacer?

  64. Juanp-or says:

    Gracias le estoy echando un vistazo pero tengo ciertos problemas, ando con un proyecto entremanos, si no te importa, te podrias poner en contacto directamente a mi correo para poder explicarte lo que quiero hacer y asi pudieras asesorarme un poco? gracias.
    Mi correo eso juanpredroortegaruiz@gmail.com

    • JMN says:

      Sin animo de molestar, este tipo de comentarios están fuera de lugar en este blog.

      Si buscas asesoramiento gratuito, lo indicado es ir a un foro del tema, plantear la duda y allí encontrarás ayuda para que puedas hacer tu proyecto, tampoco esperes que nadie lo realice por tí (como más de un caso se suele ver). Esto es lo que hacemos todos cuando tenemos unda duda de estos temas, hay muchos sitios donde resolverlas, con buscar en google saldrán unos cuantos.

      Si buscas a alguien que te asesore de manera particular, a tu correo, lo indicado es pagar por ello, hay varios sitios para esto, ejemplo: http://www.infolancer.net/

      Una cosa es hacer un blog porque nos guste, y otra cosa muy distinta es estar recibiendo peticiones de gente para que hagamos sus proyectos o les ayudemos con ellos (cansados estamos de ello), como comprenderas el tiempo libre que tenemos preferimos aplicarlo a nuestros propios proyectos.

      Para ayudar y consultar dudas de manera gratuita están los foros.

      Un saludo.

      • juanp-or says:

        quizá no lo he explicado del mejor modo, mi intención no es es que los demás me hagan mi trabajo es simplemente resolver una duda sobre como declarar ciertas cosas en processing ya que soy bastante novato, nadie quiere perder su tiempo en cosas que resulten ser eso, una perdida de tiempo, pero tampoco veo correcto que esto de lugar a colgarme un sanBenito tan a la ligera, tendre que tener mas cuidado a la hora de explicarme en otras ocasiones. No sabia yo que crear una pequeña aplicación para guardar los archivos de mi pulsómetro de deporte fuera una app para dar lugar a un comentario de este tipo, el pedir ese “asesoramiento” por llamarlo así es porque quizá un mensaje de esas dimensiones intercederia en la dinamica principal del tema, pero deacuerdo, disculpad si os ha ofendido mi comentario.

        • JMN says:

          Mi intención no era colgarte nada ni decir que no quieras hacer tu trabajo, simplemente indicarte que para resolver dudas sobre proyectos personales, los comentarios de un blog no es el sitio adecuado, y dejar una dirección de correo para ello tampoco lo es.

          El sitio adecuado para estas cosas son los foros de internet, allí es donde se resuelven las dudas sobre los proyectos personales.

          Siento que te haya tocado este comentario, ya que mi intención ni mucho menos era molestar, pero para que te hagas una idea, podemos tener cientos de correos de gente preguntando dudas sobre sus proyectos personales, mandandonos cosas a nuestros correos personales, y esperando a que les respondamos o les hagamos algo, lamentablemente esa es la actitud general que tenemos por aquí.

          Solo volverte a indicar el uso de los foros para este tipo de peticiones, que era el fin de mi mensaje, y siento si en algún momento te ha molestado mi comentario.

          Saludos.

        • Oscar says:

          Juan

          Ten en cuenta que lo que está escrito en el artículo es lo que hay. Te puedo ayudar en cosas puntuales si se trata de algo del propio artículo y siempre en los comentarios (así otra gente lo puede ver también), pero cualquier otra ayuda que se salga del ámbito del artículo ya es tiempo del que desgraciadamente no dispongo. Como dice Jorge si es algo que te urge de programación en Processing puedes preguntarlo en los foros especializados http://forum.processing.org/ o si es algo de programación en Android lo puedes hacer en el foro de htcmania http://www.htcmania.com/forumdisplay.php?f=153
          Siento no poder darte más ayuda, pero al ser esto un hobby y no una profesión no puedo dedicarle más tiempo que el estrictamente necesario.
          Un saludo

    • jose says:

      hola Juan seria de ayuda contactarme con voz es algo relacionado al proyecto que mensionaste que dejo mi correo jose_xp_799@hotmail.cm

  65. juanp-or says:

    No, si entiendo lo que decís, es logico, solo queria que supierais que mi intención no era robar vuestro tiempo, ni nada por el estilo, pido perdón si lo ha parecido y estoy muy agradecido por la ayuda prestada, voy a plantear mi duda ahora mismo en el foro Oscar a ver si alguien pudiera ayudarme con ella, repito, Muchas gracias de veras :)

  66. Andrey says:

    Oye Una Pregunta de los modulos blue que venden aqui me servira lo puedes cheekear http://www.dynamoelectronics.com/images/stories/Bluetooth%20Shield.pdf

    gracias necesito enviar un high al pin 12 de arduino

  67. Andrey says:

    otra cosa copie el codigo que tienes y me aparece error que las librerias que estan en la cabecera no existen

  68. Andrey says:

    ya logre solucionar eso pero ahora le doy run al programa tuyo
    y me sale un error en esta linea
    socket = dispositivo.createRfcommSocketToServiceRecord(UUID.fromString(“00001101-0000-1000-8000-00805F9B34FB”));

    a que se debe dice

    [javac] Since compiler setting isn’t classic or modern, ignoring fork setting.
    [javac] Since compiler setting isn’t classic or modern, ignoring fork setting.
    [javac] Since compiler setting isn’t classic or modern, ignoring fork setting.
    [javac] Compiling 3 source files to C:\Users\usuario\AppData\Local\Temp\android3109560753686470828sketch\bin\classes
    [javac] Since compiler setting isn’t classic or modern, ignoring fork setting.
    [javac] C:\Users\usuario\AppData\Local\Temp\android3109560753686470828sketch\src\processing\test\sketch_130202a\sketch_130202a.java:252: cannot find symbol
    [javac] symbol : variable UUID
    [javac] location: class processing.test.sketch_130202a.sketch_130202a
    [javac] socket = dispositivo.createRfcommSocketToServiceRecord(UUID.fromString(“00001101-0000-1000-8000-00805F9B34FB”));
    [javac] ^
    [javac] Note: C:\Users\usuario\AppData\Local\Temp\android3109560753686470828sketch\src\processing\test\sketch_130202a\sketch_130202a.java uses unchecked or unsafe operations.
    [javac] Note: Recompile with -Xlint:unchecked for details.
    [javac] 1 error

    BUILD FAILED
    C:\Users\usuario\Desktop\adt-bundle-windows-x86_64\sdk\tools\ant\build.xml:710: The following error occurred while executing this line:
    C:\Users\usuario\Desktop\adt-bundle-windows-x86_64\sdk\tools\ant\build.xml:723: Compile failed; see the compiler error output for details.

  69. Andrey says:

    Esta relacion al conecta dispositivo El simbolo UUID no lo reconoce no se porque en ese caso que debo hacer?? gracias

  70. Andrey says:

    Si ya solucione todo eso ahora conecto mi tablet samsumng galaxy note II y sale esto en el cuadro de run

    debug:
    Shutting down any existing adb server…

  71. andrey caro says:

    Igual sin debug aparece eso y device no se conecta :s

    • Oscar says:

      Pero lo estás ejecutando en el samsumg o en el PC? Al tener librerías bluetooth sólo funciona en el samsumg directamente.

  72. Pete says:

    Hi
    When running the whole program in processing i keep getting an error in line 227 (Incomptible types).
    Does anyone recgionize this error and do you have any solutions for it.

    When commenting this line out i can get the aplication to compile and run on my Nexus 7. It even sees the BT module i have on my embedded board.

    Any help is greatly appreciated

    Processing 2.0b7

    • Oscar says:

      With socket.connect(); ?

      • Pete says:

        Sorry. I did not understand that.

        • Oscar says:

          The line contains socket.connect();?

          • Pete says:

            void conectaDispositivo ( )
            {
            try
            {
            socket = // Method m = dispositivo.getClass().getMethod(“createRfcommSocket”, new Class[] { int.class });
            // socket = (BluetoothSocket) m.invoke(dispositivo, 1);

            socket. connect ( ) ; // line 225
            ins = socket. getInputStream ( ) ;
            ons = socket. getOutputStream ( ) ;

            the compiler reports “Incompatible Types” and halts in line 225

            Pete

  73. Julian David Rua Pino says:

    Hola buenos días me podrías compartir por favor este proyecto de ejemplo ya que con este código no e logrado compilarlo, ya que me saca error en varias clases que no esta en el código que publicaste, te lo agradecería enormemente, por que a partir de esto puedo seguir con mi proyecto.

    gracias quedo atento

  74. jose hinestroza says:

    Muchas gracias por compartir esta informacion!

  75. Alberto Esteban says:

    Hola buenas, antes de nada felicitarte por el pedazo de curro que has hecho.

    Estoy intentando seguir tus pasos pero a la hora de compilar me da un error en la linea de codigo siguiente:

    socket = dispositivo.createRfcommSocketToServiceRecord(UUID.fromString(“00001101-0000-1000-8000-00805F9B34FB”));

    Y no me da mucha explicación, por lo que no puedo buscar por mi cuenta.

    Tambien tengo que decir que estoy compilando el sketch en emulador y puede ser el motivo…pero no lo se.

    Si me pudieses ayudar te lo estaría muy agradecido.

    Saludos y otra vez felicidades.

    Mil gracias

  76. john lunt says:

    Brilliant job Oscar. But did you forget to import java.util.UUID?

  77. Lisergio says:

    Buenas e nuevo….

    Estoy intentando hacer algo similar pero con processing en el pc…. Y tengo una duda…

    Cuando configuras el puerto serie en processing… Usando la siguiente linea.

    myPort = new Serial(this, Serial.list()[0], 9600);

    Donde [0] es el puerto que corresponde con la placa arduino ( ya sea usando el cable usb o un puerto serie bt….

    Mi problema biene cuando cambio de puerto o uso otro adaptador serie, que el puerto cambia, por lo que hay que cambiar este numero con el que corresponda….

    Para saber cual es basta con hacer un porlist…

    println(Serial.list());

    Pero …. Y aqui viene mi duda… Como se puede hacer, que el programa se detenga, nos muestre la lista de los puertos disponibles ,con un numero asignado a cada uno ( que ya es asi, el primero es el 0, luego el 1 y asi sucesivamente…). y espere a que seleccionemos uno de esos numeros para continuar la ejecucion del sketch usando ese numero de puerto ?

    Perdon por la chapa….

    Gracias por la ayuda!

  78. szitko says:

    Why does not work on android version 4.0.4?
    Version 2.3.7 worked.

    • Oscar says:

      No idea. What kind of error do you have?

      • szitko says:

        My bluetooth is not pairing with my device HC-05 module.
        It says “paired but not connected”
        When I run the program, the background is always the password when prompted in.
        I in write, but does not connect to.

  79. heavy says:

    hola. por favor estoy intentando copilar pero el instante de cargar me sale cannot find symbol y mee subraya la linea de socket = dispositivo.createRfcommSocketToServiceRecord(UUID.fromString(“00001101-0000-1000-8000-00805F9B34FB”));

    activo las otras dos pero por nuingun motivo funciona por favor si me podrias ayuda.gracias

  80. heavy says:

    Primero te agradesco Oscar. Quisiera saber en que linea puedo comenzar para crear una pantalla donde pueda ver una senal analogica ayudame por favor es para mi proyecto final de la universidad.gracias

  81. jose says:

    hola Oscar buen dia amigo de verdad me interesa esto ya que estoy tratando de conectar una banda polar wearlink plus bluetooth, y de verdad soy algo nuevo por lo que seria de gran apoyo si me aconsejas ya que existe poco material acerca de esto por favor ayuda :(

  82. deux says:

    porque me marca error en esa linea? xfa si puedes ayudame

    socket = dispositivo.createRfcommSocketToServiceRecord(UUID.fromString(“00001101-0000-1000-8000-00805F9B34FB”));

  83. jose says:

    Buen dia Oscar sera que permitirias la aplicacion corriendo es que la necesito para entender mejor que hay cosas que no comprendo te dejo mi correo jose_xp_799@hotmail.com grax de ante mano :D

Leave a Reply

Subscribe to RSS Feed Follow me on Twitter!