Category Archives: DIY

Arduino – MPU6050

Thumbnail_1244x700_128Cs English version Resulta que hace tiempo compré una plaquita MPU6050 que no había echado a andar aún y estos días he estado trasteando con ella. MPU6050 Si todo va bien, este post contendrá información práctica para utilizar el sensor: conexión, calibración testeo etc. Mi contribución consistirá en el desarrollo de un pequeño script, que junto con un cierto sketch para Arduino permite recibir las mediciones en Matlab. Como siempre, el código, los links necesarios y una demo en vídeo se incluirán por alguna parte del post por si quieres reproducir alguno de los pasos. La plaquita MPU6050 incluye un acelerómetro y un giróscopo de tres ejes que comunica por I2C (con dos direcciones posibles) y sirve entre otras cosas para medir aceleraciones y ángulos. Puedes encontrar información algo más detallada en Arduino Playground.


Conexión


La conexión estándar involucra los pines VSS, GND, SCL y SDA; aunque algunos sketches disponibles en internet requieren también el pin INT. La conexión entre el sensor y la placa Arduino UNO sigue el siguiente esquema. MPU6050_Scheme


Librerías


Antes de comenzar con la “diversión”, es necesario algunos (aburridos) preparativos relacionados con las librerías. Primero, se tienen que descargar e instalar dos librerías: I2Cdevlib and MPU6050. La primera lidia con temas de comunicación I2C mientras que la segunda incluye algunas funciones útiles para configurar y operar el sensor. Ambas librerías pueden descargarse desde AQUÍ. El proceso de instalación es tan sencillo como copiar la carpeta de ambas librerías en la ruta de instalación del IDE de Arduino (típicamente c:/Program Files (x86)/Arduino/libraries). Hay varias formas de chequear que todo está correctamente conectado, por ejemplo utilizando uno de los sketches de prueba que vienen con la librería MPU6050. Arduino IDE- Archivo – Ejemplos – MPU6050 – MPU6050_DMP6. Este archivo comprueba las conexiones, inicializa el dispositivo e implementa un bucle en el que se transmiten por el puerto serie las aceleraciones medidas. Si todo va bien, en el monitor del puerto serie deberías ver algo parecido a lo siguiente. Library_ok


Calibración


Si te ha funcionado el sketch anterior, seguimos con los preparativos. Este tipo de sensores suele presentar cierto error en la medida, ya sea por la presencia de deriva o de offset en los datos. Estas desviaciones son propias para cada dispositivo y en general, diferente para cada uno de ellos. El sketch del apartado anterior contiene un conjunto de líneas (al rededor de la línea #200) donde se introducen unos ciertos valores de offset con la intención de corregirlos. Evidentemente, esos valores serán en general distintos para cada dispositivo por lo que sería interesante saber cómo obtenerlos. Para ello, en i2cdevlib.com hay accesible un sketch muy útil que facilita la tarea: MPU6050_Calibration_v1.1.zip. Solo necesitas cargar el código, abrir el monitor serie, colocar el sensor lo más horizontal posible y esperar. Cuando el proceso termina, verás un conjunto de mensajes como los siguientes donde encontrarás los valores buscados. CalibrationA partir de ahora, deberías tener en cuenta estos valores e incluirlos en todos los sketches que programes.


TEAPOT demo


El código usado anteriormente (DMP6) para testear que todo estaba conectado correctamente esconde una interesante demo llamada “teapot demo” que consiste básicamente en la representación 3D de una especia de avión que se orienta en función de la posición del sensor. Para conseguir ejecutarlo hay que realizar algunos pasos.

Primero tienes que comentar la línea 100 del sketch

#define OUTPUT\_READABLE\_YAWPITCHROLL

y descomentar la línea 117:

#define OUTPUT\_TEAPOT}

Esto cambia el comportamiento del código y formatea de forma adecuada los datos a transmitir. Además necesitarás instalar Processing y añadir (en Processing) la librería toxi. La instalación de la librería es tan simple como colocar la estructura de carpetas en el subdirectorio de librerías de Processing que usualmente se encuentra en UserName/Documents/processing/libraries. Posteriormente, abre el archivo de la demo MPUTeaPot para processing que se encuentra en ArduinoIdePath/libraries/MPU6050/Examples/MPU6050_DMP6/Processing/MPUTeapot. Una vez hecho esto, si cargas el código en Arduino y ejecutas el archivo de Processing, aparecerá algo similar a esto: ANIMA_TeaPotLo cual indica que estamos listos para generar nuestras propias aplicaciones con este útil sensor de bajo coste.


Matlab


Esto no podía acabar sin la aparición en escena de Matlab. Por alguna malvada razón, me resulta interesante poder leer y procesar los ángulos medidos por el sensor en tiempo real desde Matlab, y una buena forma de generar el código necesario es intentando reproducir la “TeaPot” demo. Para ello, básicamente modifiqué ligeramente el código DMP6 para adaptar el formato de los mensajes a mis necesidades y luego programé un script en Matlab que lee asíncronamente la información del sensor y la usa para pintar un cubo 3D.

ANIMA_Gif Dado que la velocidad de transmisión del sensor probablemente sea mayor que la velocidad a la que se realiza el postprocesamiento en Matlab, es recomendable implementar una lectura asíncrona del puerto serie. Lo cual en mi caso, no fue algo trivial. La solución la encontré en mathworks y lo dejo enlazado por aquí por si pudiese ser de interés.


The End


Y esto es todo por hoy. Todos los sketches y scripts usados en el post están accesibles AQUÍ. Espero usar esta conexión MPU Matlab en algunos mini-proyectos futuros y, como podrás imaginar, tengo la firma intención de publicarlos. Hasta entonces, os dejo tranquilos. Si te ha sido útil la información recopilada, pulsa like!, comparte! o lo que sea!. Nos vemos pronto.

Tagged , , , ,

DIY – Disparador automático con Arduino

Thumbnail

English Version

Resulta que llevo algún tiempo queriendo mancharme las manos con algún proyectito con Arduino y casualmente estos días, leyendo sobre fotografía, he encontrado uno bastante simpático. Inicialmente la idea era desarrollar un disparador remoto para la cámara pero, tras algún que otro problema técnico con el módulo bluetooth que tengo en casa, se quedó en un disparador automático. Esto podría ser interesante por ejemplo para hacer timelapses con poco esfuerzo (el timelapse del gif se ha hecho con este cacharrito).

TImeLapse_1400kb

El cambio no es demasiado traumático puesto que la parte interesante, disparar fotografías con un Arduino, se tiene que resolver igualmente. Una vez que se consigue esto, la razón por la que se disparen pasa a un segundo plano. Antes de seguir con la parte “aburrida”, adjunto un pequeño video en el que se ve el conjunto funcionando.

El primer problema que aparece es cómo comandar el disparo de la cámara con un microcontrolador? Pues resulta que la serie Canon EOS permite hacer esto a través del conector minijack 1.5 mm. No se demasiado sobre otras marcas/series de cámaras pero igualmente debería existir una forma de hacer esto. Aunque parezca sorprendente, tan solo conectando un cable al conector y puenteando Shutter-GND o Focus-GND se consigue que la cámara enfoque o dispare.

Mini_Jack

Obviamente, la forma más directa de hacer esto con un Arudino es usando un par de transistores o optoacopladores conectados dos salidas digitales. El interés de usar optoacoplaores (más concretamente el 4N35) en lugar de transistores reside en conseguir aislar el circuito de la cámara del Arduino y así asegurarnos que ninguna corriente no deseable se cuela en la cámara. Obviamente esto es opcional. El esquema básico es el siguiente.

Schematics

Importante lo de las resistencias a la entrada de los optoacopladores si no los quieres quemar jeje.

El circuito montado sobre una protoboard tiene la siguiente pinta.

Automatic_Shutter_V1

y conectado con la cámara…

Arduino_Camera

Una vez se tiene claro que la cosa funciona bien pasamos a montar una plaquita más compacta

Automatic_Shutter_V2

El código escrito para Arduino no tiene mucho misterio.

void setup() {
   pinMode(8, OUTPUT);
   pinMode(9, OUTPUT);
   digitalWrite(8, LOW);
   digitalWrite(9, LOW);
}

void loop() {
   digitalWrite(8, HIGH); // Focus
   delay(1500); // wait 1.5 second
   digitalWrite(9, HIGH); // Say cheese!
   delay(1000); // wait 1 second
   digitalWrite(8, LOW); 
   digitalWrite(9, LOW);
   delay(2000); 
}

Y listo. Es un proyectito bastante simple y, si os gusta la fotografía, podría seros útil en algún momento. Para cualquier pregunta, comentario o consejo, comenta!

Nos vemos pronto.

Tagged , , , , , ,

Visión por computador: Tracking!

Head_Tracking_594_Kb

English Version

Resulta que  existen infinitas formas inteligentes de realizar el tracking the un objeto en una imagen: usando descriptores de características, flujo óptico, colores, filtro de Kalman etc. Puesto que no soy un genio, y aprovechando un tracking simplificado que he hecho hace poco para un proyecto de clase (código disponible AQUÍ), me gustaría comentaros algunas de las dificultades generales que hay que resolver.

Hoy empezarmeos la casa por el tejado: Resultados!. Gifs, gifs y más gifs. He aquí un pequeño gif del código funcionando.

prueba_904KB—————————-Cómo implementar esto?—————————-

Una aplicación completa de tracking no tiene que resolver únicamente el proceso de seguimiento en sí mismo, sino que tiene que lidiar con varios problemas que lo acompañan.

  • Cómo comenzar el seguimiento? Qué estoy buscando?
  • Seguimiento: conozco dónde estaba el objetivo en el instante anterior, dónde debería buscar ahora? puedo simplificar el proceso?
  • Y si pierdo el objeto en medio del seguimiento, qué hago?

Puede parecer fácil… sólo tres aspectos a resolver?… mejor no subestimemos a Murphy no vaya ser que se complique la cosa. El siguiente diagrama da una visión general del procedimiento que yo decidí plantear.

FlowChart_EN

Lo primero que tenemos que tener en mente es que conocemos exactamente el objeo que estamos persiguiendo!. Lo creas o no, no siempre pasa. Esto quiere decir que siempre que el objeto esté a la vista, podremos localizar su posición. Esto no suele ser cierto en condiciones no controladas por muchas razones. La más inmediata es el hecho de que es imposible caracterizar un objeto teniendo en cuenta todas las posibles iluminaciones a las que puede estar sometida. Entre otras cosas porque un ordenador no puede saber si un objeto a cambiado su color a causa de una iluminación desafortunada, o simplemente es un objeto diferente. Vale… y si consideramos que la iluminación es conocida? (Simplificaciones!!). El algoritmo que aquí se comenta es bastante simple así que necesitamos bastantes simplificaciones (sinceramente, algunas de ellas un tanto “groseras”), y considerar que las iluminación está controlada es la primera.

—————————-Objetivo—————————-

Dicho esto, hablemos sobre el objetivo. Vamos a considerar el objetivo más sencillo de rastrear que existe: “una forma negra sobre fondo blanco” o lo que es lo mismo, un trocito de cinta aislante en medio de un A3.

Target

—————————-Tracking—————————-

En esto de explicar algoritmos no suele aplicar eso de “lo primero es lo primero”, suele ser más útil entender el funcionamiento normal del algoritmo y luego ver excepciones, y transitorios de inicio y finalización; que es justo lo que haremos.

Asumamos primero que conocíamos la posición del objeto en el instante anterior. Esto nos da algo con lo que trabajar. Esta información nos permite colocar una “ventana de búsqueda” centrada en \hat{x}_t = x_t + v_t y de tamaño W_{t} = f(v_{t-1}) para no tener que buscar el objeto en toda la imagen. En otras palabras: el objeto se busca en torno al punto en el que suponemos que va a estar el objeto atendiendo a los datos pasados, y el tamaño de esa región de búsqueda dependerá de alguna forma de la incertidumbre de esa estimación. La siguiente imagen intenta mostrar por qué el tamaño de la ventana es una función de la velocidad.

Window_24Kb

Ok,ya tenemos la ventana de búsqueda bien situada, ahora qué? cómo refinamos la posición? esto suele ser complicado y normalmente requiere trabajo previo de caracterización del objeto a rastrear, por ejemplo, usando descriptores binarios invariantes… pero hoy no! Estamos buscando algo oscuro en un fondo blanco y esto facilita mucho el proceso. Nuestra solución particular consiste en: recortar la imagen para quedarnos sólo con la ventana de búsqueda, umbralizarla, invertirla, y calcular el centro de masa… eso es todo. Después de haber solucionado las cosas difíciles, esto es muy simple :).

