martes, 7 de marzo de 2017

Controlar un display de un dígito y siete segmentos

En este post os voy a mostrar como usar los puertos GPIO y un pequeño programa en Python para controlar de forma directa con la Raspberry Pi, un display de un dígito con siete segmentos. Aquí os dejo una imagen del que he usado yo (modelo SMA42056).



Como podéis ver el dispositivo dispone de 7 segmentos, más un punto en la parte inferior derecha, iluminados por led. Dispone de un total de 10 conexiones (5 en la parte superior y cinco en la inferior para hacerlo funcionar). Para este ejercicio vamos a necesitar, cables de conexión, 1 display de un dígito de 7 segmentos, 8 resistencias de 330 omnios y la RaspberryPi. Si sois nuevos en esto os aconsejo leer los anteriores posts (del uso de los GPIO en el apartado Programación/GPIO).


1. Distribución de las conexiones y los segmentos del display


Vamos a ver como se distribuyen las conexiones del display en relación con los segmentos del mismo, lo mejor es que veáis la siguiente imagen

como podéis ver, el display tiene un total de 10 pines, el pin 3 y 8 son los pines del cátodo o ánodo común (según el tipo de display que tengamos que se identifican con la letra K), sería el pin de tierra. Los pines 1, 2, 4, 5 en la parte inferior y los pines 6, 7, 9 y 10 en la superior son los polos positivos de cada uno de los segmentos del display, aunque se llame display de 7 segmentos, en total hay 8, ya que hay que tener en cuenta el punto decimal (DP) en la parte inferior derecha. En la imagen podéis ver la correspondencia entre los pines y los segmentos.


2. Organización del circuito


En primer lugar vamos a ver como nos debe quedar nuestro circuito para poder controlar un display de un dígito. Aquí os dejo una imagen para que veáis la distribución que he usado, tened cuidado que en este ejercicio hay mucho cable.



si no habéis leído los anteriores post os recomiendo hacerlo (sobretodo el primero, en el que detallo el uso de las conexiones y hay un apartado al final sobre el uso de las resistencias, aquí está el link). 
Bien, como podéis ver uso el pin número 3 (cable negro para tierra, etiquetado como GROUND) este cable hay que conectarlo a los pines K (superior e inferior) del display. El resto de cables salen de los GPIO y funcionarán como polo positivo. En el siguiente cuadro os muestro un resumen de las conexiones entre la RaspberryPi y el display

RaspberryPi Cable Display
GND negro K
GPIO14/TXD0 rojo a
GPIO15/RXD0 gris b
GPIO18/ amarillo c
GPIO23 marrón d
GPIO24 verde e
GPIO25 naranja f
GPIO8/SPICE0 azul g
GPIO7/SPICE1 rosa DP


tened en cuenta que si usáis otro modelo de display las conexiones pueden se diferentes, consultad la documentación técnica para no equivocaros. Por otro lado es mejor que os aseguréis que en la pestaña Interfaces de la pantalla de Configuración de Raspberry Pi, no tengáis activado el SPI, el I2C, etc. ya que vamos a usar pines GPIO que pueden tener varias funciones al activarlos.


3. Código Python

Vamos a crear un pequeño programa en python que al ejecutarlo nos permita controlar los diferentes segmentos del display. Si no sabéis como crear un archivo con un programa en python os recomiendo leer los post sobre programación python del apartado Programación/GPIO del blog.

En primer lugar abrimos el IDLE de Python en nuestra RaspberryPi (yo uso Python3), una vez abierto creamos un nuevo fichero (en el menú File-New File) y introducimos el siguiente código (es largo pero no os preocupéis que es muy sencillo)

# importamos libreria time
import time
# importamos libreria GPIO
import RPi.GPIO as GPIO
#
# configuracion para los GPIO
# usaremos la identificacion BCM para los GPIO
GPIO.setmode(GPIO.BCM)
# desactivamos mensajes de error
GPIO.setwarnings(False)
# indicamos los puertos de salida GPIO
GPIO.setup(14, GPIO.OUT)
GPIO.setup(15, GPIO.OUT)
GPIO.setup(18, GPIO.OUT)
GPIO.setup(23, GPIO.OUT)
GPIO.setup(24, GPIO.OUT)
GPIO.setup(25, GPIO.OUT)
GPIO.setup(8, GPIO.OUT)
GPIO.setup(7, GPIO.OUT)
#
# definimos funcion que apaga o enciende todos los
# segmentos del display según el parametro
# que enviamos 0=apagar 1=encender
def INICIALIZAR_DISPLAY(estado):
    # si enviamos 0 apagamos los segmentos
    if estado == 0:
        GPIO.output(14, False)
        GPIO.output(15, False)
        GPIO.output(18, False)
        GPIO.output(23, False)
        GPIO.output(24, False)
        GPIO.output(25, False)
        GPIO.output(8, False)
        GPIO.output(7, False)
    else: # si enviamos 1 encendemos los segmentos
        GPIO.output(14, True)
        GPIO.output(15, True)
        GPIO.output(18, True)
        GPIO.output(23, True)
        GPIO.output(24, True)
        GPIO.output(25, True)
        GPIO.output(8, True)
        GPIO.output(7, True)
#
# definimos funcion para hacer un test del display
# enciende uno a uno los segmentos con un
# retraso indicado por el parametro demora
def TEST_DISPLAY(demora):
    # aparagamos todos los segmentos
    INICIALIZAR_DISPLAY(0)
    # los encendemos uno a uno
    GPIO.output(14, True)
    time.sleep(demora)
    GPIO.output(15, True)
    time.sleep(demora)
    GPIO.output(18, True)
    time.sleep(demora)
    GPIO.output(23, True)
    time.sleep(demora)
    GPIO.output(24, True)
    time.sleep(demora)
    GPIO.output(25, True)
    time.sleep(demora)
    GPIO.output(8, True)
    time.sleep(demora)
    GPIO.output(7, True)
