domingo, 25 de marzo de 2012

Pure Data: Qué es y por qué lo usamos

Pure Data es un entorno de programación gráfico diseñado para procesado de audio y vídeo en tiempo real. Desarrollado en los 90 por Miller Puckette para realizar trabajos multimedia y crear música interactiva por ordenador, se utiliza comúnmente para actuaciones de música en directo, VJ (Vee-Jaying), efectos de sonido, análisis de audio, comunicación con sensores, cámaras, robots, o incluso sitios web.

Gracias a que todos estos diferentes tipos de datos son manejados en el lenguaje como simples datos digitales, aparecen un montón de oportunidades para realizar síntesis cruzada entre ellos. Por ejemplo, instrucciones MIDI pueden usarse para manipular vídeo, accionar motores, o como queremos hacer en nuestro caso, generar una gran variedad de sonidos y controlar un array de LEDs.

Pure Data corre sobre todo tipo de plataformas: Windows, MacOS, Linux, iOS, Android, e incluso existen ports antiguos para FreeBSD e IRIX.

sábado, 24 de marzo de 2012

La matriz RGB: hardware y software

Nota: actualizado 12/04/12 con registro de estado del TLC5940 y explicación de las interferencias.

Tras las primeras pruebas, hemos fijado el hardware que usaremos para controlar la matriz RGB, basándonos finalmente en el TLC5940.

TLC5940 (datasheet)
El TLC5940 es un controlador LED de corriente constante de 16 canales.
A cada canal se le puede ajustar un PWM de 4096 valores (grayscale, 12 bits) y un valor de corriente de 64 pasos (dot correction, o corrección de puntos).Estos valores de dot correction pueden almacenarse en una EEPROM interna del chip.
Para controlar los LEDs, actúa como un sumidero de corriente (hasta 120mA por canal).
La entrada de valores de cada canal se realiza por un bus SPI (hasta 30 Mhz).

El funcionamiento es el siguiente:
  • El micro ha de proporcionar una señal de reloj (GSCLK) que es la que incrementa los contadores internos del PWM de cada canal, soporta hasta 30 Mhz.
  • Cada vez que llegue a 4096, el micro ha de enviar un pulso a nivel alto por el pin BLANK. Este pin se encarga de desactivar todas las salidas, y resetear los contadores a cero. Tras acabar el pulso, en el primer flanco de subida de GSCLK comienzan a incrementarse los contadores. Si no le llega la señal BLANK tras los 4096 ciclos, todas las salidas se desactivan. 
  • La señal BLANK se puede usar si se desea disminuir la resolución del PWM, si, por ejemplo, se quieren 2048 valores, simplemente tras 2048 ciclos de GSCLK se manda la señal BLANK y vuelve a empezar la cuenta.
  • La duración de la señal BLANK interesa que sea mínima, para que el PWM resultante no sea a ráfagas.
La transmisión de valores por SPI sigue el siguiente esquema:
  • Los contadores de cada salida tienen asociados un registro de 12 bits para cada salida, este es el usado como referencia por el contador para desactivar la salida.
  • Cada salida tiene asociado otro registro de 6 bits para el dot correction.
  • Para la programación, se emplean 5 señales: SCLK, SIN, VPRG, XLAT y DCPRG.
  • DCPRG indica si la carga de valores de dot correction es a partir de la EEPROM interna (nivel bajo) o desde SPI (nivel alto).
  • Los valores se mandan a través de SPI, los datos por SIN, sincronizados por SCLK. Al llegar al TLC5940, se almacenan en bufferes. 
  • Cuando XLAT pasa a nivel alto, los datos pasan de los bufferes a los registros, y las salidas se controlan por los nuevos valores.
  • La transmisión SPI es MSB, el primer bit es el más significativo.
  • VPRG indica si los datos que se han mandado escribirán los datos de PWM (VPRG=0) o de dot correction.
