17 diciembre 2012

Fabricando un contador simple con Arduino y un display de 7 segmentos



Luego de la entrada sobre interconexión entre la Raspberry y el Arduino vía Serial, vamos a comenzar una serie de entradas donde construiremos distintos módulos que nos permitirán conocer las distintas funcionalidades básicas del Arduino. Luego de finalizar esta serie de artículos tendremos un pequeño módulo de pruebas que será capaz de realizar realizar algunas tareas interesantes:

  1. Desplegar información a traves de un display de 7 segmentos.
  2. Capturar eventos del usuario mediante pulsadores.
  3. Monitorear y controlar nuestro Arduino mediante la conexión serial que probamos previamente.

Si bien los módulos pueden construirse por separado y prácticamente hemos cubierto la mitad del tercer punto, pensé que sería más interesante ir armando cada módulo paso a paso y luego poner todo en conjunto para ver como trabaja. En esta primera entrada vamos a hacer uso de las funciones digitalWrite para controlar un pequeño display de 7 segmentos conectado a nuestro Arduino Mega.


Desplegando información a través de un display de 7 segmentos.


Seguramente todos hemos visto en las peliculas cuando el héroe está a punto de desactivar la bomba que destruirá la ciudad y hay un pequeño contador que cuenta hasta cero. Sin embargo, lamento desilucionarlos, en este post no van a encontrar como fabricar una bomba, sino más bien como utilizar los display de 7 segmentos para aplicaciones más pacíficas como por ejemplo  hacer un mini reloj o un contador de personas.

Usualmente utilizando electrónica digital tendríamos que hacer un circuito que se encargue de controlar el display, en internet podemos encontrar un sin fín de ejemplos de como hacerlo. La ventaja que tenemos al hacerlo con el Arduino es que nos permite reducir el tiempo de desarollo. En este caso en vez de calcular toda la circuitería digital nos encargaremos que el Arduino, mediante un programa se encargue de desplegar los números que nosotros querramos.

¿Qué es un display de 7 segmentos?


Un display de 7 segmentos no es nada más que un arreglo de diodos LED dispuestos de tal manera, que nos permiten visualizar números cuando estos se encuentran encendidos en ciertas combinaciones.

Estos se venden en distintos colores, pero el más común es el color rojo. En general, pueden adquirir de dos tipos: Anodo común o de Cátodo común. Dicho "mal y pronto" esto significa que la línea comun entre los distintos díodos puede ser la que va hacia tierra, para el caso de los de cátodo común o la que viene del positivo en caso contrario.

Para este sencillo ejemplo utilizaremos un display de 7 segmentos de cátodo común porque simplemente es un poco más fácil de explicar ya que utiliza "lógica positiva" un 1 lógico activa el led y un 0 lógico lo desactiva..

Listo, ya tenemos nuestro display. Ahora... ¿Como controlamos que numeros se visualizan?


Si estuvieramos trabajando con electrónica digital deberíamos de hacer una tabla de verdad y definir todas las combinaciones que quisieramos visualizar, por ejemplo, utilizando la codificación BCD (números binarios del 0 al 9). Luego, calcularíamos una ecuación que nos serviría para construir el circuito que nos permitiría controlar nuestro display con diversas puertas lógicas.

Como esta no es una entrada acerca de lógica booleana ni circuitos digitales vamos a ahorrarnos ese paso y vamos a adquirir el circuito integrado 7448. Este circuito es un integrado de tecnología TTL en el que alguien ya se tomó el trabajo de generar la circuitería necesaria para decodificar las líneas que contienen el código BCD a las líneas correspondientes en nuestro display de 7 segmentos.


Para conectar nuestro decodificador BCD a 7-Segmentos utilizaremos unas simples resistencias de 330 Ohms y conectaremos todo como se muestra en el siguiente circuito:


Aquí pueden ver algunas fotografías de como se ve el integrado junto con el display. Nota: Algunas líneas las he pasado por debajo del display:


Preparando el código del Arduino


