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

5 comentarios:

  1. Interesante el proyecto, donde puedo conseguir algun diagrama de conexion.

    ResponderEliminar
  2. Excelente trabajo, podrías mostrar como van conectados los leds a los TLC5940, van continuos con los pines o cada color va hacia un TLC, ha que se deba que se iluminen los leds que ya fueron pasados, por velocidad de refresco o problemas de circuiteria, saludos y espero que pronto publiques código de ejemplo o el diagrama.

    ResponderEliminar
  3. Hola,
    En este post se explica la librería que se desarrolló:
    http://arduinosynth.blogspot.com.es/2012/04/libreria-grafica-matrixcontroller.html
    En ella ya no hay los problemas de interferencias que aqui se mostraban.

    La conexión hardware esta en los esquemas en esta entrada:
    http://arduinosynth.blogspot.com.es/2012/09/codigo-fuente-y-memoria.html

    Aunque a priori te puedo decir que eran 2 TLC, el primero las salidas 0-7 eran los catodos rojos, y las 8-15 los azules. En el segundo, las 0-7 eran los verdes, y los ánodos de todos estaban conectados mediante transistores a 5V para activarlos cuando es necesario, consulta los esquemas de la memoria para verlo más claro.

    Un saludo

    ResponderEliminar
    Respuestas
    1. De nuevo excelente trabajo y por compartir la información, veré los link que me mencionas para obtener mas información de tu trabajo. Saludos desde México.

      Eliminar