domingo, 31 de marzo de 2013

Controlar una matriz de LEDs de 5x5 con Raspberry Pi, Python y GPIOs

Controlar una matriz de LEDs de 5x5 con Raspberry Pi, Python y GPIOs


Tras una larga ausencia que raya en el descuido de este blog, me encuentro de nuevo por aqui para platicarles como hacer una matriz de LEDs de 5x5 para el despliegue de texto.

Ya que tenemos el Cubo de LEDs de 3x3x3 pareceria que hacer un matriz de 5x5 sería ir un paso atras en cuanto a complejidad, sin embargo este proyecto nos ayudara a perfeccionar el manejo de algunos elementos de Python como lo son las listas.

En esta ocasión tomaremos ventaja de un efecto visual denominado POV (Persistencia de la Visión por sus siglas en inglés) el cual nos permite engañar a nuestro sentido de la vista haciéndonos creer que múltiples LEDs están encendidos cuando en realidad prendiendo y apagando a un ritmo muy rápido.


El material


Para armar la matriz necesitaremos 25 LEDs, 5 transistores NPN, cable (preferentemente de dos colores diferentes) cautín y soldadura.

El material seleccionado para hacer la base es una espuma recubierta de cartón delgado de 5mm que es ligero, barato y puede darnos una estructura sólida para nuestra matriz. Ademas de un cutter, bisturí o exacto para poder hacer cortes precisos y pegamento para unir las piezas.

Se corta un cuadrado de 27cm por lado que sera la base, además se cortarán 8 rectángulos de 5cm x 27 cm para las divisiones internas, 2 rectángulos de 28 cm x 5.5 cm y por ultimo 2 rectángulos de 27 cm x 5.5 cm.


La construcción


Sobre la base cuadrada se harán marcas en cada uno de los cuatro lados a las siguientes distancias de la orilla:

- 5 cm
- 5.5 cm
- 10.5 cm
- 11 cm
- 16 cm
- 16.5 cm
- 21.5 cm
- 22 cm

ahora uniremos con lápiz las lineas correspondientes de tal forma que queden definidos 25 cuadrados, ademas quedarán identificadas las lineas donde estarán las 8 divisiones (4 horizontales y 4 verticales).

Les recomiendo trazar también unas lineas diagonales que dividan todos los cuadrados en dos triángulos rectángulos y después trazar las diagonales opuestas para de esta manera tener identificado el centro de cada uno de los cuadrados, que será la posición donde colocaremos nuestros LEDs.

Los 8 rectángulos de 5 cm x 27 cm tambien tendrán las mismas marcas por el lado largo que los lados del cuadrado ademas, por el lado corto, habra que hacer una marca a 2.5 cm de cada lado y unirla con lápiz a todo lo largo.

En estos 8 rectángulos cortaremos esas pequeñas áreas de 5mm x 2.5 cm (todas por el mismo lado del rectángulo) que nos permitirán inter-conectar estas piezas para armar el entrelazado de las divisiones interiores. Una vez inter-conectadas las piezas nos aseguraremos de que esten bien alineadas para poder poner pegamento por uno de sus lados y afianzarlo a la base cuadrada en su posición.

Ya para finalizar, tenemos dos pares de rectángulos, uno de ellos ligeramente mas largo que el otro. Estos nos servirán paralos bordes de la matriz, asegúrese de pegar primero el par de rectángulos largos en lados opuestos y al final los mas cortos para terminar con la matriz.


El circuito


Para controlar la matriz, utilizaremos solo 10 pines de la Raspberry Pi, 5 para las filas y 5 para las columnas. Todas las filas estarán conectando entre sí los ánodos y al final iran a uno de los pines de la Raspberry Pi, las columnas unirán los cátodos e irán conectados a la salida de los transistores NPN, tal como lo hicimos en el cubo de 3x3x3.


El código


Como se menciono al inicio de este post, el hacer este ejercicio nos ayudara a perfeccionar nuestras habilidades para usar listas en Python, la razón de esto es que cada uno de los caracteres que desplegaremos en la matriz lo deberemos de definir nosotros en una lista de 5x5 que tendra 1 o 0 en cada una de sus posiciones, correspondiendo directamente a LED encendido o apagado. A continuación les muestro el código que se uso para generar los caracteres numéricos. Para facilitar la visualización y legibilidad, el número 0 ha sido realzado en los elementos de la lista.


#numbers
chars.append([
"01110",
"10011",
"10101",
"11001",
"01110"
])
chars.append(["00100","01100","00100","00100","11111"])
chars.append(["11110","00001","01110","10000","11111"])
chars.append(["11110","00001","00110","00001","11110"])
chars.append(["10001","10001","01111","00001","00001"])
chars.append(["11111","10000","11110","00001","11110"])
chars.append(["01111","10000","11110","10001","01110"])
chars.append(["11111","00010","00100","00100","00100"])
chars.append(["01110","10001","01110","10001","01110"])
chars.append(["01110","10001","01111","00001","00110"])

Este es el código que mostrará los caracteres en la matriz:


#!/usr/bin/env python

# Import required libraries
import time
import RPi.GPIO as GPIO

# Set up the GPIO mode
GPIO.setmode(GPIO.BCM)

#Initialize a list with the GPIO pin numbers we are going to use
gpiopins = [14,15,18,21,23,24,10,25,8,7]

# Set up pins listed as outputs
print "Setting up pins ",
for p in gpiopins :
 print str(p) + " ",
 GPIO.setup(p, GPIO.OUT)
 #GPIO.setup(p, GPIO.LOW)
print "for OUPUT completed."

cols = [14,18,23,10,8]
rows = [7,25,24,21,15]

chars = []

chars.append([...
...
...])


def getLetter(letter):
 return chars[ord(str(letter))]

def drawMatrix(mtx):
 #print mtx
 t = time.clock() + 0.4
 while t > time.clock() :
  for i in range(0,5) :
   for j in range(0,5) :
    if mtx[i][j] == "1" :
     GPIO.output(cols[j],True)
     GPIO.output(rows[i],True)
     #time.sleep(0.005)
     GPIO.output(cols[j],False)
     GPIO.output(rows[i],False)

def drawString(text):
 text = text + chr(32)
 for l in range(len(text)):
  drawMatrix(getLetter(text[l]))
 time.sleep(0.4)

def scrollText(text):
 mtx = ["","","","",""]
 text = chr(32) + text.strip() + chr(32)
 l1 = getLetter(text[0])
 for i in range(len(text)-1):
  l2 = getLetter(text[i+1])
  for j in range(0,5):
   mtx[j] = l1[j] + "000" + l2[j]
  #print mtx
  drawScrollingMatrix(mtx)
  l1 = l2
  #time.sleep(0.05)

def drawScrollingMatrix(mtx):
  for offset in range(0,8):
   t = time.clock() + 0.14
   while t > time.clock() :
    for i in range(0,5) :
     for j in range(0,5) :
      if mtx[i][j+offset] == "1" :
       GPIO.output(cols[j],True)
       GPIO.output(rows[i],True)
       GPIO.output(cols[j],False)
       GPIO.output(rows[i],False)

#initialize all LEDs to off
for i in range(0,5) :
 GPIO.output(cols[i], False)
 GPIO.output(rows[i], False)

#control variables
delay = 0.5

print "Start patterns"
drawString("RASPBERRY PI & PYTHON & GPIO")
scrollText("RASPBERRY PI & PYTHON & GPIO")

El resultado





Saludos!