En este post vamos a ver cómo usar Python, una Raspberry Pi y los puertos GPIO para trabajar con un visualizador de 7 segmentos.
Al final vamos a dibujar los números del 0 al 9 de una manera sencilla.
Display de 7 segmentos: ánodo y cátodo
Es importante recordar que hay 2 tipos de displays, unos son de ánodo común y otros son de cátodo común.
Si es de ánodo común, entonces debes escribir un LOW sobre la entrada que quieres encender. Y en caso de que sea de cátodo común debes escribir un HIGH sobre la entrada.
Además, para ánodo común debes conectar el común a 5 volts, y para cátodo común debes conectar el común a tierra.
Para guiarme siempre me ha servido la siguiente imagen (que no es mía):
Puertos GPIO
Me voy a referir a cada puerto por su número consecutivo, y no por su número GPIO. En la siguiente imagen puedes ver que el GPIO 25 es el puerto número 22; pues en el código de Python me referiré al consecutivo, que en este caso sería el 22.
Circuito para display de 7 segmentos
Voy a reutilizar el circuito de mi anterior post sobre gpio y display 7 segmentos desde la terminal.
Mis displays son de cátodo común así que el común va conectado a GND. Si, en tu caso, son de ánodo común, entonces el común iría al 5 v.
No olvides que debes usar una resistencia (de 220 o 47 ohm) por cada letra del display.
Definiendo las letras
Nota: te recomiendo ver mi post sobre GPIO y Python.
Como ves en el circuito de arriba cada letra está conectada a determinado pin. He definido un diccionario para facilitar las cosas:
diccionario = {
'A': 10,
'B': 12,
'C': 16,
'D': 11,
'E': 13,
'F': 8,
'G': 32,
}
De este modo, si la conexión cambia, las letras no se ven afectadas.
Dibujo de números
Para dibujar los números debemos encender o apagar determinada terminal del visualizador de 7 segmentos.
Yo los he definido como binarios, en donde un 1 es encender y un 0 es apagar. Todos siguen el orden de las letras, es decir, el primer bit es la A, el segundo la B, etcétera.
numeros = {
'0': '1111110',
'1': '0110000',
'2': '1101101',
'3': '1111001',
'4': '0110011',
'5': '1011011',
'6': '1011111',
'7': '1110000',
'8': '1111111',
'9': '1110011',
}
Los argumentos
Este script de python va a aceptar el número que se desea dibujar como argumento de línea de comandos, para que se pueda invocar con:
python main.py NUMERO
Así que la lectura de argumentos se hace así:
parser = argparse.ArgumentParser()
parser.add_argument("numero", help="Número que quieres dibujar")
argumentos = parser.parse_args()
Gracias a que tenemos un diccionario de números podemos usar el número leído desde la terminal para obtener la representación en binario con:
numero = numeros.get(argumentos.numero)
Dibujando valor en display de siete segmentos con Python
Una vez que tenemos la cadena binaria que vamos a dibujar sobre el display recorremos el diccionario de pines y leemos la cadena binaria; si es un 1 entonces encendemos el led (porque mi visualizador es de cátodo común) y si no, lo apagamos.
El código que los dibuja es:
contador = 0
for clave in diccionario:
valor = diccionario.get(clave)
bit = numero[contador]
estado = GPIO.LOW
if bit == "1":
estado = GPIO.HIGH
GPIO.output(valor, estado)
contador = contador + 1
De este modo nos ahorramos escribir código, pues mientras nuestro diccionario esté bien definido todo saldrá a la perfección.
Código completo
Ahora veamos el código que hace que todo esto sea posible:
"""
Programado por Luis Cabrera Benito
____ _____ _ _ _
| _ \ | __ \ (_) | | |
| |_) |_ _ | |__) |_ _ _ __ _____| |__ _ _| |_ ___
| _ <| | | | | ___/ _` | '__|_ / | '_ \| | | | __/ _ \
| |_) | |_| | | | | (_| | | / /| | |_) | |_| | || __/
|____/ \__, | |_| \__,_|_| /___|_|_.__/ \__, |\__\___|
__/ | __/ |
|___/ |___/
Blog: https://parzibyte.me/blog
Ayuda: https://parzibyte.me/blog/contrataciones-ayuda/
Contacto: https://parzibyte.me/blog/contacto/
"""
import RPi.GPIO as GPIO
import time
import argparse
diccionario = {
'A': 10,
'B': 12,
'C': 16,
'D': 11,
'E': 13,
'F': 8,
'G': 32,
}
numeros = {
'0': '1111110',
'1': '0110000',
'2': '1101101',
'3': '1111001',
'4': '0110011',
'5': '1011011',
'6': '1011111',
'7': '1110000',
'8': '1111111',
'9': '1110011',
}
GPIO.setmode(GPIO.BOARD)
for clave in diccionario:
valor = diccionario.get(clave)
GPIO.setup(valor, GPIO.OUT)
parser = argparse.ArgumentParser()
parser.add_argument("numero", help="Número que quieres dibujar")
argumentos = parser.parse_args()
numero = numeros.get(argumentos.numero)
contador = 0
for clave in diccionario:
valor = diccionario.get(clave)
bit = numero[contador]
estado = GPIO.LOW
if bit == "1":
estado = GPIO.HIGH
GPIO.output(valor, estado)
contador = contador + 1
Para invocarlo pasa un número del 0 al 9 como primer argumento. Por ejemplo, para dibujar el 0 sería:
python siete_segmentos.py 0
Puedes indicar cualquier número y, mientras esté soportado, funcionará.
Bonus: dibujar números del 0 al 0 de manera recursiva
Podemos hacer que se dibujen los números de manera infinita, invocando al script de Python con bash. Esto es opcional, pues el script ya funciona bien, sin embargo, como demostración podemos usar lo siguiente:
for numero in 0 1 2 3 4 5 6 7 8 9
do
/usr/bin/python3 ./siete.py $numero
sleep 1
done
bash probar_siete.sh
Es un simple ciclo for que va del 0 al 9 e invoca al script de Python con ese número; para después dormir 1 segundo.
Al final del script se vuelve a invocar al mismo, así que estará siempre en ejecución hasta que se presione CTRL + C
. Yo lo he probado y se ve así:
Espero que el lector disculpe el movimiento de la cámara, pero no se me ocurrió tomarlas en opción burst shoot y al momento de escribir esto ya he desarmado el circuito.
Por cierto, la diferencia en el brillo es porque no he usado resistencias del mismo valor.
Si quieres puedes leer más sobre Raspberry o Python en mi blog.