Target_Location_17kB

—————————-Proceso de reenganche—————————-

Qué hacemos si no sabemos dónde está el objeto en el instante anterior? pues tenemos algunas alternativas, entre ellas:

  • Buscar actívamente el objeto. Esto consume tiempo y capacidad de cálculo puesto que habría que analizar la imagen completa sin saber si quiera si el objeto está a la vista.
  • Respuesta pasiva. Lo hemos perdido… pues nada, esperaremos justo en el sitio donde lo hemos perdido hasta que pase por aquí y nos reenganchamos.

La segunda alternativa es más simple por lo que, adivinas qué vamos a hacer? exactamente, ninguna de las anterior… nah, I’m kidding, la segunda xD. Para nosotros es suficiente esa opción puesto que no vamos a usar la aplicación para nada serio, en tal caso, seguramente la primera opción sería más adecuada.

Y se acabó! Esto ha sido todo por hoy. Os animo a que probéis el código, o mejor, a que implementéis vuestros propios algoritmos de seguimiento y los compartáis por aquí en los comentarios.

Hasta la próxima!

Tagged , , , , , , , ,

Dibujo Paramétrico – #2 – Drawing Apparatus

Head_Full_Size_Web

English Version.

Resulta que el último post ha abierto mi caja de pandora particular. Hay bastantes “máquinas de dibujo” ahí fuera y siento herir sensibilidades (espero que no) pero tengo la neceidad imperiosa de hablar sobre ellas xD. Hoy me gustaría empezar por una bastante simple conocida como “Drawing apparatus” (o bien “dibujando con dos tocadiscos”) diseñada por Robert Howsare. Seguro que has visto el vídeo en internet en algún momento, y sino, no se a qué estás esperando –> Sitio Oficial

En su página oficial puedes encontrar ejemplos de algunas figuras hechas con el cacharrito. Cuando vi los dibujos nació en mi el antojo de generar y digitalizar ese tipo de formas. No tengo tocadiscos pero todo lo que necesito es Matlab y un poquitín de tiempo! Hay algo que no se pueda hacer con Matlab? jojojo .La objetivo es simplemente simular el mecanismo y jugar un rato.

Como puedes ver en el video de su página web, la máquina consiste en dos vinilos girando a diferente velocidad con un mecanismo de cuatro barras anexo. Una de las articulaciones del mecanismo sujeta un lápiz que será el que pinte el patrón.

Ahora bien… un pequeño atajo. Como puedes estar pensando (y si no, aquí estoy yo para inducirte a pensarlo) la cinemática de este mecanismo se puede resolver analíticamente planteando sus ecuaciones trigonométricas, recordando las relaciones trigonométricas “chulas” y obteniendo la solución. Sinceramente, no soy demasiado amigo de los cosenos así que optaré por calcular las posiciones de forma “iterativa”.

Además, estos días he estado aprendiendo a generar pequeñas interfaces gráficas con Matlab, así que aprovecharé este mini proyecto para entrenar un poco más. La idea de la interfaz gráfica es poder modificar los parámetros relativos a la geometría y operación del mecanismo (y por tanto el resultado). Lo siguiente es una captura de cómo se ve la aplicación (por cierto el código disponible aquí).

Snapshot

Una vez especificada la geometría, se puede dibujar el mecanismo (parado) para chequear que todo está bien y comenzar la simulación. Se genera una animación para ver el mecanismo funcionando.

RES_S1_52Mb

Solo un par de comentarios adiconales antes de irme. El primero relativo a las velocidades. Hay que tener en cuenta que no todas las velocidades funcionan “bien”. Dependiendo de los valores, el resultado será má so menos interesante. No puedo dar una regla de oro pero, como consejo general, se debería intentar escoger velocidades cuyo ciclo de repetición sea largo. Por ejemplo, si estableces una velocidad de 1 y 2, en cuestión de dos vueltas el mecanismo está justo en la misma posición que al principio, por lo que el patrón no será demasiado interesante.

Finalmente, esto se puede usar en Illustrator para hacer un poco de magia? Pues SI! en Matlab se pueden guardar las figuras en formato *.eps usando el comando “print”. Básicamente eso es lo que hace el botón etiquetado como “Save” de la interfaz. Obviamente, una vez en illustrator, podemos hacer lo que sea con el gráfico. He aquí mi intento:

Test_Web

Hay otras máquinas de dibujo más locas que estas, y espero escribir sobre ellas en futuros posts. Espero que te haya interesado el post, y que propongas lo que sea en los comentarios. Nos vemos pronto!.

Cuidate!.

Tagged , , , , , , ,

DIY: Scanimations

Head_Scanimation_1920

English version.

Resulta que acabo de abrir los ojos y es 2015! (feliz año nuevo por cierto). La consecuencia de las navidades es una cola de posts pendientes esperando a que los exámenes me dejen un par de minutillos libres para ser escritos (además de un par de kilitos de polvorones).