Si observaron el circuito cada línea representa un valor específico en potencias de dos. Con cuatro líneas digitales podemos representar hasta 16 combinaciones de números, o en otras palabras podemos representar desde el 0 al 15. El código BCD es una pequeña reducción de este rango ya que con las 4 líneas únicamente podemos contar hasta 9. Si alimentamos nuestro decodificador con numeros mayores presentará algunos caracteres raros que posiblemente no nos interesen para mayor cosa.

Antes de seguir vamos a definir algunas constantes, primero utilizaremos las líneas 4 al 7. Originalmente usé las líneas 0 al 3 pero el Arduino Mega que poseo utiliza las líneas 1 y 2 como puerto Serial, así que al iniciar el arduino o cargar un nuevo programa el display mostraba caracteres raros. Lo mejor fué entonces dejar el display en las otras líneas.

# Lineas de datos
const int D0 = 4;
const int D1 = 5;
const int D2 = 6;
const int D3 = 7;

Definiendo una pequeña función de ayuda


A veces es mas sencillo definir algunas funciones que nos ayudarán a simplificar el código. En este caso vamos a definir una pequeña función llamada writeTo7seg que nos ayudará a escribir directamente a las líneas.

void writeTo7Seg(byte num) {
  digitalWrite(D0, (num&1)==1);
  digitalWrite(D1, (num&2)==2);
  digitalWrite(D2, (num&4)==4);
  digitalWrite(D3, (num&8)==8);
}

¿Que hace esta función? Este es un método abreviado de conversion a BCD utilizando "máscaras" con la operación booleana AND. Tal vez en decimal sea un poco difícil de comprender por lo que les dejo un ejemplo en "binario".

Imaginemos por ejemplo que tenemos el numero 7, en binario esto sería igual a 0111, significa que las líneas deberán tener los siguientes valores D0=1, D1=1, D2=1, D3=0. En C podemos fácilmente intercambiar los valores booleanos True y False por 1 y 0 respectivamente.

Lo que sucede internamente en la función es lo siguiente:
Para D0:
  0111
& 0001
= 0001==0001
= True

Para D1:
  0111
& 0010
= 0010==0010
= True

Para D2:
  0111
& 0100
= 0100==0100
= True

Para D3:

  0111
& 1000
= 0000==1000
= False

Por último ponemos todo junto, establecemos las líneas y agregamos algunos If que se encargaran de incrementar el contador:

const int D0 = 4;
const int D1 = 5;
const int D2 = 6;
const int D3 = 7;

byte inc;

void writeTo7Seg(byte num) {
  digitalWrite(D0, (num&1)==1);
  digitalWrite(D1, (num&2)==2);
  digitalWrite(D2, (num&4)==4);
  digitalWrite(D3, (num&8)==8);
}

void setup() {
  // put your setup code here, to run once:
  pinMode(D0,OUTPUT);
  pinMode(D1,OUTPUT);
  pinMode(D2,OUTPUT);
  pinMode(D3,OUTPUT);
  
  inc = 0;
}

void loop() {
  inc = (inc < 10) ? inc : 0;

  writeTo7Seg(inc);
 
  inc++;
  delay(1000);
}

Es necesario que coloquemos un delay para poder apreciar el cambio. Si es demasiado rápido no podremos observar nada Si todo ha funcionado según lo planificado, nuestro circuito deberá de funcionar de la siguiente manera:

Conclusión

Las función digitalWrite combinadas con un poco de código y un poco de circuitería externa nos pueden servir fácilmente para poder desplegar información. En esta entrada hemos utilizado un pequeño display para mostrar valores internos almacenados en el Arduino.

En la próxima entrada nos encargaremos del trabajo con interrupciones para poder capturar eventos externos.

Fuentes y Referencias


2 comentarios:

alx hudson dijo...

y como se podria utilizar en 2 display? y sin incrementar, por ejemplo que se tomara el incremento de otro dato ?

manuel carvalo dijo...

https://www.youtube.com/watch?v=ERdvQi1r5Kg