lunes, 27 de febrero de 2017

Controlar una matriz LED de 8x8 con MAX7219

Hola a todos, hace tiempo compré un kit de aprendizaje (de la marca KEYES) en el que venían un montón de LED, botones, sensores varios, una de las cosas que en ese momento me llamó la atención era un panel LED de 8x8 que iba colocado en una pequeña placa que incorporaba un chip MAX7219CNG. Más tarde descubrí que todo ello era un pequeño grupo de elementos para facilitar el control de la matriz de 8x8 y que además permite conectar hasta 8 elementos iguales y formar una matriz mayor. Este es el aspecto que tiene montado



sin embargo se trata de una placa base con un zócalo para el chip MAX7219CNG, y dos zócalos para conectar la matriz de leds, y algunos otros componentes, desmontado el aspecto es el siguiente 




pero si no queréis soldar y perder tiempo se vende ensamblado en este formato y otros a un precio realmente asequible.

Este post os voy a mostrar como controlar esta matriz LED de 8x8, usando el chip controlador MAX7219. Vamos a usar nuestra Raspberry Pi, la placa con la matriz led de 8x8 y el chip MAX7219CNG, y 4 cables (en este caso usaré cables hembra-hembra ya que voy a prescindir de la placa de pruebas para hacer las conexiones)


1. Requisitos previos

1.1. Activar SPI
Para utilizar todos estos componentes en primer lugar tenemos que habilitar el bus SPI de la Raspberry Pi desde el apartado de configuración. Si disponéis de la versión actualizada de Raspbian y estáis en modo escritorio vais al botón Inicio - Preferencias - Configuración de Raspberry Pi, se abrirá la ventana de configuración, haced click en la pestaña Interfaces, seguramente la opción SPI esá desactivada, acivad la opción y pulsad el botón Aceptar



si no disponéis de una versión actualizada de Raspbian o bien os conectáis mediante consola tendréis que usar el comando sudo raspi-config para abrir el panel de configuración, tenéis que encontrar la opción para activar el SPI, en versiones antiguas está en Advanced Options, pero en las últimas versiones está en Interfacing Options, una vez localizada la opción SPI la tendréis que activar.



una vez activado desde el escritorio o desde la consola reiniciad el dispositivo. Ahora vamos a comprobar que esté en funcionamiento. abrid una pantalla de terminal y poned la orden

lsmod | grep -i spi

al hacer intro nos deberia devolver una línea parecida a esta, 

spi_bcm2825 7424 0 

en algunos casos según el kernel os devolverá spi_bcm2807 (no pasa nada), seguidamente introducimos la orden

ls -l /dev/spi*

al hacer Intro esto nos devolverà dos líneas parecidas a estas

crw-------- 1 root root 153, 0 Jan 1 1970 /dev/spidev0.0
crw-------- 1 root root 153, 1 Jan 1 1970 /dev/spidev0.1

si es así todo perfecto, en caso contrario aseguraos que el bus esta activo y por si acaso reiniciad el dispositivo.


1.2. Instalar el driver SPI y librerias
Antes que nada actualizaremos el repositorio y de paso nuestro sistema, para ello abriremos una pantalla de terminal y usaremos la orden

sudo apt-get update

hacemos intro en el teclado y esperamos a que finalice, y luego

sudo apt-get upgrade

hacemos intro en el teclado y a esperar (esta vez será un poco más largo). Una vez haya finalizado la actualización reiniciad la Raspberry Pi.
Una vez reiniciada vamos instalar el driver para SPI y librerías Python, desde una pantalla de terminal ejecutamos la  orden 

sudo usermod -a -G spi,gpio pi

hacemos Intro, la siguente orden es

git clone https://github.com/rm-hull/luma.led_matrix.git

esto descargará del repositorio de luma.led_matrix una copia de los archivos necesarios para instalar las librerías, la copia se realizará en una carpeta llamada luma.led_matrix, con la siguiente orden accederemos a esta carpeta

cd luma.led_matrix

hacemos Intro en el teclado, la siguiente orden es mas larga (yo uso python3, si vosotros usáis una versión anterior sustituid python3 por python)

sudo apt-get install python3-dev python3-pip libfreetype6-dev libsdl1.2-dev

hacemos intro en el teclado, y la orden final para ejecutar el instalador (yo uso python3, si vosotros usáis una versión anterior sustituid python3 por python)

sudo python3 setup.py install

Al hacer Intro se instalan las librerias Python para poder controlar la matriz led. Si con las diferentes órdenes no os devuelve ningún error, todo correcto, si abrís el explorador de archivos veréis que en /home/pi/ se ha creado la carpeta luma.led_matrix dentro encontraréis documentación y ejemplos de uso.
Para acabar solo deciros que esta librería está en evolución de manera que es posible que en el futuro el método de instalación cambie, aquí os dejo el link oficial del apartado de instalación que he usado yo

https://luma-led-matrix.readthedocs.io/en/latest/install.html#max7219-devices-spi



2. Organización del circuito


Aquí tenéis la distribución que he usado yo para las conexiones, he usado cables hembra-hembra para conectar la Raspberry Pi directamente a la placa, pero también podéis conectar la placa a una protoboard, lo más importante es que os aseguréis que conectáis correctamente los cables:

Placa Raspberry Pi Función
Pin Nombre Pin Etiqueta
1 VCC 2 5V 5V
2 GND 6 GND Ground
3 DIN 19 GPIO 10 (MOSI) Data In
4 CS 24 GPIO 8 (SPI CS0) Chip Select
5 CLK 23 GPIO 11 (SPI CLK) Clock

