sábado, 16 de febrero de 2013

Cubo de LEDs 3x3x3 controlado con Python, GPIOs y Raspberry Pi

Cubo de LEDs 3x3x3


Para quien ha seguido las publicaciones en este blog resultará normal el hecho de que incrementemos el nivel de dificultad de un proyecto a otro. Primero vimos como encender y apagar un LED, luego como manejar 4 LEDs en una secuencia determinada para obtener una secuencia binaria usando LEDs y decimal utilizando un  display de 7 segmentos.

Para este proyecto, necesitaremos el siguiente material:


  • Cautin
  • Soldadura
  • Cable
  • 27 LEDs
  • 3 transistores NPN
  • Placa fenólica perforada
  • Cable plano de 26 hilos
  • Conector IDC-26 hembra

El problema


Hasta el momento no hemos hecho mas que utilizar un pin GPIO para cada uno de los LEDs que queremos controlar, el dia de hoy tendremos que resolver una situación, ¿como controlaremos de manera individual 27 LEDs cuando la Raspberry Pi solo nos puede proveer de 17 pines GPIO?

La solución


La solución que utilizaremos para resolver la pregunta anterior es una combinación de software y la forma en la que conectaremos los LEDs entre ellos para optimizar el uso de los pines GPIO.

El cubo que construiremos tiene 3 niveles de 3 LEDs por lado, esto es 3 x 3 x 3 = 27 LEDs.

Aunque esto ya debería ser familiar, lo primero que tenemos que identificar es el ánodo (+) y el cátodo (-) de los LEDs. Al observar las conexiones de los LEDs observaremos que una es ligeramente mas larga que la otra, eso es lo que nos ayudara a identificar el ánodo (+) del LED, por consecuencia, la conexión mas corta del LED es el cátodo (-).



Lo que haremos para armar el primer nivel del cubo será tomar 9 LEDs y doblar completamente el cátodo (-) desde la base del LED hasta que quede en un ángulo de 90 grados con respecto al ánodo (+), como se muestra a continuación.


Ahora, hay que soldar los cátodos de tal forma que obtengamos una matriz de 3x3. A continuación se muestran los 3 niveles ya terminados.


Una vez terminados los 3 niveles, a continuación los apilaremos uno sobre otro, a una distancia adecuada para que los ánodos (+) se puedan soldar entre ellos. Al final tendremos 9 columnas de ánodos (+) y 3 niveles de cátodos. Por lo que cada LED individual puede ser identificado con una coordenada única en 3 dimensiones, y lo mejor de todo, hemos resulto nuestro problema inicial, pues ¡solo utilizaremos 12 pines GPIOs!

¿Tan facil?


Una vez que hemos resuelto el problema anterior hasta parece trivial, ¿cierto? pues este proyecto ahora nos presenta otro problema que debemos resolver, los GPIOs de la Raspberry Pi son pines digitales y pueden ser controlados para enviar (HIGH) o no enviar (LOW) voltaje de acuerdo a nuestras necesidades pero nuestro diseño requiere poder enviar voltaje positivo a los ánodos (las columnas del cubo) y voltaje negativo a los cátodos (cada uno de los niveles) así que ¿cómo vamos a enviar voltaje negativo a los niveles del cubo?


Aqui la solución radica en el uso de transistores utilizados como interruptores, en el cual basicamente lograremos que al enviarle corriente al transistor usando los GPIOs este permitira el flujo de la corriente negativa que tendremos conectada a una de sus terminales, tal como se muestra en el diagrama siguiente:



Habiendo hecho esto para cada uno de los 3 niveles del cubo hemos terminado con la parte del hardware, ahora voltearemos hacia el software.


El Código


#!/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 = [0,1,4,14,15,17,18,21,22,23,24,10]

# 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 - LOW completed."

levelpins = [1,4,0]
pins = [ [23,24,10] , [18,21,22] , [14,15,17] ]
delay = 0.2
loops = 10

#Initialize all LEDs to off
for y in range(0,3) :
  GPIO.output(levelpins[y],False)
  for x in range(0,3) :
   for z in range(0,3) :
    GPIO.output(pins[x][z],False)

print "Start patterns"

print "LED by LED, bottom left front to top right back"
for loopcount in range(loops/2) :
 for y in range(0,3) :
  GPIO.output(levelpins[y],True)
  for x in range(0,3) :
   for z in range(0,3) :
    GPIO.output(pins[x][z],True)
    time.sleep(delay/2)
    GPIO.output(pins[x][z],False)
  GPIO.output(levelpins[y],False)

print "Column by column, left front to right back"
for loopcount in range(loops/2) :
 for y in range(0,3) :
  GPIO.output(levelpins[y],True)
 for x in range(0,3) :
  for z in range(0,3) :
  GPIO.output(pins[x][z],True)
   time.sleep(delay)
   GPIO.output(pins[x][z],False)
 GPIO.output(levelpins[y],False)

print "Row by Row, bottom front to top back"
for loopcount in range(loops) :
 for y in range(0,3) :
  GPIO.output(levelpins[y],True)
  for z in range(0,3) :
   for x in range(0,3) :
    GPIO.output(pins[x][z],True)
   time.sleep(delay)
   for x in range(0,3) :
    GPIO.output(pins[x][z],False)
  GPIO.output(levelpins[y],False)

print "Row by Row, bottom left to top right"
for loopcount in range(loops) :
 for y in range(0,3) :
  GPIO.output(levelpins[y],True)
  for x in range(0,3) :
   for z in range(0,3) :
    GPIO.output(pins[x][z],True)
   time.sleep(delay)
   for z in range(0,3) :
    GPIO.output(pins[x][z],False)
  GPIO.output(levelpins[y],False)

print "Level by Level, bottom to top"
for x in range(0,3) :
 for z in range(0,3) :
  GPIO.output(pins[x][z],True)
for loopcount in range(loops) :
 for y in range(0,3) :
  GPIO.output(levelpins[y],True)
  time.sleep(delay)
  GPIO.output(levelpins[y],False)
for x in range(0,3) :
 for z in range(0,3) :
  GPIO.output(pins[x][z],False)

El Resultado Final



Espero que esta referencia pueda ser de su utilidad

No hay comentarios.:

Publicar un comentario