A la hora de transmitir los valores nuevos, interesa que se acabe un ciclo de PWM, se manden los nuevos datos, y entonces, se inicie el nuevo ciclo. Como los sistemas de PWM y SPI van independientes, si no se hace así, puede ocurrir parpadeos y temblores en los LEDs.

El chip dispone de detección de LED fundido y de sobrecarga térmica, para ello tiene un pin, XERR, de colector abierto, que es puesto a nivel bajo si ocurre alguna de estas situaciones. Se pueden unir los pines XERR de varios para detectar si ocurre en alguno de ellos.

Para detectar que ha ocurrido exactamente si XERR pasa a nivel bajo, el chip tiene un registro de estado de 192 bits que especifica estas situaciones, indicando si es un error térmico, o que salida ha provocado que se detecte un LED fundido.

El hardware
En nuestro sistema, tenemos dos TLC5940 encadenados o daisy-channed. A los canales 0-7 del primero están los cátodos de los LED rojos, en 8-15 los cátodos de los LED azules y en el segundo TLC5940, en los canales 0-7 están los cátodos de los LED verdes. Los canales 8-15 del segundo están vacíos.
Las conexiones significativas son:
  • SOUT de #1 a SIN de #2, para encadenar la transmisión SPI
  • SIN y SCLK a los pines del SPI del Arduino.
  • GSCLK a la salida del Timer1
  • XLAT y BLANK pueden ser conectados a cualquier pin digital del Arduino. Su configuración está definidia como constantes en el código.
Para conectar los ánodos, necesitamos una etapa de potencia ya que a un consumo de 15mA de cada LED, tendremos un máximo de 360mA al escribir una fila en blanco, y no puede ser aportado por un pin del Arduino, que soporta hasta 40mA. Para ello, usamos un transistor PNP  darlington MPSA63 a través de una resistencia de 10K. Las ocho entradas están conectadas a un decodificador 3 a 8 para controlar las filas con 3 pines del microcontrolador.

Para más detalle, ver el esquemático.
El software
Comenzamos usando la libreria del TLC5940 para Arduino, multiplexando las filas en el hilo principal de ejecución, pero no resultó adecuado (Ver primeros pasos con la matriz RGB). Hay una librería experimental, TLC5940Mux, pero está documentada como que tiene errores de flickering y mezcla entre columnas.
Tras algo de investigación, encontramos este post en el foro de Arduino sobre el tema, y un código para la rutina de interrupción modificado. Este soluciona un poco los problemas, pero sigue adoleciendo de problemas. Por ello, hemos tenido que desarrollar nuestro código de control propio.

El funcionamiento es el siguiente:
  • Continuamente, el Timer1 de Arduino genera una señal cuadrada de periodo fclk/2 que se utiliza para GSCLK, incrementando los contadores del TLC5940.
  • El Timer2 está configurado para interrumpir cada 4096 interrupciones del Timer1. Cuando interrumpe, manda los valores de los colores de la siguiente fila, activa la fila siguiente, y entonces, manda los pulsos de XLAT para escribir los valores y de  BLANK para resetear los contadores y comenzar la cuenta.
La librería mantiene un array con los valores de cada columna, siento el total definido por NUM_ROWS. El número de TLC5940 encadenados está definido en NUM_TLC, dos en nuestro caso.

Con la modificación comentada de la librería conseguimos alguna animación autónoma:


Arduino Synth - RGB matrix. from José Martín on Vimeo.


Seguimos teniendo problema de interferencia entre filas, se puede un detalle aqui:
Los puntos con luz tenue no deberían haberse iluminado.



Tal y como lo hemos desarrollado, conseguimos un refresco de 244 Hz (cambia de fila 1960 veces por segundo), con un número de colores posible de mas de 68700 M de colores (2^36). Una pantalla de PC típica tiene 16 M de colores a 60 Hz.

El esquemático será publicado aquí en breve.