aquí tenéis una imagen de como me ha quedado a mí el circuito (he usado una Raspberry Pi 3, si usáis otro modelo aseguraos que conectáis correctamente los pines). Si tenéis dudas consultad el post anterior (Conector GPIO principos basicos), y si vuestro modelo de RaspberryPi no está consultad la documentación oficial



3. Código Python

3.1 . Ejecutar un porgrama de ejemplo
Vamos a ver algo de código para poder ver este dispositivo en funcionamiento. Para empezar si ya habéis activado el SPI y habéis instalado todo lo necesario y tenéis el circuito a punto, abrid una nueva pantalla de terminal y ejecutad la orden

sudo python3 luma.led_matrix/examples/matrix_demo.py

haced intro y el dispositivo empezará a funcionar. Si os da error aseguraos de que la ruta del archivo que ejecutáis es correcta (hay que ejecutar el archivo matrix_demo.py que se encuentra en la carpeta luma.led_matrix/examples), que las conexiones están bien y todas las piezas del dispositivo de la matriz correctamente colocadas (en mi caso aunque ya venia todo montado, el chip max7219 no estaba correctamente colocado en el zócalo y lo tuve que acabar de montar ya que no conectaba correctamente)

3.2. Más código python 
En el archivo de ejemplo podéis ver como se usa, pero os dejo dos ejemplos sencillos que he extraído de este archivo para que podáis empezar ahora mismo. En el siguiente código se muestra un texto desplazándose en los 6 tipos de letra que nos permite la librería que hemos descargado


# importamos la libreria GPIO
import RPi.GPIO as  GPIO
# desactivamos mensajes error de GPIO
GPIO.setwarnings(False)
# importamos las librerias necesarias para trabajar con
# la matriz led 8x8
from luma.led_matrix import legacy
from luma.led_matrix.device import max7219
from luma.core.serial import spi
# inicializamos los objetos para el dispositivo
serial=spi(port=0,device=0)
device=max7219(serial)
# guardamos en una variable el texto que queremos mostrar
msg = "frambuesa-pi.blogspot.com.es"
# mostramos el texto en la matriz led 8x8 con fuente CP437
legacy.show_message(device, msg, fill="white",  font=legacy.proportional(legacy.CP437_FONT))
# mostramos el texto en la matriz led 8x8 con fuente DEFAULT_FONT
legacy.show_message (device, msg, fill="white", font=legacy.proportional(legacy.DEFAULT_FONT))
# mostramos el texto en la matriz led 8x8 con fuente LCD_FONT
legacy.show_message(device, msg, fill="white", font=legacy.proportional(legacy.LCD_FONT))
# mostramos el texto en la matriz led 8x8 con fuente SINCLAIR_FONT
legacy.show_message(device, msg, fill="white", font=legacy.proportional(legacy.SINCLAIR_FONT))
# mostramos el texto en la matriz led 8x8 con fuente TINY_FONT
legacy.show_message(device, msg, fill="white", font=legacy.proportional(legacy.TINY_FONT))
# mostramos el texto en la matriz led 8x8 con fuente UKR_FONT
legacy.show_message(device, msg, fill="white", font=legacy.proportional(legacy.UKR_FONT))


En el siguiente ejemplo podemos ver una imagen fija (la letra X) y a través de un bucle que se repite 5 veces controlamos la intensidad de los leds

# importamos la libreria GPIO
import RPi.GPIO as  GPIO
# desactivamos mensajes de error GPIO
GPIO.setwarnings(False)
# importamos las librerias necesarias para trabajar con
# la matriz led 8x8
from luma.led_matrix import legacy
from luma.led_matrix.device import max7219
from luma.core.serial import spi
from luma.core.render import canvas
# importamos libreria time
import time
# inicializamos los objetos para el dispositivo
serial=spi(port=0,device=0)
device=max7219(serial)
# guardamos en una variable el texto que queremos mostrar
msg = "X"
# mostramos un texto fijo en la matriz led
with canvas(device) as draw:
    legacy.text(draw, (0, 0), text=msg, fill="white")
# creamos doble bucle que aumenta el brillo del texto
for x in range(5):
    for intensity in range(16):
        device.contrast(intensity * 16)

        time.sleep(0.5)

El tercer y último ejemplo de código dibuja un recuadro, en primer lugar con el borde iluminado y luego con el interior iluminado


# importamos la libreria GPIO
import RPi.GPIO as  GPIO
# desactivamos mensajes error de GPIO
GPIO.setwarnings(False)
# importamos las librerias necesarias para trabajar con
# la matriz led 8x8
from luma.led_matrix import legacy
from luma.led_matrix.device import max7219
from luma.core.serial import spi
from luma.core.render import canvas
# importamos la libreria time
import time
# inicializamos los objetos para el dispositivo
serial=spi(port=0,device=0)
device=max7219(serial)
# mostramos un recuadro con el borde iluminado
with canvas(device) as draw:
    draw.rectangle(device.bounding_box,outline="white", fill="black")
# tiempo espera de dos segundos
time.sleep(2)
# mostramos un recuadro con el interior iluminado
with canvas(device) as draw:
    draw.rectangle(device.bounding_box,outline="black", fill="white")

espero que os haya gustado y os ayude a no perder tiempo (sobretodo con la instalación), por otro lado si alguien dispone de código para la matriz led, que quiera compartir me encantaría verlo, a ver que es todo lo que se puede hacer, cambiar la orientación de las letras, dibujar formas concretas... hasta pronto!