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í):
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).
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.
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):
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:
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).
Cuando me llegue el sensor de humedad, actualizaré este post para que muestre también la humedad relativa del ambiente.
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
Pingback: Display Adafruit 0.56” de 4 dígitos de 7 segmentos I2C en la Raspberry Pi | Carlini's Blog
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?
Hola, Antonio.
No sé, parece que está bien… ¿No será algún problema con las tabulaciones…?
Vale lo probare, pero otra cosa como haria para que se apagasen todos los segmentos al parar el scripts; quizas con otro scripts?¿ como seria si fuese con otro script.
Gracias por responder
yo lo estoy haciendo con la raspberry pi 3 funcionara igual?
Pone al final del programa:
GPIO.cleanup()
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?