miércoles, 23 de mayo de 2012

Processing

Processing es un entorno de programación que sirve para programar una multitud de cosas de forma fácil y rápida sin preocuparnos demasiado por las entrañas del hardware utilizado. Puede ser utilizado tanto para aplicaciones locales así como aplicaciones para la web (Applets). Se distribuye bajo la licencia GNU GPL.



Actualmente se pueden ejecutar sketchs dentro de móviles con Android como sistema operativo, 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.






En esta entrada explicare los pasos a seguir para hacer la comunicación entre processing y un dispositivo android.


Con processing se programa nuestra propia aplicación con su propia interfaz para cualquier dispositivo que tenga un controlador bluetooth.

Primeramente tenemos que tener instalado el programa:


1) Descargamos el Android SDK

Debes descomprimir el archivo zip en un directorio y abrir el directorio "tools" y ejecutar el archivo ejecutable "Android" que abrirá el AVD Manager tal y como se muestra aqui:


Aqui necesitaremos añadir el repositorio de Android e instalar todos sus componentes. Para eso, debemos hacer click sobre la izquierda en "Available Packages" y marcar la opción central que aparece en pantalla. El manager conectará con el repositorio de android y mostrará los componentes disponibles para descargar:


Aqui podemos seleccionar todos los elementos para tener el sistema de desarrollo completo. Una vez instalado, necesitamos instalar una versión especial para Android de Processing.


Ahora les mostraré como hacer un programa simple

void setup() {  
   size(480,800);  
  
   smooth();  
   noStroke();  
   fill(255);  
   rectMode(CENTER);     //Esto permite a los rectangulos aparecer  
};  
  
void draw() {  
   background(#FF9900);  
   rect(width/2, height/2, 150, 150);  
};
Si presionamos el boton "Run" (Ejecutar) Processing compilará nuestro programa en un archivo Applet temporal de Java que se ejecutará en una ventana individual. Para los que ya conocen Processing, es la forma habitual de trabajo. Para compilarlo para Android, debemos selecionar "Android Mode" en el menu y podremos ver la plicación en el emulador al pulsar como "Run":







NOTA: La primera ver que ejecutes el emulador, se mostrará un mensaje indicando que Android SDK no ha sido instalada. Pulsa "Yes" y selecciona el directorio de los archivos del SDK que previamente has copiado en un directorio. Una vez hecho, ejecuta tu programa otra vez.

Ten en cuenta que el emulador tarda su tiempo en inicializarse y ejecutar el programa por lo que ten paciencia :)

Tenemos ya todo el sistema funcionando y es por supuesto muy emocionante, pero aqui falta algo no? Vamos ejecutar nuestro programa en un dispositivo Android real!

Para ejecutar un programa en dispositivo android tenemos que seguir los siguientes pasos:

1) Para que funcione, es importante que tu dispositivo android tenga la opción "USB debugging" activada". Puedes activarla en Configuración -> Aplicaciones -> Desarrollo.

2) Ahora conecta tu dispositivo por USB y selecciona Sketch -> Present desde el menu:



Ahora vamos a probar la conexión de Bluetooth

Para esto vamos a 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. 

Este es el código


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);
}
///////////////////////////////////////////////////////////////////////////////////

Bibliografía
Processing + Android + Bluetooth
Como programar un android con processing

2 comentarios:

  1. Excelente post, práctico, funcional y muy buen ejemplo. Me estoy iniciando en la programación de móviles. Un saludo cordial desde Guatemala.

    ResponderEliminar