Processing + Arduino + touchOSC

[singlepic id=746 w=320 h=240 float=center]
Hoy veremos la forma de comunicar nuestro dispositivo móvil android/ipad/iphone/iphone con nuestra PC, por medio de un protocolo conocido como OSC (Open Sound Control), comúnmente este protocolo se utiliza para el control de luminaria y dispositivos como estrobos, secuenciadores y otras cosas usadas en el mundo musical, se podría decir que es el reemplazo del protocolo MIDI. OSC usa el protocolo de internet UDP para realizar la comunicación, por esa razón como requisito necesitamos que los dispositivos se encuentran en la misma red, conocer su dirección IP y abrir un puerto de comunicación.

Para el siguiente acto necesitaremos: processing, arduino, led RGB, dispositivo con touchOSC instalado. Pero que haremos exactamente??… Crearemos una plantilla personalizada con el touchOSC editor, la cual usaremos como control para variar la intensidad de un led RGB y poder crear combinaciones de colores, abriremos un enlace de comunicación entre processing y touchOSC, por ultimo mandaremos toda la informacion recibida a una placa arduino conectada por el puerto serie y veremos el resultado obtenido en el led RGB, al final de todo esto tendremos el siguiente resultado:

Pues comencemos, lo primero que debemos hacer es crear nuestra plantilla para el touchOSC y cargarla al dispositivo, para esto usaremos el touchOSC Editor una herramienta creada por Hexler que podemos descargar de aquí, usaremos tres controles tipo fader con resolucion de un byte (0-255) para variar la intensidad del led, para ello seguimos los siguientes pasos del videotutorial:

Ahora toca abrir processing, pero antes de empezar a tirar lineas de codigo debemos instalar una libreria especifica para el la comunicacion con OSC, usaremos la libreria oscP5 creada por Andreas Schlegel y podemos descargarla aqui, la descomprimos y movemos su contenido a documentos/processing/libraries, una vez instalada ahora si abrimos un nuevo sketch.

Crearemos una clase Fader que usaremos como control y para visualizar la interaccion con el dispositivo movil, este control sera lo mas parecido al fader y con las mismas propiedades que usamos en nuestra plantilla, la clase final para el Fader queda de la siguiente manera:

