Está en la página 1de 17

Letrero Matricial de LEDs

Un letrero matricial es uno de los proyectos ms atractivos de la electrnica. Su elaboracin puede ser sencilla por su diseo, aunque algo engorrosa por la implementacin del hardware. En esta oportunidad aprenderemos a disear un panel de 8 filas y de 64 columnas, es decir, de 512 LEDs, pero vers que ampliar o reducir el tamao ser tan simple como aadir o quitar registros en el hardware o cambiar un solo nmero en el software. El letrero desplegar un mensaje esttico incluido en el firmware. En el captulo de las memorias FLASH y EEPROM se presenta un letrero de LEDs programablecuyos mensajes se ingresan va el puerto serie.

El hardware
Sabemos que para encender un LED necesitamos de una seal de control, aparte de la alimentacin (Vcc o GND), cierto? Con esto en mente deberamos suponer que para un letrero de 515 LEDs se necesitaran de 512 seales saliendo del microcontrolador. Pero no es as. Podemos resolver parte del problema multiplicando las seales del microcontrolador con ayuda de dispositivos como multiplexores, decodificadores o registros serie-paralelo como el 74164, 74595 o el CD4094. Los dos ltimos son muy parecidos y son a la vez mejores porque cuentan con doble buffer. Uno para almacenar internamente los datos seriales que van ingresando al registro y otro que se conecta al exterior..

Diagrama funcional del registro de desplazamiento 74HC595. Todos estos registros son de 8 bits pero tienen la caracterstica de poder ser montados en cascada para multiplicar sus salidas. Por ejemplo, abajo vemos cmo conectar 8 registros 74HC595 en cascada, lo que equivale a un "mega-registro" serie-paralelo de 64 bits con DATA como principal entrada serial de datos, CLOCK como reloj comn y STROBE como la seal que deja salir por los pines Qx (al mismo tiempo) todos los datos ingresados serialmente. Del mismo modo se pueden ir aadiendo tantos registros como salidas paralelas se deseen.

Conexin en cascada de 8 registros 74HC595 para el letrero matricial de LEDs.

Para nuestro letrero DATA, CLOCK y STROBE sern las seales que saldrn del microcontrolador. Las 64 salidas col0 a col63 controlarn los LEDs. Si nuestro letrero va trabajar con duty cycle de 1/4 debemos duplicar el circuito mostrado. Eso del duty cycle lo entenderemos en el camino. DS es la entrada serial de datos. SH_CP es el reloj de los bits de datos, es decir, con cada pulso aplicado al pin SH_CP ingresar en el registro 74HC595 el bit presente en su pin DS. Los bits as cargados van siendo almacenados en el registro interno 8STAGE SHIFT REGISTER (ver el diagrama funcional del 75HC595). Recin cuando apliquemos un pulso en el pin ST_CP todos los datos cargados pasarn al segundo registro interno 8-BIT STORAGE REGISTER y de all salen a los pines Qx. Si el pin OE vale 1 lgico, todas las salidas estarn en alta impedancia. En nuestro circuito est conectado a GND de modo que el estado de los pines Qx es siempre 1 o 0. El pin MR es reset, y pone a cero todos los pines Qx si vale 0. Para nuestro diseo no necesitamos resetear los registros de esta forma, as que lo mantenemos conectado a VCC. Los pines Q7' y Q7 tienen el mismo valor. Q7' permite la conexin en cascada sin mermar la corriente del pin Q7. Los registros 74HC595 deben ser de la serie HC, o sea, de tecnologa CMOS porque son los que pueden manejar la mayor corriente, que segn el datasheet es de 35mA en los pines Qx actuando como fuentes o sumideros, aunque esta corriente no puede estar presente en todos los pines Qx al mismo tiempo Debemos saber que esos 35mA son un valor extremo que no debera permanecer constante, pero como en el letrero matricial los LEDs nunca estn prendidos todos al mismo tiempo, ser perfecto para bombear todos los picos de corriente posibles. Por otro lado, si nos basamos solo en este mecanismo para ampliar nuestras seales, para controlar los 512 LEDs tendramos que usar 512/8 = 64 registros 74HC595, lo cual nos llevara a un circuito muy difcil de implementar. La tcnica para salvar este segundo inconveniente es un artificio que consiste en encender grupos de LEDs en tiempos diferentes pero con la suficiente frecuencia como para dar la impresin de estar encendidos todos al mismo tiempo. Obviamente, en un letrero matricial los LEDs quedan mejor agrupados en filas y/o columnas. En la siguiente figura los nodos de los LEDs se unen formando las columnas (cols) y los ctodos se unen formando las filas (rows). Tambin se puede armar una configuracin alternativa invirtiendo la polaridad de todos los LEDs. En ese caso los transistores sern de tipo PNP.

