Las matrices LEDs 8×8 son sumamente conocidas. Su nombre se debe a que están compuestas por 64 LEDs dispuestos en forma de cuadrado con 8 columnas de 8 LEDs cada una.
Matriz LED cátodo común y ánodo común
Las matrices de LEDs pueden ser de dos tipos: ánodo común o cátodo común.
Matriz cátodo común: los terminales negativos (cátodos) de todos los LEDs de cada fila están conectados juntos. Lo mismo ocurre con los pines positivos (ánodos) de cada columna.
Matriz ánodo común: las conexiones son contrarias, es decir, los ánodos se conectan a las filas y los cátodos a las columnas.
Puedes notar que solo se cuenta con 16 pines para controlar la matriz, 8 para las columnas y 8 para las filas.
¿Cómo manejar una matriz LED?
En una matriz no es posible controlar todos los LEDs como si fueran independientes. Esto pasa porque solo se dispone de los pines correspondientes a filas y columnas.
Si se aplican valores de alto (HIGH) y bajo (LOW) a varias columnas y filas, respectivamente, se encenderán todos los LEDs de las intersecciones.
Para poder mostrar gráficos correctamente es necesario realizar un barrido por filas o columnas. Se iluminará sólo una fila a la vez.
Por ejemplo, si quieres mostrar un corazón son necesarios 8 pasos, uno por cada fila.
¿Pero esto no muestra solo una fila a la vez?
Pues no.
Las actualizaciones se realizan suficientemente rápido y con ayuda del efecto de persistencia visual el ojo humano no es capaz de notar el instante donde los LEDs se apagan.
Circuito integrado MAX7219 y MAX7221
Controlar una matriz de 8×8 implica utilizar 16 señales digitales y refrescar la imagen de una forma constante. Es por eso que en lugar de utilizar un Arduino directamente, emplearemos el circuito integrado MAX7219 o MAX7221 para esta tarea.
Los circuitos integrados MAX7219 y MAX7221 son casi iguales. Eso significa que son fácilmente intercambiables uno por el otro. De ahora en adelante me referiré al MAX7219, aunque todo es igual de válido para el MAX7221.
El MAX7219 es un circuito integrado que facilita el control de LEDs. Es usado principalmente en pantallas de 7 segmentos, paneles de LEDs industriales y como controlador de matriz de LED con Arduino.
Entre sus ventajas:
- Interfaz de control serie: con tan solo 3 pines podemos controlar toda una matriz de LEDs.
- Circuito externo simple: requiere pocos componentes externos.
- Conexión en cascada: se pueden conectar varios MAX7219 en cascada. De esta forma se puede controlar varias matrices LEDs utilizando solo 3 pines de la placa Arduino.
Módulos de matriz LED con Arduino basados en MAX7219
Existen módulos de matrices LEDs para Arduino con el circuito montado. Existen de una única matriz o de varias.
Los que están compuestos por varias matrices utilizan un MAX7219 por cada una, y estos están conectados tal y como vimos en el esquema anterior. Es decir, que se conectan todos los MAX7219 en cascada.
Los módulos simples, no vienen diseñados para este tipo de acople, pero cuentan con dos conectores: uno de entrada y uno de salida. Esto nos permite conectar varios módulos en cascada.
El conector de entrada cuenta con los pines VCC y GND que son utilizados para alimentar el módulo. Además, están los pines DIN, CS y CLK que son utilizados para la comunicación.
En algunos módulos el pin CS es nombrado como LOAD.
El conector de salida es idéntico al de entrada. La única diferencia es que se ha sustituido el pin DIN por el pin DOUT. Este segundo conector es el que permite conectar varios módulos en cascada.
Como conectar un módulo matriz LED con Arduino
Para usar un módulo de matriz de LED para Arduino basado en MAX7219 es necesario conectar el pin VCC, al pin +5V de la placa y unir los pines GND del módulo y el Arduino. Los pines DIN, CLK y CS se conectan a tres pines digitales del Arduino.
Aquí puedes ver cómo queda la conexión de un Arduino UNO con un módulo simple.
El orden de los pines puede cambiar de un módulo a otro, por lo tanto, es importante que revises la nomenclatura antes de realizar la conexión.
Librería MAX7219 con Arduino
Existen muchas de librerías para módulos de matriz LED con Arduino. Aquí vas a ver la biblioteca MD_MAX72xx que te permite hacer maravillas con tu cartel digital.
Ya sabes como conectar un modulo de matriz de LED con Arduino basado en MAX7219, ahora solo queda aprender a programar su código.
Una de las ventajas de esta librería es que si conectas cuatro módulos en cascada los puedes usar como si fueran una matriz de 8 pixeles de altura y 32 de ancho.
Instalar librería MAX7219 con Arduino
Comencemos instalando la librería.
Para esto tienes que abrir el Gestor de Librerías que se encuentra en Herramientas/Administrar Bibliotecas…
Una vez abierto el Gestor de Librerías busca MD_MAX72 e instala la librería.
Listo ya tienes la librería instalada.
Funciones principales de la librería MD_MAX72xx
Como todas las librerías para Arduino, la MDMAX72xx tiene un montón de funcionalidades que pueden hacer muchas cosas.
De momento, las funciones y método más interesantes para nosotros son las siguientes.
Función MD_MAX72XX()
Esta sentencia es llamada constructor. Se usa para crear un objeto MD_MAX72XX. Simboliza los módulos de matrices LEDs que conectas al Arduino.
Permite controlar los módulos con cualquier pin digital.
1
|
MD_MAX72XX mxObj = MD_MAX72XX(hardware, pinDIN, pinCLK, pinCS, matCount);
|
Donde:
- pinDIN: es el pin digital del Arduino que se conecta al pin DIN del módulo.
- pinCLK: es el pin digital del Arduino que se conecta al pin CLK del módulo.
- El resto de las variables cumplen la misma función que en la sobrecarga anterior.
// Utilizar:<br />
// – PAROLA_HW como tipo de hardware<br />
// – pin digital 2 conectado al pin DIN<br />
// – pin digital 4 conectado al pin CLK<br />
// – pin digital 3 conectado al pin CS<br />
// – se conectan dos matrices </p>
<p>MD_MAX72XX mx = MD_MAX72XX(MD_MAX72XX::PAROLA_HW, 2, 4, 3, 2);
1
2
3
4
5
6
7
8
9
|
//Modulo de matriz LED con Arduino basado en MAX7219 o MAX7221
// Utilizar:
// – PAROLA_HW como tipo de hardware
// – pin digital 2 conectado al pin DIN
// – pin digital 4 conectado al pin CLK
// – pin digital 3 conectado al pin CS
// – se conectan dos matrices
MD_MAX72XX mx = MD_MAX72XX(MD_MAX72XX::PAROLA_HW, 2, 4, 3, 2);
|
En ambas sobrecargas el argumento hardware puede tomar cualquiera de los siguientes valores:
- MD_MAX72XX::GENERIC_HW: hardware genérico.
- MD_MAX72XX::FC16_HW: para el uso de módulos tipo FC-16.
- MD_MAX72XX::PAROLA_HW: para el uso de módulos tipo Parola.
- MD_MAX72XX::ICSTATION_HW: para el uso de módulos tipo ICStation.
- MD_MAX72XX::DR0CR0RR0_HW *
- MD_MAX72XX::DR0CR0RR1_HW *
- MD_MAX72XX::DR0CR1RR0_HW: equivalente a GENERIC_HW.
- MD_MAX72XX::DR0CR1RR1_HW *
- MD_MAX72XX::DR1CR0RR0_HW: equivalente a FC16_HW.
- MD_MAX72XX::DR1CR0RR1_HW *
- MD_MAX72XX::DR1CR1RR0_HW: equivalente a PAROLA_HW.
- MD_MAX72XX::DR1CR1RR1_HW: equivalente a ICSTATION_HW.
* Estos valores se utilizan cuando se conectan matrices en cascada y no corresponden ninguno de los estándares. Para la conexión propuesta anteriormente (la de tres módulos simples con Arduino UNO) es necesario utilizar MD_MAX72XX::DR0CR0RR1_HW.
Función control()
Esta función permite configurar algunos parámetros de control en los módulos de matrices LED basados en MAX7219. Puede ser utilizada para establecer la intensidad del brillo de los LEDs o poner el módulo en modo de bajo consumo.
Primera sobrecarga: admite dos argumentos y permite configurar un parámetro en todos los módulos:
1
|
mxObj.control(param, value);
|
Donde:
- param: es el parámetro a modificar.
- value: es el valor a aplicar al parámetro indicado.
mx.control(MD_MAX72XX::SHUTDOWN, false);</p>
<p>// Establecer a 1 la intensidad de los LEDs<br />
mx.control(MD_MAX72XX::INTENSITY, 1);
1
2
3
4
5
|
// Sacar todas las matrices del modo de bajo consumo
mx.control(MD_MAX72XX::SHUTDOWN, false);
// Establecer a 1 la intensidad de los LEDs
mx.control(MD_MAX72XX::INTENSITY, 1);
|
Segunda sobrecarga: admite tres argumentos y permite configurar el parámetro de un solo módulo.
1
|
mxObj.control(mat, param, value);
|
Donde:
- mat: es un entero entre 0 y la cantidad de módulos conectados. Indica el módulo a configurar.
- param: es el parámetro a modificar.
- value: es el valor a aplicar al parámetro indicado.
mx.control(1, MD_MAX72XX::SHUTDOWN, true);
1
2
|
// Poner el segundo módulo en modo de bajo consumo
mx.control(1, MD_MAX72XX::SHUTDOWN, true);
|
Tercera sobrecarga: permite aplicar la configuración a un intervalo de módulos.
1
|
mxObj.control(matIni, matFin, param, value);
|
Donde:
- matIni: inicio del intervalo de módulos.
- matFin: fin del intervalo de módulos.
- param: parámetro a modificar.
- value: valor a aplicar al parámetro indicado.
mx.control(0, 3, MD_MAX72XX::TEST, true);
1
2
|
// Poner las matrices 0, 1, 2 y 3 en modo de prueba
mx.control(0, 3, MD_MAX72XX::TEST, true);
|
En todas las sobrecargas el argumento param puede tener varios valores. Los más importantes son:
- MD_MAX72XX::TEST: activa o desactiva el modo de prueba. Cuando se activa (value = true) se encienden todos los LEDs para comprobar que ninguno esté dañado.
- MD_MAX72XX::SHUTDOWN: activar o desactivar el modo de bajo consumo.
- MD_MAX72XX::INTENSITY: permite especificar el brillo de los leds. El valor de value tiene que estar entre 0-15, donde 0 apaga los LEDs y 15 es el brillo máximo.
- MD_MAX72XX::UPDATE: Permite habilitar o deshabilitar la actualización automática.
Cuando la auto-actualización está deshabilitada es necesario ejecutar la función update() para que los cambios sean mostrados en la matriz.
Función getColumnCount()
Esta función permite conocer el número total de columnas, es decir, retorna la cantidad de matices multiplicada por 8.
int last_col = mx.getColumnCount() – 1;
1
2
|
// obtener la última columna de todo el conjunto de matrices
int last_col = mx.getColumnCount() – 1;
|
Función clear()
Esta función permite “limpiar” la información de las matrices, en otras palabras, apaga todos los LEDs de las matrices.
Primera sobrecarga: no requiere argumentos y limpia todas las matrices.
mx.clear();
1
2
|
// Limpiar todas las matrices
mx.clear();
|
Segunda sobrecarga: permite limpiar un intervalo de matrices.
1
|
mxObj.clear(matIni, matFin);
|
Donde:
- matIni: inicio del intervalo de matrices a limpiar.
- matFin: fin del intervalo de matrices a limpiar.
mx.clear(0, 2);
1
2
|
// Limpiar las matrices 0, 1 y 2.
mx.clear(0, 2);
|
Función setColumn()
Esta función permite establecer el estado de una columna de LEDs.
Primera sobrecarga: recibe tres parámetros y permite establecer el estado de una columna indicando su matriz:
1
|
mxObj.setColumn(mat, col, estado);
|
Donde:
- mat: es un entero que indica la matriz a modificar.
- col: es un entero entre 0 y 7 que indica la columna a modificar.
- estado: es un entero de 8 bits que indica los LEDs a encender. Cada bit puesto a 1 indica que se encenderá su LED correspondiente.
// Se encienden los dos LEDs inferiores y el LED superior de la columna<br />
mx.setColumn(0, 3, B11000001);</p>
<p>// Establecer un nuevo estado en la octava columna de la tercera matriz<br />
// Se encienden el LED superior y el inferior<br />
mx.setColumn(2, 7, B10000001);
1
2
3
4
5
6
7
|
// Establecer un nuevo estado en la cuarta columna de la primera matriz
// Se encienden los dos LEDs inferiores y el LED superior de la columna
mx.setColumn(0, 3, B11000001);
// Establecer un nuevo estado en la octava columna de la tercera matriz
// Se encienden el LED superior y el inferior
mx.setColumn(2, 7, B10000001);
|
Segunda sobrecarga: recibe dos parámetros y también permite establecer un nuevo estado en una columna. La diferencia con la sobrecarga anterior es que en este caso se asume que las matrices forman una matriz más extensa.
Eso significa que si se emplean dos matrices es como si se utilizara una matriz de 8 filas y 16 columnas. Donde las columnas 0-7 se corresponden con la primera matriz y las columnas 8-15 con la segunda.
1
|
mxObj.setColumn(col, value);
|
Donde:
- col: es un entero que indica la columna a modificar. El valor de col debe estar entre 0 y la cantidad de columnas entre todos los módulos, es decir, que si utilizas tres matices col puede tener valores entre 0 y 23.
- value: es un entero de 8 bits que indica los LEDs a encender. Cada bit puesto a 1 indica que se encenderá su LED correspondiente.
// – Las columnas 8-15 pertenecen a la segunda matriz<br />
// – 0xFF = B11111111<br />
mx.setColumn(10, 0xFF);</p>
<p>// Configurar la última columna de la segunda matriz con todos los LEDs apagados<br />
// – Las columnas 8-15 pertenecen a la segunda matriz<br />
// – 0xFF = B00000000<br />
mx.setColumn(15, 0x00);<br />
1
2
3
4
5
6
7
8
9
10
|
// Configurar la tercera columna de la segunda matriz con todos los LEDs encendidos
// – Las columnas 8-15 pertenecen a la segunda matriz
// – 0xFF = B11111111
mx.setColumn(10, 0xFF);
// Configurar la última columna de la segunda matriz con todos los LEDs apagados
// – Las columnas 8-15 pertenecen a la segunda matriz
// – 0xFF = B00000000
mx.setColumn(15, 0x00);
|
Función setPoint()
Esta función permite encender o apagar un LED indicando su fila y columna.
1
|
mxObj.setPoint(fila, col, estado);
|
Donde:
- fila: indica la fila en que se ubica el LED. Es un valor entre 0 y 7.
- col: indica la columna del LED. Es un valor entre 0 y la cantidad de columnas total.
- estado: indica si el LED se debe encender o apagar.
// – Las columnas 8-15 pertenecen a la segunda matriz<br />
// – true -> encender<br />
mx.setPoint(1, 10, true);</p>
<p>// Apagar el LED de la primera fila y la 7ma columna (7ma columna de la primera matriz)<br />
// – Las columnas 0-7 pertenecen a la primera matriz<br />
// – false -> apagar<br />
mx.setPoint(0, 7, false);
1
2
3
4
5
6
7
8
9
|
// Encender el LED de la segunda fila y la 11na columna (tercera columna de la segunda matriz)
// – Las columnas 8-15 pertenecen a la segunda matriz
// – true -> encender
mx.setPoint(1, 10, true);
// Apagar el LED de la primera fila y la 7ma columna (7ma columna de la primera matriz)
// – Las columnas 0-7 pertenecen a la primera matriz
// – false -> apagar
mx.setPoint(0, 7, false);
|
Función setRow()
Esta función permite establecer el estado de una fila de LEDs.
Primera sobrecarga: necesita tres argumentos y permite establecer el estado de una fila correspondiente a una matriz en particular.
1
|
mxObj.setRow(mat, fil, value);
|
Donde:
- mat: es un entero que indica sobre qué matriz actuar.
- fil: es un entero entre 0 y 7 que indica la fila a modificar
- estado: es un entero de 8 bits con el nuevo estado de la fila. Los bits puestos a uno indican los LEDs que se encenderán.
// – 0xFF = B11111111<br />
mx.setRow(0, 4, 0xFF);</p>
<p>// Encender la mitad de los LEDs de la 6ta fila de la tercera matriz<br />
// – 0xF0 = B11110000<br />
mx.setRow(2, 5, 0xF0);
1
2
3
4
5
6
7
|
// Encender todos los LEDs de la 5ta fila de la primera matriz
// – 0xFF = B11111111
mx.setRow(0, 4, 0xFF);
// Encender la mitad de los LEDs de la 6ta fila de la tercera matriz
// – 0xF0 = B11110000
mx.setRow(2, 5, 0xF0);
|
La segunda sobrecarga solo necesita dos argumentos y establece un nuevo estado en la fila indicada para todas las matrices.
1
|
mxObj.setRow(fil, estado);
|
Donde:
- fil: es un entero entre 0 y 7 que indica la fila a modificar
- estado: es un entero de 8 bits con el nuevo estado de la fila. Los bits puestos a uno indican los LEDs que se encenderán.
// – 0xFF = B11111111<br />
mx.setRow(4, 0xFF);</p>
<p>// Encender la mitad de los LEDs de la 6ta fila de todas las matrices<br />
// – 0xF0 = B11110000<br />
mx.setRow(5, 0xF0);
1
2
3
4
5
6
7
|
// Encender todos los LEDs de la 5ta fila de todas las matrices
// – 0xFF = B11111111
mx.setRow(4, 0xFF);
// Encender la mitad de los LEDs de la 6ta fila de todas las matrices
// – 0xF0 = B11110000
mx.setRow(5, 0xF0);
|
Tercera sobrecarga: admite cuatro argumentos y permite establecer el estado de una fila en un intervalo de matrices.
1
|
mxObj.setRow(matIni, matFin, fil, estado);
|
Donde:
- matIni: es un entero que indica la primera matriz del intervalo.
- matFin: es un entero que indica la última matriz del intervalo.
- fil: es un entero entre 0 y 7 que indica la fila a modificar.
- estado: es un entero de 8 bits con el nuevo estado de la fila. Los bits puestos a uno indican los LEDs que se encenderán.
// – 0xFF = B11111111<br />
mx.setRow(1, 3, 4, 0xFF);</p>
<p>// Encender la mitad de los LEDs de la 6ta fila de las matrices 1, 2 y 3<br />
// – 0xF0 = B11110000<br />
mx.setRow(0, 2, 5, 0xF0);
1
2
3
4
5
6
7
|
// Encender todos los LEDs de la 5ta fila de las matrices 2, 3 y 4
// – 0xFF = B11111111
mx.setRow(1, 3, 4, 0xFF);
// Encender la mitad de los LEDs de la 6ta fila de las matrices 1, 2 y 3
// – 0xF0 = B11110000
mx.setRow(0, 2, 5, 0xF0);
|
Función transform()
Esta función permite aplicar transformaciones a la información mostrada en las matrices, es decir, que permite rotar, desplazar o invertir los LEDs en la matriz.
Primera sobrecarga: admite dos argumentos y permite aplicar una transformación al contenido de una sola matriz.
1
|
mxObj.transform(mat, trans);
|
Donde:
- mat: matriz a la que se le aplicará la transformación.
- trans: tipo de transformación a aplicar.
// – MD_MAX72XX::TINV -> invertir LEDs<br />
mx.transform(1, MD_MAX72XX::TINV );</p>
<p>// Desplazar el contenido de la primera matriz una posición a la izquierda<br />
// – MD_MAX72XX::TSL -> Desplazar a la izquierda<br />
mx.transform(0, MD_MAX72XX::TSL );
1
2
3
4
5
6
7
|
// Invertir todos los LEDs de la segunda matriz
// – MD_MAX72XX::TINV -> invertir LEDs
mx.transform(1, MD_MAX72XX::TINV );
// Desplazar el contenido de la primera matriz una posición a la izquierda
// – MD_MAX72XX::TSL -> Desplazar a la izquierda
mx.transform(0, MD_MAX72XX::TSL );
|
Segunda sobrecarga: admite tres argumentos y permite realizar una transformación a un intervalo de matrices.
1
|
mxObj.transform(matIni, matFin, trans);
|
Donde:
- matIni: es un entero que indica la primera matriz del intervalo.
- matFin: es un entero que indica la última matriz del intervalo.
- trans: tipo de transformación a aplicar.
// – MD_MAX72XX::TSR -> desplazar a la derecha<br />
mx.transform(1, 2, MD_MAX72XX::TSR );
1
2
3
|
// Desplazar el contenido de las matrices 1 y 2 una posición a la derecha
// – MD_MAX72XX::TSR -> desplazar a la derecha
mx.transform(1, 2, MD_MAX72XX::TSR );
|
Tercera sobrecarga: admite un solo parámetro y permite aplicarle una transformación a todas las matrices.
1
|
mxObj.transform(trans);
|
Donde:
- trans: tipo de transformación a aplicar.
mx.transform( MD_MAX72XX::TSU );
1
2
|
// Desplazar el contenido de todas las matrices una posicion hacia arriba
mx.transform( MD_MAX72XX::TSU );
|
En la siguiente tabla tienes el conjunto de transformaciones que puedes realizar con la función transform().
Valor | Transformación |
MD_MAX72XX::TSL | Desplazar un píxel a la izquierda |
MD_MAX72XX::TSR | Desplazar un píxel a la derecha |
MD_MAX72XX::TSU | Desplazar un píxel hacia arriba |
MD_MAX72XX::TSD | Desplazar un píxel hacia abajo |
MD_MAX72XX::TFLR | Voltear de derecha a izquierda |
MD_MAX72XX::TFUD | Voltear de arriba hacia abajo |
MD_MAX72XX::TRC | Rotar 90 grados en sentido horario |
MD_MAX72XX::TINV | Invertir píxeles |
Función setChar()
Esta función permite dibujar un carácter empezando en una columna específica.
1
|
byte w = mxObj.setChar(col, c);
|
Donde:
- col: columna donde comienza el carácter.
- c: carácter a mostrar.
- w: valor retornado por setChar(). Indica cuantas columnas ocupa el carácter dibujado.
int ancho = mx.setChar(9, ‘A’);
1
2
|
// Dibujar el caracter ‘A’ comenzando en la columna 9 (segunda columna de la segunda matriz)
int ancho = mx.setChar(9, ‘A’);
|
Función update()
La función update() actualiza el contenido de la matriz cuando la auto-actualización ha sido deshabilitada.
Primera sobrecarga: no recibe parámetros y actualiza el estado de todas las matrices conectadas.
1
|
mxObj.update();
|
Segunda sobrecarga: admite un parámetro y actualiza solo el estado de la matriz indicada.
1
|
mxObj.update(mat);
|
Donde:
- mat: es el número de la matriz a actualizar.
mx.update(2);
1
2
|
// actualizar la información de la matriz número 3
mx.update(2);
|
Ya conoces cómo conectar un módulo de matriz de LED con Arduino basados en MAX7219 y cómo utilizar las funciones de la librería MD_MAX72xx para controlarla, por lo tanto, ya estas en condiciones de empezar a trabajar.