Referencias

Prueba de sonido: Ardsynth_test

Ahora que nuestra clase ardsynth funciona correctamente y recibimos eventos MIDI podemos empezar a probar algún pequeño programa para comprobar que nuestro sistema puede reproducir sonidos sencillos.
Sintetizador analógico - Cables y módulos (se parece al Pure Data, ¿no?)

Ardsynth_test.pd

Para ello hemos creado un nuevo patch (programa) en Pure Data en el que hemos instanciado un objeto de la clase ardsynth, que es una representación virtual del Arduino y el cual nos transfiere los eventos MIDI ya empaquetados en mensajes inteligibles por el lenguaje.

MIDI: Qué es y qué usamos

MIDI es un protocolo de comunicación serie estándar que permite que varios dispositivos musicales electrónicos (controladores, sintetizadores, secuenciadores, PCs,..) se conecten entre sí y compartan información para la generación de sonidos.

Surgió a principios de los 80 para permitir interconectividad entre instrumentos de distintos fabricantes. Dave Smith, el ingeniero que desarrolló la idea del protocolo, consiguió establecer conexión entre dos sintetizadores (su Prophet 600 y un Roland Jupiter-6) y de demostrarlo por primera vez en el 1983 Winter NAMM Show.

Su creación facilitó el desarrollo de secuenciadres y sintetizadores hardware y software, y permitió la integración de la música en la informática.

viernes, 23 de marzo de 2012

La plataforma Arduino

Para la realización del hardware, hemos elegido la plataforma de desarrollo Arduino.

Arduino es una plataforma de desarrollo para prototipos basada en microcontroladores Atmel AVR de 8 bits. Se compone de una placa hardware y un software de desarrollo multiplataforma.

Respecto a la tarjeta hardware, ha habido varias revisiones de hardware, actualmente, las dos versiones actuales, Arduino Uno y Arduino Mega 2560, se basan respectívamente en los microcontroladores ATmega328 y ATmega2560.
Debido a las razones encontradas en el estudio preliminar, nos centraremos en la Arduino Mega 2560, que es la usada en el proyecto.

Presentación Hito 1

Hoy, 23 de Marzo, hemos realizado la presentación del hito 1.

La presentación mostrada se puede descargar aquí.

En el feedback de la presentación, nos han comentado la posibilidad de haber elegido un micro de mayor potencia con el fin de aunar en él todo el procesamiento, evitando la parte realizada en un PC.
Algunas de las razones por las que elegimos la dualidad Arduino-PureData son:
  • Modificabilidad: el procesamiento en PureData es más fácil de modificar para, por ejemplo, integrar otro sintetizador o conectarlo a otro sistema o software, además de poder cambiar fácilmente el sonido sin tirar lineas y lineas de código.
  • Potencia: PureData está orientado a tiempo real e imagen y sonido. Tiene ya integradas muchas funciones útiles y está estructurado para cumplir los requisitos que el tiempo real impone. Esto evita una gran tarea de programación para el microcontrolador y muchos problemas de temporización y carga del micro.
En breve, añadiremos los avances comentados en la presentación, así como entradas de introducción a Arduino y PureData.
También hemos cambiado la zona horaria del reloj, que por alguna razón el blog estaba configurado como hora del pacífico...

viernes, 16 de marzo de 2012

Pure Data e interacción con eventos MIDI

Ahora tenemos resuelto el paso de instrucciones MIDI al ordenador mediante nuestro programa cargado en el Arduino. Recibimos los eventos generados por un controlador por la UART1 a velocidad MIDI (31250 baudios) y los reenviamos por la UART0 a velocidad estándar de PC (57600 baudios).

Comenzamos a analizar los datos utilizando el lenguaje de programación visual Pure Data. Con él somos capaces de abrir una conexión con el Arduino gracias a un conjunto de librerías que crean un objeto virtual 'ardsynth'. Este objeto representa nuestra placa y nos permite abrir una comunicación serie con ella para recibir las instrucciones que le manda el controlador.