Tablero de LEDs para el letrero matricial Los valores de las resistencias R1 a R64 dependen de la corriente que tiene que fluir por los LEDs, la cual a su vez depende de los mismos LEDs. Hay que tener en cuenta que los LEDs no estarn prendidos al 100 % sino la octava parte (por las ocho filas) y tambin que la corriente promedio no siempre es proporcional al brillo del LED prendido, es decir, que un LED est prendido la octava parte no significa que vaya a brillar ocho veces menos. Sobre los transistores: deben tener la capacidad de controlar la corriente proveniente de todos los LEDs de cada fila. Podran ser MOSFETs como el IRF520 y si el tablero es pequeo, hasta un ULN2803podra ser suficiente. Los transistores trabajarn en modo corte-saturacin, por lo que sus resistencias de base (que no estn presentes en este circuito) pueden tranquilamente ser de 10k o 4.7k.

Los barridos
Una vez estructurado el hardware de la matriz de LEDs nos damos cuenta de que podemos encender los LEDs que queramos de cualquier fila o de cualquier columna simplemente activando las coordenadas de dichos LEDs. Por ejemplo, si queremos prender los LEDs de las columnas 0, 3, 4, 7 y 63 de la fila 5 se vera as:

Encendiendo los LEDs del letrero matricial Sin embargo, no es posible encender varios LEDs que pertenezcan a diferentes filas y diferentes columnas al mismo tiempo. Es aqu donde entra a jugar el software. Por ejemplo en la siguiente animacin se muestra cmo para visualizar la letra G se encienden los LEDs correspondientes pero en tiempos diferentes. La primera figura muestra la secuencia del barrido en cmara lenta pero en la prctica los barridos sern tan rpidos que los LEDs se vern como en la segunda figura.

Animacin en slow motion de la visualizacin de figuras en el tablero de LEDs.

Visualizacin en tiempo real de figuras en el tablero de LEDs. Cuando encendemos de esta forma los LEDs, es decir, activando solo 1 de las 8 filas cada vez, se dice que el letrero trabaja con un duty cycle de 1/8 porque en promedio cada LED permanece prendido la octava parte del tiempo. Los letreros de LEDs disponibles en el mercado como enwww.ledauthority.com suelen utilizar un duty cycle de 1/4, es decir, encienden 2 filas de LEDs al mismo tiempo en cada barrido. De ese modo, se consigue una mayor iluminacin de los LEDs. Armar un letrero con duty cycle de 1/4 es tan simple como juntar varios letreros de 4 filas cada uno. Por ejemplo, si queremos construir un letrero de 8x64 LEDs, armamos dos letreros de 4x64 y los ponemos uno encima del otro. El hardware es casi el mismo y aunque deberemos utilizar el doble de registros 74HC595, bien vale la pena por la buena iluminacin que se consigue.

Matriz de LEDs para un letrero con duty cycle de 1/4

Los caracteres
De lo visto anteriormente queda claro que encendiendo los LEDs convenientemente podemos formar en el letrero la figura que deseemos. Ser el microcontrolador quien de acuerdo con su programa se encargue de generar los barridos activando las filas y columnas adecuadamente segn un patrn establecido. Este patrn corresponde a letras, figuras o nmeros que queramos y se puede estructurar de diversas formas. Vamos a representar el patrn con un array de datos, donde cada dato represente una columna del panel de LEDs. De esta forma, si asignamos un 0 a un LED apagado y un 1 a un LED prendido, podemos establecer a partir de cada columna un byte de dato. Luego podremos agrupar ordenadamente todos estos datos y escribirlos en un formato conocido.

Por ejemplo, para el pequeo texto de arriba el array escrito en lenguaje C quedara algo as: const char matrix[] = {0xFC, 0x12, 0x11, 0x12, 0xFC, 0x00, 0x3F, 0x40, 0x80, 0x40, 0x3F, 0x00, 0xFF, 0x11, 0x11, 0x31, 0xCE, 0x00}; Este array puede tener cualquier nombre pero de aqu en adelante me referir a el como matrix.

Generacin automtica de matrix


Ya vimos que para generar el array matrix que se visualizar en el panel de LEDs hace falta conocer el sistema binario y/o hexadecimal. Pero para quienes no tengan la paciencia de componerla manualmente sobre todo si quieren experimentar con textos grandes, les presento una de varias herramientas que encontr en Internet. Se llama LCD font maker y, aunque fue diseado para componer patrones de caracteres o grficos para displays LCD o GLCD, tambin nos servir para nuestro panel de LEDs. Su uso es tan fcil como seguir los tres pasos que se nos indican en la siguiente figura.