Estas Navidades, buscando algún regalo creativo encontré un par de vídeos que me llamaron la atención. Seguramente los hayas visto alguna vez… En el vídeo se veía cómo con una lámina de acetato en la que había impresa una especia de “código de barras” y un folio con una “imagen codificada” se generaba una animación al mover una capa sobre la otra. Tal como leí en algún sitio, parecía un gif sacado de la pantalla. Tras un poco de investigación di con el nombre de la criatura (tambores)… Scanimation! Resulta que es el nombre que reciben estas animaciones (basadas en algo llamado “patrones de Marié” (wiki)).

Es muy interesante cómo algo tan aparentemente simple puede generar tal efecto así que, rápidamente me puse manos a la obra para ver si era capaz de hacer uno “hecho en casa”! Como intuirás, las herramientas que utilicé son Photoshpo, Illustrator (opcional), y en este caso Matlab, y parece que me he acercado a la solución (siento la mala calidad pero si no quería postear imágenes demasiado pesadas es lo que hay 😦 , para verlo un poco mejor -> Youtube ) :

GIF_Prop

Figura 1: Ejemplo.

El mecanismo es muy simple. La historia está en que según la posición en la que esté el acetato, solo podamos ver UN frame de la animación. Dicho esto, un hipotético flujo de trabajo podría ser:

  1. Coger un frame de la animación.
  2. Poner el acetato encima en una posición.
  3. Eliminar el contenido del frame que queda oculto por las columnas opacas del “código de barras”.
  4. Desplazar el acetato a una nueva posición y volver al paso #1 (con el siguiente frame).

Como podrás imaginar, hay un par de problemas que hay que resolver antes de pasar a la acción. Más específicamente, problemas relacionados con cómo generar el código de barras “mágico”?… bien, como puedes ver en la animación anterior, el código de barras que se desliza es un patrón repetitivo, por tanto, con fijar el ancho de las columnas transparentes-opacas es suficiente no? Obviamente es justo ahí donde está la miga del asunto. Para conseguir generar el efecto, la relación entre el ancho de las columnas opacas y el ancho de las columnas transparentes viene fijado por el número de frames que tenga la animación… QUÉÉ?… nada.. que el grosor de las columnas negras depende del grosor de las columnas transparentes, y además del número de frames que tenga la animación. En caso de tener una animación con N frames, debe cumplirse lo siguiente:

Ancho_{Opaco} = (N-1)\cdot Ancho_{Transparente}

Por tanto, para generar el patrón del acetato, lo primero que tenemos que hacer es fijar el ancho de la columna transparente y lo demás viene rodado. Ahora bien… Qué ancho le damos a esa columna?… malas noticias… no hay una respuesta genérica a esa pregunta, depende. Depende de si pretendes ver el efecto en el ordenador o por contra lo quieres imprimir; y también dependerá del tamaño y resolución de la propia imagen. Normalmente mientrás más finas sean las columnas, mejor será el resultado pero OJO!, si imprimes un patrón con separaciones de 1 pixel… dudo que el resultado sea el esperado.

Ex

Figure 2: Scanimations de la misma animación generadas con tres anchos diferentes.

Vengo de la escuela de “10 minutos de trabajo extra hoy, para trabajar sólo un minuto mañana” así que, en lugar de crear una scanimation a mano, me fuí a Matlab y escribí un pequeño código (próximamente en C, que creo que será más accesible) para generar esto de forma automática así que, aquí tienes un pequeño tutorial de cómo hacerlo funcionar (recursos disponibles aquí).

  • Genera los frames que forman la animación.
  • (CUIDADO) Guarda los frames nombrados secuencialmente (1.jpg, 2.jpg 3.jpg, etc). Es importante para que el código funcione corretamente.
  • Sitúa el archivo “pattern.m” en la misma carpeta donde tienes las imágenes.
  • Abre Matlab y sitúate en la carpeta de trabajo.
  • Ejecuta la función de la siguiente manera: “pattern( número_de_frames , Ancho_columna_Transparente_(en_pixels))
  • Esto generará dos archivos .png uno con el patrón y otro con la animación codificada.
  • (Opcional) En caso de que quieras ver el efecto en el ordenador, simplemente tienes que abrir Photoshop, situar ambas imágenes en capas diferentes y mover la “capa acetato”.

GIF_RESNo creas que la única forma de ver el efecto es deslizando una capa sobre otra. En este asunto, la “perspectiva” juega de nuestra parte. Si colocamos las capas con una pequeña separación entre ellas, seremos capaces de percibir el efecto moviéndonos a su alrededor. El siguiente vídeo contiene un ejemplo práctico bastante vistoso.

Y esto es todo! Como siempre, espero que haya resultado interesante y te invito a añadir o preguntar cualquier cosa en los comentarios.

Cuídate.

Tagged , , , , , , , ,