Termómetro ambiental digital construido a partir de: Arduino Uno, sensor de temperatura y visualizador de tres dígitos de siete segmentos. |
Utilizaremos un visualizador multiplexado de tres dígitos de siete segmentos para desplegar en grados Celsius la temperatura ambiente obtenida a partir de las lecturas de un sensor TMP36. Este proyecto contrasta con nuestro proyecto anterior en el que la información del sensor de temperatura solo se imprimía en una terminal en la pantalla de la computadora.
Visualizador multiplexado
Para controlar un visualizador de siete segmentos (SSD por sus siglas en inglés) se necesitan conectar nueve pines: siete pines para controlar los segmentos, un pin para el punto decimal, y otro pin que sirve de ánodo o cátodo común.Si queremos desplegar n dígitos usando n SSDs individuales, necesitaríamos un total de 9 × n conexiones. Sin embargo, si usamos un visualizador multiplexado, también conocido como MD por sus siglas en inglés (multiplexed display), solo requerimos 8 + n pines: siete pines para los segmentos, un pin para el punto decimal, y n pines de ánodo o cátodo común (un pin por cada dígito). En nuestro proyecto queremos usar tres dígitos, por lo que bajamos de 27 conexiones (9 × 3) a tan solo 11 (8 + 3) al momento de utilizar multiplexado.
Visualizador multiplexado o MD (multiplexed display) de tres dígitos, de siete segmentos por cada dígito. |
La técnica de multiplexado se basa en una característica que tiene la vista humana conocida como persistencia de la retina, en donde conservamos la sensación de ver una imagen aún cuando ésta ya despareció. Si creamos una intermitencia encendiendo y apagando un led, al momento en que ésta sea lo suficientemente rápida ya no apreciamos que el led llega a apagarse sino que nos da la sensación de que está permanentemente encendido.
Para el MD de n dígitos el multiplexado consiste en encender los segmentos deseados del dígito a desplegar en la primera posición, pausar por Δ segundos y apagar después todos los segmentos. Lo anterior lo repetimos secuencialmente con el dígito de la segunda posición, después con el dígito de la tercera posición y así hasta llegar al dígito de la n-ésima posición para luego comenzar nuevamente con el dígito de la primera posición y continuar así sucesivamente. El valor de Δ debe ser suficientemente breve para dar la impresión de un encendido continuo. A base de prueba y error determinamos que 0.001 segundos (una milésima de segundo) genera el efecto deseado en nuestro programa de Python.
El MD para nuestro proyecto es uno de la serie KW3-561 el cual puede verse de manera esquemática así:
Pines y segmentos de un visualizador multiplexado de tres dígitos. |
El MD tiene doce pines numerados del 1 al 12 con la siguiente correspondencia (notar que el pin 6 no se utiliza):
- Pin 1: Segmento E
- Pin 2: Segmento D
- Pin 3: Segmento P (punto decimal)
- Pin 4: Segmento C
- Pin 5: Segmento G
- Pin 6: No se utiliza
- Pin 7: Segmento B
- Pin 8: Ánodo o cátodo común de DIG_3 (dígito de la tercera posición)
- Pin 9: Ánodo o cátodo común de DIG_2 (dígito de la segunda posición)
- Pin 10: Segmento F
- Pin 11: Segmento A
- Pin 12: Ánodo o cátodo común de DIG_1 (dígito de la primera posición)
A partir de lo ya discutido estamos en condiciones de esbozar un algoritmo un poco más formal para realizar el multiplexado de un MD de tres dígitos de la forma
DD.D
:- Sea n un número en base decimal (0 ≤ n < 100) conformado por tres dígitos d1, d2 y d3, en donde n = d1×10 + d2 + d3×0.1; es decir, d1 son las decenas, d2 son las unidades y d3 son las décimas de unidad. Repetir lo siguiente mientras se desee desplegar n en el MD:
- Para i de 1 hasta 3:
- Mandar una señal de encendido a la posición de DIG_i, y una señal de apagado a todas las demás posiciones.
- Encender o apagar los segmentos A, B, C, D, E, F y G correspondientes al valor del dígito di (la entrada del “Visualizador de siete segmentos” detalla puntalmente la manera de hacer esto). Adicionalmente, si i = 2, encender el segmento P (punto decimal), de lo contrario apagarlo.
- Pausar por Δ segundos.
- Apagar todos los segmentos correspondientes al dígito di.
Armando el proyecto
Esta es la lista de componentes necesarios para nuestro proyecto:- Arduino Uno.
- MD de ánodo común KW3-561ASN (dígitos rojos de 14.2 mm de altura).
- Sensor de temperatura TMP36.
- Protoboard.
- Ocho resistencias de 330Ω (bandas naranja, naranja, café).
- Cables conectores.
Vista de protoboard Fritzing para el termómetro ambiental digital. |
Cada pin asociado a un segmento del MD debe quedar conectado, con una resistencia de 330Ω de por medio, a un pin digital del Arduino. Estas son las conexiones que se muestran en la figura anterior:
- El pin digital 2 del Arduino se conecta al pin 1 (SEG_E) del MD.
- El pin digital 3 del Arduino se conecta al pin 2 (SEG_D) del MD.
- El pin digital 4 del Arduino se conecta al pin 3 (SEG_P) del MD.
- El pin digital 5 del Arduino se conecta al pin 4 (SEG_C) del MD.
- El pin digital 6 del Arduino se conecta al pin 5 (SEG_G) del MD.
- El pin digital 7 del Arduino se conecta al pin 11 (SEG A) del MD.
- El pin digital 8 del Arduino se conecta al pin 10 (SEG_F) del MD.
- El pin digital 9 del Arduino se conecta al pin 7 (SEG_B) del MD.
- El pin digital 10 del Arduino se conecta al pin 12 (DIG_1) del MD.
- El pin digital 11 del Arduino se conecta al pin 9 (DIG_2) del MD.
- El pin digital 12 del Arduino se conecta al pin 8 (DIG_3) del MD.
- El pin de 5V del Arduino se conecta al pin Vs (pin izquierdo) del TMP36.
- El pin analógico A0 del Arduino se conecta al pin Vout (pin central) del TMP36.
- Algún pin GND del Arduino se conecta al pin GND (pin derecho) del TMP36.
El software
El código fuente completo en Python 3 del proyecto se muestra a continuación. Contiene diversos comentarios con el fin de ayudar a su comprensión.#!/usr/bin/env python3 # Archivo: termometro_digital.py import pyfirmata from time import time # Valor de delta para el multiplexado. PAUSA_MULTIPLEXADO = 0.001 # Leer la temperatura después de este número de segundos. PAUSA_LECTURAS = 60 # Iniciar la placa de Arduino. # IMPORTANTE: Cambiar la cadena de caracteres que indica # el puerto serie que utiliza nuestra plataforma. placa = pyfirmata.Arduino('/dev/ttyACM0') # Crear un thread iterador, de lo contrario la placa puede # seguir enviando datos por la conexión serial hasta # producir un desbordamiento. pyfirmata.util.Iterator(placa).start() # Inicializar el pin de entrada analógica 0 del Arduino # para conectarlo al pin Vout del TMP36. entrada_temperatura = placa.get_pin('a:0:i') entrada_temperatura.enable_reporting() # Incicializar los pines de salida digital para los # segmentos del MD. segmento = [ placa.get_pin('d:4:o'), # SEG_P/Ard_4/MD_3 placa.get_pin('d:6:o'), # SEG_G/Ard_6/MD_5 placa.get_pin('d:8:o'), # SEG_F/Ard_8/MD_10 placa.get_pin('d:2:o'), # SEG_E/Ard_2/MD_1 placa.get_pin('d:3:o'), # SEG_D/Ard_3/MD_2 placa.get_pin('d:5:o'), # SEG_C/Ard_5/MD_4 placa.get_pin('d:9:o'), # SEG_B/Ard_9/MD_7 placa.get_pin('d:7:o') # SEG_A/Ard_7/MD_11 ] # Inicializar los pines de salida digital para las # conexiones del ánodo común de las posiciones DIG_1, # DIG_2 y DIG_3 del MD. posicion = [ placa.get_pin('d:10:o'), # DIG_1/Ard_10/MD_12 placa.get_pin('d:11:o'), # DIG_2/Ard_11/MD_9 placa.get_pin('d:12:o'), # DIG_3/Ard_12/MD_8 ] # Diseños de los dígitos individuales. Este programa no # utiliza los diseños de la A a la F. patron = [ # ABCDEFGP <-- Segmentos # -------- 0b11111100, # 0 0b01100000, # 1 0b11011010, # 2 0b11110010, # 3 0b01100110, # 4 0b10110110, # 5 0b10111110, # 6 0b11100000, # 7 0b11111110, # 8 0b11110110, # 9 0b11101110, # A 0b00111110, # b 0b10011100, # C 0b01111010, # d 0b10011110, # E 0b10001110 # F ] def voltios_a_celsius(v): """Convierte un voltaje v obtenido de un sensor TMP36 a grados Celsius. """ return 100 * (v - 0.5) def binario(n): """Devuelve como lista el valor binario de n. La lista resultante es de la forma: [bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7] Los bit8 en adelante son ignorados. """ resultado = [] for i in range(8): resultado.append(n & 1) n >>= 1 return resultado def activa_posicion(n): """Enciende el pin correspondiente al dígito de la posición n de un MD, apagando los pines restantes. n = 0: DIG_1 n = 1: DIG_2 n = 2: DIG_3 """ for i, d in enumerate(posicion): d.write(i == n) def despliega_digito(d, puntodec=False): """Despliega el digito d en la posición actualmente activa (DIG_1, DIG_2 o DIG_3) del MD. Si d es menor a 0 o mayor a 15 apaga todos los segmentos. Si puntodec es True, enciende el segmento correspondiente al punto decimal. """ d = ((patron[d] if 0 <= d <= 15 else 0b00000000) | puntodec) for pin, bit in zip(segmento, binario(d)): # El operador 'not' de la siguiente instrucción se # necesita debido a que el MD es de ánodo común. # Dicho operador se debe omitir si el MD es de # cátodo común. pin.write(not bit) def despliega_numero(n): """Despliega el número n en un visualizador multiplexado (MD) con tres dígitos de siete segmentos (SSD). El valor desplegado siempre tiene la forma: DD.D donde D es un dígito del 0 al 9. Despliega 88.8 si el valor de n es menor a cero o mayor o igual a 100. """ if n < 0 or n >= 100: fmt = '888' else: fmt = '{:03}'.format(round(n * 10)) for i, d in enumerate(fmt): activa_posicion(i) despliega_digito(int(d), i == 1) placa.pass_time(PAUSA_MULTIPLEXADO) despliega_digito(-1) def lee_temperatura(): """Realiza la lectura del voltaje de un sensor de temperatura TMP36 y devuelve el valor obtenido convertido a grados Celsius. """ while True: v = entrada_temperatura.read() if v != None: v *= 5 return voltios_a_celsius(v) # El algoritmo de multiplexado comienza aquí. try: tiempo = 0 while True: # Tomar nueva lectura de temperatura después de # PAUSA_LECTURAS segundos. # Esta condición es verdadera en la primera # iteración (tiempo == 0). if time() > tiempo + PAUSA_LECTURAS: tiempo = time() temperatura = lee_temperatura() despliega_numero(temperatura) except KeyboardInterrupt: # Terminar programa cuando se presione Ctrl-C. # Apagar los SSDs de las tres posiciones. for i in range(3): activa_posicion(i) despliega_digito(-1) finally: placa.exit()Para correr el programa se necesita tener el Arduino conectado por el puerto USB a la computadora anfitriona y ejecutar el siguiente comando desde una terminal en el mismo directorio donde se encuentra el archivo
termometro_digital.py
:
python3 termometro_digital.pySi todo resulta bien se debe poder ver la temperatura ambiente en el visualizador. El programa corre hasta que presionemos Ctrl-C para terminar.