En el Paso 1 escogemos la fuente que deseemos. Yo escog Verdana-Negrita-11 porque vi que da letras que se ajustan bien a la altura del letrero. Antes de ir al siguiente paso es preferible poner ahora en Char input el texto que mostrar el letrero. Yo dej unos espacios al principio para que el texto empiece a aparecer desde el costado derecho. Con Offset puedes centrar y ajustar vertical y horizontalmente el patrn del texto. Hay que establecer Height (altura) a 8 y Width (ancho) lo ajustamos hasta que cubra todo el texto, en mi caso fue de 230.

En el Paso 2 sale una ventana donde debemos establecer los parmetros que se indican abajo.

En el Paso 3 se nos genera el cdigo del array que representa nuestro texto. El resultado aparecer como se muestra en la siguiente figura.

Podemos seleccionar el cdigo generado mediante el botn Copy all para luego pegarlo en el cdigo fuente de nuestro proyecto. El cdigo del array est declarado como unsigned char code Bmp001 pero como nuestro programa estar escrito para los compiladores AVR IAR C y AVR GCC, debemos luego cambiarlo por PROGMEM const char matrix, como se ve abajo (matrix es un nombre a escoger). Para el compilador CodeVisionAVR los calificadores PROGMEM const los debemos reemplazar por __flash. PROGMEM const char matrix[] = { /*---------------------------------------------------------------------------Source file / text : www.cursomicros.com Width x Height (pixels) :230X8 ----------------------------------------------------------------------------*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x1F,0xFC,0xE0, 0x7C,0x0F,0x0F,0x7C,0xE0,0xFC,0x1F,0x03,0x00,0x03,0x1F,0xFC,0xE0,0x7C,0x0F,0x0F, 0x7C,0xE0,0xFC,0x1F,0x03,0x00,0x03,0x1F,0xFC,0xE0,0x7C,0x0F,0x0F,0x7C,0xE0,0xFC, 0x1F,0x03,0x00,0x00,0xE0,0xE0,0x00,0x00,0x3C,0x7E,0xC3,0x81,0x81,0x81,0x42,0x00, 0x7F,0xFF,0x80,0x80,0x80,0x40,0xFF,0xFF,0x00,0xFF,0xFF,0x02,0x03,0x03,0x03,0x00,

0x4E,0x9F,0x99,0x99,0x99,0xF9,0x72,0x00,0x3C,0x7E,0xC3,0x81,0x81,0xC3,0x7E,0x3C, 0x00,0xFF,0xFF,0x02,0x01,0x01,0xFF,0xFE,0x02,0x01,0x01,0xFF,0xFE,0x00,0x00,0xFF, 0xFF,0x00,0x00,0x3C,0x7E,0xC3,0x81,0x81,0x81,0x42,0x00,0xFF,0xFF,0x02,0x03,0x03, 0x03,0x00,0x3C,0x7E,0xC3,0x81,0x81,0xC3,0x7E,0x3C,0x00,0x4E,0x9F,0x99,0x99,0x99, 0xF9,0x72,0x00,0x00,0xE0,0xE0,0x00,0x00,0x3C,0x7E,0xC3,0x81,0x81,0x81,0x42,0x00, 0x3C,0x7E,0xC3,0x81,0x81,0xC3,0x7E,0x3C,0x00,0xFF,0xFF,0x02,0x01,0x01,0xFF,0xFE, 0x02,0x01,0x01,0xFF,0xFE,0x00 };

El cdigo fuente
Escribir el programa depender de varios factores, como el tamao del letrero, la forma cmo se presenta el texto (efecto), la longitud de los mensajes, de si los mensajes son estticos o programables en tiempo de ejecucin, etc. En esta ocasin el letrero solo muestra un mensaje en desplazamiento. Por tanto el cdigo fuente ser muy simple. En la siguiente prctica tendremos un letrero programable. /****************************************************************************** * FileName: main.c * Overview: LED sign. Letrero Matricial de LEDs. * Processor: ATmega164P * Compiler: AVR IAR C y AVR GCC (WinAVR) * Author: Shawn Johnson. http://www.cursomicros.com. * * Copyright (C) 2008 - 2013 Shawn Johnson. All rights reserved. * * License: Se permiten el uso y la redistribucin de este cdigo con * modificaciones o sin ellas, siempre que se mantengan esta * licencia y la nota de autor de arriba. *****************************************************************************/ #include "avr_compiler.h" #define SDATA_HIGH() #define SDATA_LOW() PORTD |= (1<<5) PORTD &= ~(1<<5)

#define SCLOCK_HIGH() PORTD |= (1<<6) #define SCLOCK_LOW() PORTD &= ~(1<<6) #define SOEN_HIGH() #define SOEN_LOW() #define WIDTH 64 PROGMEM const char matrix[] = { /*---------------------------------------------------------------------------Source file / text : www.cursomicros.com Width x Height (pixels) :230X8 ----------------------------------------------------------------------------*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x1F,0xFC,0xE0, 0x7C,0x0F,0x0F,0x7C,0xE0,0xFC,0x1F,0x03,0x00,0x03,0x1F,0xFC,0xE0,0x7C,0x0F,0x0F, PORTD |= (1<<7) PORTD &= ~(1<<7)

0x7C,0xE0,0xFC,0x1F,0x03,0x00,0x03,0x1F,0xFC,0xE0,0x7C,0x0F,0x0F,0x7C,0xE0,0xFC, 0x1F,0x03,0x00,0x00,0xE0,0xE0,0x00,0x00,0x3C,0x7E,0xC3,0x81,0x81,0x81,0x42,0x00, 0x7F,0xFF,0x80,0x80,0x80,0x40,0xFF,0xFF,0x00,0xFF,0xFF,0x02,0x03,0x03,0x03,0x00, 0x4E,0x9F,0x99,0x99,0x99,0xF9,0x72,0x00,0x3C,0x7E,0xC3,0x81,0x81,0xC3,0x7E,0x3C, 0x00,0xFF,0xFF,0x02,0x01,0x01,0xFF,0xFE,0x02,0x01,0x01,0xFF,0xFE,0x00,0x00,0xFF, 0xFF,0x00,0x00,0x3C,0x7E,0xC3,0x81,0x81,0x81,0x42,0x00,0xFF,0xFF,0x02,0x03,0x03, 0x03,0x00,0x3C,0x7E,0xC3,0x81,0x81,0xC3,0x7E,0x3C,0x00,0x4E,0x9F,0x99,0x99,0x99, 0xF9,0x72,0x00,0x00,0xE0,0xE0,0x00,0x00,0x3C,0x7E,0xC3,0x81,0x81,0x81,0x42,0x00, 0x3C,0x7E,0xC3,0x81,0x81,0xC3,0x7E,0x3C,0x00,0xFF,0xFF,0x02,0x01,0x01,0xFF,0xFE, 0x02,0x01,0x01,0xFF,0xFE,0x00 }; const unsigned int LEN = sizeof(matrix); /***************************************************************************** * Main function ****************************************************************************/ int main(void) { unsigned int bad; // Base index unsigned int idx; // Index unsigned char dato; // dato unsigned char row; // Fila unsigned char col; // Columna unsigned char i; DDRD = 0xE0; DDRB = 0xFF; PORTD = 0x00; PORTB = 0x00; while(1) { for(bad=0; bad<LEN; bad++) // Bucle para LEN "frames" { for(i=0; i<6; i++) // Bucle de 6 barridos por "frame" { for(row=1; row; row<<=1) // Cada barrido pasa por las 8 filas { for(col=WIDTH; col; col--) // Cada fila iene WIDTH columnas { idx = bad + col - 1; // Calcular ndice de elemento if(idx < LEN) // Si est dentro del rango dato = pgm_read_byte(&matrix[idx]); // Extraer dato else dato = 0x00; // si no, asumir 0x00 if(dato & row) SDATA_HIGH(); else SDATA_LOW(); nop();nop(); SCLOCK_HIGH(); // Si el bit de row es 1 // colocar 1 en DS // o, colocar 0

// Pulso de reloj para

nop();nop(); SCLOCK_LOW(); } PORTB = 0x00 SOEN_HIGH(); nop();nop(); SOEN_LOW(); PORTB = row; } } } } } descargar

// validar el dato colocado

// Desactiva todas las filas // Pulso para sacar todos // los datos cargados

// Activar la fila actual

La simulacin
Dudo que todos los lectores consigan implementar en la prctica real un letrero matricial completo debido a la relativa complejidad del hardware, pero creo que al menos podrn ver su diseo en una buena simulacin gracias a Proteus. Debemos notar que para la simulacin en Proteus no es necesario armar el circuito completamente. Para este diseo por ejemplo he ignorado las resistencias y los transistores de las columnas y filas del panel. Se puede (o debe) editar el parmetro Minimum Trigger Time de las matrices de LEDs para mejorar la visualizacin de los LEDs sobre todo si se cambia la frecuencia del XTAL.

Simulacin del letrero matricial de LEDs en Proteus El realismo de simulacin tambin depender de la potencia de la computadora. En computadoras lentas el contenido del panel se desplaza ms lentamente, aunque se puede mejorar la animacin modificando algunos parmetros, como la cantidad de barridos por frame en el cdigo fuente, solo para fines de la simulacin.