Arduino.pd

El plug-in de Pure Data que crea la interfaz software para la comunicación con el Arduino es Pduino (Arduino: Interfacing with software). Incluye dos programas de prueba y una clase principal llamada "arduino.pd" que es la que nos permite crear el puerto de comunicación.

Para llegar a nuestro objetivo hemos tenido que rediseñar esta clase, renombrada como 'ardsynth.pd'.

Primeros pasos con la matriz RGB

Matriz RGB.
Tras recibir la matriz RGB, hemos configurado unas pruebas para ver el funcionamiento de los drivers RGB y la multiplexación.
Para ello, hemos conectado a un Arduino Dueminalove dos chips TLC5940 en configuracion daisy-channel, enlazados a través de la interfaz SPI, siguiendo el esquema de referencia de la libreria TLC5940 para Arduino.
Grosso modo, esta libreria usa los Timers 1 y 2 de Arduino (deshabilita PWM en algunas salidas) para las entrada de reloj del TLC5940 (GSCLK) y para la señal XLAT. En la datasheet del TLC5940 viene todo explicado con cronogramas. Una descripción bastante buena del funcionamiento, con código en C para PIC16F876, puede encontrarse aqui.
La libreria incluye funciones integradas para realizar shades y shifts.

Para multiplexar las filas, aún no hemos construido los drivers para controlar las filas con el Arduino, por lo que, de momento, cada LED se enciende con unos 5mA, dando unos 40 por fila, que el máximo que Arduino puede aportar por cada pin. Posteriormente construiremos uno que soporte unos 500mA, ya que cada LED admite hasta 50mA, aunque se puede aumentar ya que está encendido 1/8 del tiempo como máximo.
Un papel ayuda con la mezcla.


Para la multiplexación, se realiza una secuencia de:
  • escribir fila i en los drivers
  • esperar cierto retraso
  • activar fila i 
  • esperar cierto retraso
  • apagar filai
  • aumentar i para la siguiente fila.

Probando a minimizar los retrasos, hemos llegado unos retrasos de  900 y 1000 microsegundos, ya que si se apuran más, se produce un solapamiento de colores entre la fila actual y la anterior.
Si reducimos aún más el tiempo que le damos a la libreria para escribir los driver, conseguimos un curioso efecto, aunque se trate de bugs de software.




Con esta velocidad, no tenemos una visión óptima, puede apreciarse un siguiente parpadeo. Hay una versión de la libreria TLC5940 optimizada para multiplexación, pero experimental y con algunos fallos, orientaremos los esfuerzos en implementarla.
Las imágenes del artículo son de nuestra matriz, las fotografías han sido subexpuestas para apreciar los colores y con exposición larga para que no se note el barrido.
La matriz ha sido rellenada con colores aleatorios generados al inicio, en un array tridimensional de 8x8x3, con miles de millones de colores posibles.



sábado, 3 de marzo de 2012

Estudio del sistema de iluminación


Sistema de iluminación
Hemos estado estudiando las opciones, y nos hemos decantado por una matriz de LED RGB de 8x8, hemos encargado una a través de eBay, datasheet aqui. Cuando nos llegue, empezaremos a montarla. Para alimentarla, podemos usar fuente normal con resistencias o un driver IC para LED de corriente constante.
Entre las opciones, las hemos reducido a dos posibles:
  • Driver PWM hardware: se ajusta un valor y se va cambiando la fila excitada y los valores PWM asociados. Un IC posible sería el TLC5940 de TI, cada uno tiene 15 canales, se necesitarían dos, conectados en cascada, para cubrir los 24 puntos necesarios.
  • Driver de corriente constante hardware, se utilizaria un IC que genere una corriente constante, y ajustando dicha corriente, realizar las mezclas, barriendo las filas con los valores de corriente asociados. 