[code language=java]
class Fader {

int val, valMap;
int px, py;
final int h=300, w=70;
color[] col;

color[] red= {
color(#DE1D2A), color(#131010), color(#501515)
};
color[] green= {
color(#3B811C), color(#111410), color(#25451A)
};
color[] blue= {
color(#1C2D81), color(#0D0D10), color(#0C1233)
};

Fader(int px, int py, char c) {
this.px=px;
this.py=py;

switch(c) {
case ‘R’:
col=red;
break;
case ‘G’:
col=green;
break;
case ‘B’:
col=blue;
break;
}
setValue(0);
}

void draw() {
strokeWeight(4);
strokeJoin(ROUND);
stroke(col[0]);
fill(col[1]);
rect(px, py, w, h);
fill(col[2]);
rect(px, py+(h-valMap), w, valMap);

if (mousePressed && (mouseX>=px && mouseX=py && mouseY< =py+h)) {
setValue((int)map((h-(mouseY-py)), 0, h, 0, 255));
}
}

void setValue(int val) {
this.val=val;
valMap=int(map(val, 0, 255, 0, h));
}

int getValue() {
return val;
}
}
[/code]

Despues crearemos nuestra plantilla personalizada, para esto haremos uso de vectores con las direcciones de cada uno de nuestros controles, estas direcciones son del url y las definimos cuando creamos nuestra plantilla con el editor. La clase de nuestra plantilla queda asi:
[code language=java]
class RGBLayout {

//Creamos nuestras direcciones para recibir datos
//Estos nombres los pusimos al crear la plantilla
//en el touchOSC editor /Pagina/Direccion
String[] Addr= {
“/RGB/fdrRed”,
“/RGB/fdrGreen”,
“/RGB/fdrBlue”,
};

//Creamos un vector para guardar los datos recibidos
//crea tantas variables como direcciones tenga nuestra plantilla
float[] Data= new float[Addr.length];

//Por default touOSC usa el typetag “f” como identificador
String Typetag=”f”;

//Con este metodo comprobaremos si la informacion debe ser procesada
void check(OscMessage theOscMessage) {

//Para cada direccion en nuestra plantilla
for (int i = 0; i < Addr.length; i++) {
//Verfica si la informacion enviada coincide con alguna direccion
if (theOscMessage.checkAddrPattern(Addr[i])==true) {
//Comprueba que coincida el idenificador
if (theOscMessage.checkTypetag(Typetag)) {
//Guardamos el valor de la direccion en el vector Data
Data[i] = theOscMessage.get(0).floatValue();
//Imprime la direccion y el nuevo valor que tomo
println(Addr[i]+" = "+ Data[i]);
}
}
}
//En caso de que no coincida ninguna direccion, se ignora la info
}

//imprime la informacion de todas nuestras variables
void printData() {
println(Data);
}

//imprime el nombre de nuestros objetos
void printAddr() {
println(Addr);
}
}
[/code]

Y por ultimo nuestro programa principal, en este debemos importar las librerias oscP5 y netP5 para que funcione correctamente, crearemos objetos de las clases definidas anteriormemte y verificaremos los datos recibidos para posterioremente mandarlas al arduino por el puerto serie, y nuestro programa principal queda asi:
[code language=java]
//importamos librerias necesarias
import oscP5.*;
import netP5.*;
import processing.serial.*;

OscP5 oscP5;
Serial serial;
RGBLayout layout;

//Creamos tres objetos Fader, uno por color
Fader fdrRed;
Fader fdrGreen;
Fader fdrBlue;

//variables para la intensidad de color
int r, g, b;
//PImage logo;

void setup() {
size(600, 320);
smooth();

//creamos el objeto OSC en el puerto 8000
oscP5 = new OscP5(this, 8000);
//creamos la plantilla de touchOSC a usar
layout= new RGBLayout();
//intentamos abrir el puerto serial
try {
serial = new Serial(this, Serial.list()[0], 9600);
}
//en caso de error tendremos una excepcion
catch(Exception e) {
println(“Error al abrir puerto serial…”);
}
//muestra el direccionamiento de la plantilla
layout.printAddr();

//creamos los faders
fdrRed=new Fader(10, 10, ‘R’);//px, py, color
fdrGreen=new Fader(90, 10, ‘G’);
fdrBlue=new Fader(170, 10, ‘B’);

//cargamos la marca de agua
//logo=loadImage(“watermark.png”);
}

void draw() {
//Dibujamos los faders
fdrRed.draw();
fdrGreen.draw();
fdrBlue.draw();

//Guardamos el valor del fader en la variable
r=fdrRed.getValue();
g=fdrGreen.getValue();
b=fdrBlue.getValue();

//intentamos escribir el PS
try {
//comando para color r y su valor
serial.write(114);
serial.write(r);
//comando para color g y su valor
serial.write(103);
serial.write(g);
//comando para color b y su valor
serial.write(98);
serial.write(b);
}
//en caso de error tendremos una excepcion
catch(Exception e) {
println(“Error con el puerto serial, no se puede escribir…”);
}

//Dibujamos cuadro con colores mezclados
stroke(0);
fill(color(r, g, b));
rect(270, 10, 300, 300);

//image(logo, 450, 240);
}

//Este evento ocurre cada vez que llega informacion desde OCS
//theOSCMessage lleva toda la informacion recibida
void oscEvent(OscMessage theOscMessage) {
//verificamos si coincide la informacion con nuestra plantilla
layout.check(theOscMessage);

//los faders toman el valor enviado
fdrRed.setValue((int) layout.Data[0]);
fdrGreen.setValue((int)layout.Data[1]);
fdrBlue.setValue((int) layout.Data[2]);
}
[/code]

Ahora si para finalizar necesitamos que la placa arduino procese los datos recibidos, para ello crearemos un algoritmo que reciba un byte y determine si es un comando, una vez que determina el comando espera otro valor para almacenarlo en la variable correspondiente, para variar la intensidad del led usaremos los pines de PWM de arduino usando la funcion analogOut().

[code language=java]
//dato recibido
int inByte = 0;
//Pines de los leds
int led[]={
6,5,3};
//led a modificar
int currLed;
//bandera de valor recibido
boolean commandFlag=0;
//led de espera de valor
const int ledCom=13;

void setup()
{
//salida led R
pinMode(led[0], OUTPUT);
//salida led G
pinMode(led[1], OUTPUT);
//salida led B
pinMode(led[2], OUTPUT);
//salida led comando
pinMode(ledCom, OUTPUT);

//Inicializa comunicacion serial a 9600bps
Serial.begin(9600);
Serial.print(“Conectado…”);
}

void loop()
{
//si hay datos en el bufer del puerto
if (Serial.available() > 0) {
//leemos valor recibido
inByte = Serial.read();

//si un comando espera valor
if (commandFlag){
//modificamos la intensidad del led seleccionado
analogWrite(led[currLed],inByte);
//reiniciamos bandera y led de comando
commandFlag=false;
digitalWrite(ledCom, LOW);
}
//Si esparamos un comando
else
{
//Elegimos que led modificar
//modificamos bandera y led de comando
switch (inByte){
case 114://r ascii
currLed=0;
digitalWrite(ledCom, HIGH);
commandFlag=1;
break;
case 103://g ascii
currLed=1;
digitalWrite(ledCom, HIGH);
commandFlag=1;
break;
case 98://b ascii
currLed=2;
digitalWrite(ledCom, HIGH);
commandFlag=1;
break;
}
}
}
}
[/code]

Fue un post un poco largo, espero que no se hayan aburrido. No olvides dejar tus comentarios al final de la pagina 😉

Adrian MB

Me gusta la electrónica, programación y todo lo relacionado. Ing. en Mecatronica de la UPIITA del IPN y estudiante de Diseño Industrial en la UAM. @adrianmtzb http://adrianmb.mx

También te podría gustar...

  • Ray

    perdona se me olvido preguntarte mediante un ruter wifi conectado al ethernet shield?

  • Ray

    hola me puedes ayudar con un proyecto que tengo este post me ayuda pero funciona con un arduino uno y el ethernet shield

    gracias

  • rod

    Hola, está genial, gracias por el post.
    ¿Qué software utilizas para que te aparezcan las imágenes de una webcam en el screencat? es algún programa opensource?

    • El screencast lo hice con screenFlow y la parte del circuito lo grabe con una cámara aparte, después solo lo agregue y sincronice con el editor de screenflow, es decir el video del circuito esta sobrepuesto.

      Saludos

  • Cesar

    Muchas gracias por el post! esta muy educativo para un principiante!
    Saludos desde chile

  • Roger

    Excelente, te quedo muy padre 😀