Display de 4 dígitos de 7 segmentos en la Raspberry Pi

Para el monitor de bebé que estoy construyendo quiero un display en el que mostrar la temperatura de un sensor, la humedad, y ya de paso, la hora. Voy a emplear el siguiente display de 4 dígitos de 7 segmentos (ver hoja de referencia aquí):

4x7LED1

Lo compré aquí por menos de 2€. Hay varios modelos muy similares, con dos puntos entre el tercer y cuarto dígito, con algún puntito más, pero se manejan todos de la misma forma.

Buceando por google, encontré un par de páginas que explican (más o menos), cómo llegar a hacerlos funcionar conectados a una Raspberry Pi. Pongo los links más abajo.

Lo primero es conocer el funcionamiento del display, que no es más que 4 bloques (dígitos) de números que aparecen representados por 7 leds (por eso se llaman 7 segmentos, aunque en realidad este modelo tiene un led/segmento más, por el punto decimal).

220px-7_segment_display_labeled.svg

Cada segmento se numera de A a G, y el punto decimal (DP).

Como tener encendidos todos los leds que necesitásemos indistintamente al mismo tiempo para representar los números correspondientes en el display requeriría más corriente de la que la Raspberry puede proporcionar, se recurre a una técnica llamada multiplexing, que consiste en ir encendiendo sucesivamente y de forma muy rápida cada uno de los segmentos que queremos tener encendidos, de forma que el ojo humano no es capaz de percibir que en realidad no están todos encendidos al mismo tiempo.

4x7LED2

4x7LED3-2

Esquema

4x7LED5

La conexión con la Raspberry Pi la hago según el siguiente esquema, empleando una resistencia para cada segmento (las conexiones de los 4 dígitos no llevan resistencias):

FW0Y6QZI2BYJMXU.LARGE

No voy a explicar el funcionamiento del GPIO de la Raspberry Pi, pero es bastante sencillo (y maravilloso). Estudiando el código más abajo se puede entender muy fácilmente.

Y lo monto todo de manera pseudo-definitiva sobre una placa:

image2

Display de 4 dígitos de 7 segmentos. Montaje sobre placa (vista frontal)

image3

Display de 4 dígitos de 7 segmentos. Montaje sobre placa (vista trasera, con algunas soldaduras algo chapurreras)

El código que empleo para que el display actúe como un reloj es el siguiente (tomado y modificado de aquí), que guardo en un fichero llamado reloj.py:

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

segments = (24,12,19,21,23,22,15,11)

for segment in segments:
        GPIO.setup(segment, GPIO.OUT)
        GPIO.output(segment, 0)

digits = (26,18,16,13)

for digit in digits:
        GPIO.setup(digit, GPIO.OUT)
        GPIO.output(digit, 1)

num =  {' ':(0,0,0,0,0,0,0),
        '0':(1,1,1,1,1,1,0),
        '1':(0,1,1,0,0,0,0),
        '2':(1,1,0,1,1,0,1),
        '3':(1,1,1,1,0,0,1),
        '4':(0,1,1,0,0,1,1),
        '5':(1,0,1,1,0,1,1),
        '6':(1,0,1,1,1,1,1),
        '7':(1,1,1,0,0,0,0),
        '8':(1,1,1,1,1,1,1),
        '9':(1,1,1,1,0,1,1)}

try:
        while True:
            n = time.ctime()[11:13]+time.ctime()[14:16]
            s = str(n).rjust(4)
            for digit in range(4):
                for loop in range(0,7):
                    GPIO.output(segments[loop], num[s[digit]][loop])

                if (int(time.ctime()[18:19])%2 == 0) and (digit == 1):
                    GPIO.output(11, 1)
                else:
                    GPIO.output(11, 0)

                GPIO.output(digits[digit], 0)
                time.sleep(0.001)
                GPIO.output(digits[digit], 1)

except KeyboardInterrupt:

        GPIO.cleanup()

Para ejecutarlos, basta con hacer sudo python reloj.py.

Y como lo que quiero es que el display no sólo muestre la hora, sino que también muestre la temperatura de un termómetro DS18B20 que tengo conectado a la Raspberry Pi, y que se vaya alternando la hora y la temperatura cada 5 segundos, empleo el suguiente código, que guardo en un fichero llamado relojYtemp.py:

import os #Para el termómetro
import RPi.GPIO as GPIO
import time

#Cargo los módulos para el termómetro:
os.system("sudo modprobe wire")
os.system("sudo modprobe w1-gpio")
os.system("sudo modprobe w1-therm")