La segunda opción es más sencilla en software, pero la primera permite mezclas mucho mas ricas (PWM de 12 bits, 4096 estados, miles de millones de colores), así como muchas más opciones como detección de LED fundido, correcciones cromáticas de 6 bits para cada canal...

Etapa de entrada y lectura de tramas

Etapa de entrada:
La especificación oficial MIDI contempla el siguiente esquema para el aislamiento, mediante un optoacoplador. De esta manera, tanto se aisla electricamente, como se evita el problema de la adaptación de niveles de tensión.

Lo hemos implementado con este circuito:
To Be Copied Here

Lectura de datos MIDI
Hemos implementado un pequeño programa para leer los bytes que le llegan por la UART1 (MIDI, a 31250 baudios), y replicarlos por la UART0 (SerialOverUSB, 57600 baudios), los replica como cadenas de caracteres, con 3 bytes por linea, que representan:
  • Byte 1: información de set de instrumentos, código de instrumento, etc.
  • Byte 2: código de nota pulsada.
  • Byte 3: intensidad de nota pulsada (0 corta el sonido de esa nota). 
Para pruebas, hemos probado a hacer sonar un altavoz mediante ondas cuadradas y la orden Tone() de Arduino, el resultado es el siguiente:





Como emisor de datos, hemos puesto a otro Arduino (Duemilanove) a mandar notas MIDI, haciendo una escala ascendente.

La entrada serie del PC:

Sketch

 
/*
  MIDI interface
  
  @author J. Martin, S. Lopez 
 */

int nbyte=0;
long int frequency;
int midi[3];

void setup() {
  // initialize both serial ports:
  Serial.begin(115200);
  Serial1.begin(31250);
}

void loop() {
  
}

void serialEvent1() {
  int inByte = Serial1.read();
  midi[nbyte] = inByte;
  Serial.print(inByte); 
  Serial.print(" ");
  nbyte++;
  
  if (nbyte==3) {
    nbyte=0;
    Serial.println();
    
    frequency = map(midi[1], 0x1E, 0x5A, 55,1760);
    tone(8,frequency);
  }
}


Análisis inicial

Hemos estado analizando el análisis de la práctica con Juan Manuel Montero y Roberto Barra, los días 22 y 29 de Febrero.
De ahí hemos concretado algunos puntos:
  • Los módulos a realizar serán la interfaz USB, la placa de control, el procesado en PC y el sistema de iluminación. Además, se implementará un Wiimote como interfaz de control más adelante.
  • La plataforma Arduino Dueminalove/UNO sólo dispone de un módulo USART, usado por la comunicación USB, y la comunicación con MIDI requiere otro, debido a limitaciones de la libreria para crear un puerto serie virtual, por lo que pasamos a realizar la práctica con una placa Arduino Mega 2560 R3.

También se ha acordado la planificación temporal de la práctica, de la que se derivan los siguientes hitos: 
  • Hito 1: 
    • Reenvio de comandos desde la entrada MIDI al PC a través del arduino.
    • Poder escuchar las notas en el PC, de forma simple (comprobación de recepción sólo).
    • Recepcion de datos adicionales del Arduino.
    • Clasificación de tramas en PureData según sean notas o datos de control.
    • Visualización simple de forma autónoma por el Arduino.
  • Hito 2: 
    • Visualización basica comandada por PC, no dependiente del ritmo o acordes.
    • Reproducción de las notas tocadas con fidelidad.
    • Recepción de datos en bruto con Wiimote.
  • Hito 3: 
    • Visualización dependiente del ritmo o acordes
    • Interfaz de entrada completa
    • Control con Wiimote completo (mejora).

Descripción de la práctica

Sintetizador digital MIDI implementado en PureData
con feedback visual configurable


Nuestro proyecto pretende construir un sintetizador digital MIDI que utilize la señal de un piano, un secuenciador o, en general, de cualquier controlador MIDI para generar señales de audio y efectos luminosos modulados por hardware a través de un programa desarrollado en PureData, un lenguaje de programación orientado a tiempo real.

Este sistema está pensado para aplicaciones como el diseño y puesta a punto de performances basadas en audio e iluminación como actuaciones musicales en directo, permitiendo ajustar parámetros de forma fácil en función de las necesidades del usuario gracías a la modularidad del software de control.

Especificaciones HW y SW tentativas:
-Arduino Mega 2560 Revision 3
-PureData 0.42.5

Módulos del sistema
Consta principalmente de los módulos señalados en la figura superior, que son:
  • Controlador MIDI. Es el elemento que genera las instrucciones a decodificar por el ordenador. Puede ser un teclado, una guitarra MIDI, un secuenciador, o cualquier dispositivo capaz de transmitir dichas instrucciones. En la práctica, utilizaríamos un teclado MIDI conectado a nuestro periférico de entrada para realizar las pruebas de sonido e iluminación.
  • Interfaz de control. A través de este elemento controlaríamos los parámetros del software de procesamiento, tanto musicales como adición de efectos, elección de patches, modelado de sonidos, etc., como de iluminación, así como conmutación entre modos de funcionamiento del sistema. Este módulo iría conectado al periférico de entrada que se encargaría de transmitir esta información al ordenador.
  • Periférico de entrada MIDI-USB. Es el dispositivo que actúa de pasarela entre el controlador y el ordenador en el que reside el programa. Además, envía los datos de la interfaz de control al ordenador y controla el módulo de visualización. En principio implementaríamos este módulo con un microcontrolador Arduino.
  • Unidad de iluminación. Se quiere incluir un módulo de visualización, que generara una respuesta visual a los datos enviados por el controlador. Este sistema tendría varios canales de iluminación independientes, cada uno de ellos con tres canales RGB, de forma que el software de procesamiento pudiera generar el color deseado en cada uno de ellos. Este módulo podría conectarse a diversos sistemas de iluminación como focos RGB o matrices de LEDs.
  • Procesado de datos y generación de audio. El proceso de generación de audio se realiza con la ayuda de un ordenador personal en el que se ejecuta un programa desarrollado en PureData, un lenguaje orientado a tiempo real basado en flujos de información.
Estimación de recursos necesarios
Como primera aproximación, creemos que necesitaríamos:
  • Controlador MIDI: intentaríamos traer al laboratorio un teclado MIDI pequeño, por lo que simplemente necesitaríamos un lugar para guardarlo. En caso de no encontrarlo, disponemos de un secuenciador MIIDI Yamaha QY22.
  • Plataforma Arduino para implementar el periférico de entrada.
    Sliders, potenciómetros, conectores, y puede que algún PIC de bajo rendimiento y una pantalla LCD para la interfaz de control.
  • Alguna matriz de LEDs, tiras de LEDs, etc., o similar para el módulo de iluminación.
  • Altavoces o auriculares para reproducir el sonido final.
Contacto, referencias y más información

Partlist

Esta entrada irá almacenando la partlist de todo, siendo actualizada periodicamente. UA 3/3/12

Placa de desarrollo:



Etapa de entrada:

  • 6N138
  • 1N4148
  • Varias resistencias.
  • Conector DIN-5 180 grados (MIDI HW specs).


Sistema de iluminación:

  • Matriz LED RGB 8x8, ref. GTM2088ARGB-21. Datasheet.
  • 2x TLC5940
  • 1x 74HC138
  • 8  MPSA63
  • 2x 10nF
  • 1x 100nF
  • 1x 100 uF
  • 3x 100pF
  • 11x 10Kohm
  • 2x 2K7ohm
  • 1x 220 ohm
  • 1x 6N138
  • 1x Tira pines macho .1"
Plataforma
  • 1x PCB