#
# definimos funcion que recibe un parametro que debe ser
# un número o un punto y enciende los segmentos
# correspondientes del display
def PRINT_DISPLAY(digito):
    INICIALIZAR_DISPLAY(0) # apagamos todos los segmentos
    # activamos los segmentos para cada número
    if digito== "0": # numero 0
        GPIO.output(14, True) # segmento a
        GPIO.output(15, True) # segmento b
        GPIO.output(18, True) # segmento c
        GPIO.output(23, True) # segmento d
        GPIO.output(24, True) # segmento e
        GPIO.output(25, True) # segmento f
    elif digito== "1": # numero 1
        GPIO.output(15, True) # segmento b
        GPIO.output(18, True) # segmento c
    elif digito== "2": # numero 2
        GPIO.output(14, True) # segmento a
        GPIO.output(15, True) # segmento b
        GPIO.output(23, True) # segmento d
        GPIO.output(24, True) # segmento e
        GPIO.output(8, True) # segmento g
    elif digito== "3": # numero 3
        GPIO.output(14, True) # segmento a
        GPIO.output(15, True) # segmento b
        GPIO.output(18, True) # segmento c
        GPIO.output(23, True) # segmento d
        GPIO.output(8, True) # segmento g
    elif digito== "4": # numero 4
        GPIO.output(15, True) # segmento b
        GPIO.output(18, True) # segmento c
        GPIO.output(25, True) # segmento f
        GPIO.output(8, True) # segmento g
    elif digito== "5": # numero 5
        GPIO.output(14, True) # segmento a
        GPIO.output(18, True) # segmento c
        GPIO.output(23, True) # segmento d
        GPIO.output(25, True) # segmento f
        GPIO.output(8, True) # segmento g
    elif digito== "6": # numero 6
        GPIO.output(14, True) # segmento a
        GPIO.output(18, True) # segmento c
        GPIO.output(23, True) # segmento d
        GPIO.output(24, True) # segmento e
        GPIO.output(25, True) # segmento f
        GPIO.output(8, True) # segmento g
    elif digito== "7": # numero 7
        GPIO.output(14, True) # segmento a
        GPIO.output(15, True) # segmento b
        GPIO.output(18, True) # segmento c
    elif digito== "8": # numero 8
        GPIO.output(14, True) # segmento a
        GPIO.output(15, True) # segmento b
        GPIO.output(18, True) # segmento c
        GPIO.output(23, True) # segmento d
        GPIO.output(24, True) # segmento e
        GPIO.output(25, True) # segmento f
        GPIO.output(8, True) # segmento g
    elif digito== "9": # numero 9
        GPIO.output(14, True) # segmento a
        GPIO.output(15, True) # segmento b
        GPIO.output(18, True) # segmento c
        GPIO.output(23, True) # segmento d
        GPIO.output(25, True) # segmento f
        GPIO.output(8, True) # segmento g
    elif digito== ".": # DP (punto decimal)
        GPIO.output(7, True) # segmento DP
#
# Codigo para ejecutar las funciones
# con la siguiente funcion encendemos todos segmentos
INICIALIZAR_DISPLAY(1)
# damos un tiempo de espera
time.sleep(0.5)
# con la siguiente funcion apagamos todos los segmentos
INICIALIZAR_DISPLAY(0)
#damos un tiempo de espera
time.sleep(0.5)
# llamamos a la funcion que enciende los segmentos
# uno a uno con un tiempo de espera
TEST_DISPLAY(0.2)
#damos un tiempo de espera de un segundo
time.sleep(1)
# con la siguiente funcion apagamos todos los segmentos
INICIALIZAR_DISPLAY(0)
# con el siguente bucle infinito podemos introducir un
# numero o un punto y al hacer intro aparecera en el
# display
while (True):
    # mensaje para el usuario
    tecla=input("introduzca un número o punto y presione Intro en el teclado: ")
    # llamamos a la funcion que ilumina los segmentos
    PRINT_DISPLAY(tecla)
    

guardamos el archivo en una ubicación conocida (en el menú File-Save As), si es necesario apuntad la ruta por si la necesitáis usar más tarde. 

Podemos ejecutar directamente este pequeño programa presionando la tecla F5 (también se puede ejecutar des de el menú Run-Run Module)

La primera parte del código prepara los GPIO y los módulos necesarios. Seguidamente he definido la función INICIALIZAR_DISPLAY () que recibe el parámetro estado, si recibe un 0 todos los segmentos del display se apagan, si recibe un 1 todos los segmentos del display se encienden. La segunda función definida es TEST_DISPLAY() que recibe el parámetro demora, esta función enciende uno a uno los segmentos del display con el tiempo de demora establecido en el parámetro demora. La tercera y última función PRINT_DISPLAY() recibe el parámetro dígito, que puede ser un número o un punto y activa el segmento o segmentos necesarios para que se muestre en el display. La última parte del código ejecuta las diferentes funciones para ver su funcionamiento.

Si todo es correcto se abre una nueva ventana de IDLE de python y empieza la ejecución, el display inicialmente encenderá todos los segmentos, luego se apagarán, y empezarán a iluminarse los segmentos uno a uno, una vez iluminados todos los segmentos se apagarán todos y en la pantalla de ejecución podremos introducir un número, o el punto y al hacer Intro en el teclado aparecerá en el display. 

Espero que os haya gustado (acepto críticas), hasta pronto!