#Función para obtener la temperatura del sensor interior:
def get_temp_sens1():
        try:
                tfile = open("/sys/bus/w1/devices/28-00000557e1a7/w1_slave")
                text = tfile.read()
                tfile.close()
                secondline = text.split("\n")[1]
                temperaturedata = secondline.split(" ")[9]
                temperature = float(temperaturedata[2:])
                temperature = temperature / 1000
                temperature = round (temperature,1)
        except:
                temperature = 0
        return float(temperature)

#print get_temp_sens1()

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

segments = (24,12,19,21,23,22,15,11)

for segment in segments:
        GPIO.setup(segment, GPIO.OUT)
        GPIO.output(segment, 0)

digits = (26,18,16,13)

for digit in digits:
        GPIO.setup(digit, GPIO.OUT)
        GPIO.output(digit, 1)

num =  {' ':(0,0,0,0,0,0,0),
        '0':(1,1,1,1,1,1,0),
        '1':(0,1,1,0,0,0,0),
        '2':(1,1,0,1,1,0,1),
        '3':(1,1,1,1,0,0,1),
        '4':(0,1,1,0,0,1,1),
        '5':(1,0,1,1,0,1,1),
        '6':(1,0,1,1,1,1,1),
        '7':(1,1,1,0,0,0,0),
        '8':(1,1,1,1,1,1,1),
        '9':(1,1,1,1,0,1,1)}


try:
        while True:
            temp = str(int(get_temp_sens1()*10)).rjust(4)

            t_fin = time.time() + 5
            while time.time() < t_fin:
                for digit in range(4):
                    for loop in range(0,7):
                        GPIO.output(segments[loop], num[temp[digit]][loop])

                    if (digit == 2):
                        GPIO.output(11, 1)
                    else:
                        GPIO.output(11, 0)

                    GPIO.output(digits[digit], 0)
                    time.sleep(0.001)
                    GPIO.output(digits[digit], 1)

            t_fin = time.time() + 5
            while time.time() < t_fin:
                n = time.ctime()[11:13]+time.ctime()[14:16]
                s = str(n).rjust(4)
                for digit in range(4):
                    for loop in range(0,7):
                        GPIO.output(segments[loop], num[s[digit]][loop])

                    if (int(time.ctime()[18:19])%2 == 0) and (digit == 1):
                        GPIO.output(11, 1)
                    else:
                        GPIO.output(11, 0)

                    GPIO.output(digits[digit], 0)
                    time.sleep(0.001)
                    GPIO.output(digits[digit], 1)


except KeyboardInterrupt:

        GPIO.cleanup()

(Ya expliqué en este post cómo usar el sensor de temperatura DS180B20 con la Raspberry Pi).

Display de 4 dígitos de 7 segmentos, conectado a la Raspberry Pi junto con sensor DS18B20

Display de 4 dígitos de 7 segmentos, conectado a la Raspberry Pi junto con sensor DS18B20

Cuando me llegue el sensor de humedad, actualizaré este post para que muestre también la humedad relativa del ambiente.

El display mostrando la temperatura en la cuna

El display mostrando la temperatura en la cuna

Si queremos ahorrarnos tanto cable y programación, también se venden estos displays con un controlador incorporado, de forma que podemos conectarlos fácilmente a la Raspberry Pi por I2C. Pero son de 5 a 10 veces más caros, claro (por ejemplo, este). En otra entrada explicaré su manejo.

 

Referencias

  • http://www.instructables.com/id/Controlling-a-7-segment-4-digit-display-with-a-Ras/
  • http://www.techni.ca/2014/11/drive-7-segment-4-digit-display-with.html
  • https://www.raspberrypi.org/forums/viewtopic.php?f=37&t=91796
  • http://rpi.science.uoit.ca/lab/ssdispay/
  • http://razzpisampler.oreilly.com/ch09.html
  • http://learn.parallax.com/4-digit-7-segment-led-display-arduino-demo
  • http://ahoj.io/raspberry-pi-s-load-on-a-7-segment-display
  • http://hackyourmind.org/articles/2013/06/07/raspberry-pi-with-7-segment-display.html

 

7 pensamientos en “Display de 4 dígitos de 7 segmentos en la Raspberry Pi

  1. Pingback: Display Adafruit 0.56” de 4 dígitos de 7 segmentos I2C en la Raspberry Pi | Carlini's Blog

  2. Hola queria preguntar que en el codigo de python de relojYtemp me da error de sintaxis en la linea 56 pero no se por que a que se podria deber?

  3. Como se haria un script en python para que con los datos que muestra en el display los cogiese y los metiese en un archivo de texto en el que saliese la hora y la temperatura, como seria?

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *