G027 Display de 7 Segmentos

Descripción
Si se quiere hacer un circuito que realice alguna función práctica, hay un 50% de probabilidades de que se necesite enviar información al mundo exterior.


El mercado ofrece componentes para mostrar información y para empezar, nada mejor que un sencillo display LED de 1 digito.

Un Display LED son un grupo de diodos LED que tienen forma de barra y están formado por 7 barras más 1 punto.

Estos displays nos son típicos en despertadores y similares, están formados por 7 líneas, que a dependiendo de qué segmentos  se iluminan, muestran los dígitos del 0 al 9.

A cada uno de los 7 segmentos se les adjudica una letra para representarlos y suele ser a, b, c, e, f, g y aparte un punto (o dos, o dos puntos según el fabricante) y es un buen momento para echar un vistazo a las especificaciones de cada fabricante para estar seguros de que pin es cual.

Todos los circuitos, los displays incluidos, llevan un código de fabricante rotulado. Es buena política buscar en internet la hoja de especificaciones(o data sheet) y echarle un ojo. Lo expuesto aquí es para el que tengo en este momento, cada vez que tenga un display, buscar su data sheet, que que puede parecer el mismo por fuera pero puede ser distinto por dentro.

 
Lo importante es que sepáis que es cada pin, y que veáis que segmento es cual. En realidad es bastante más fácil de lo que parece, localizad primero un GND. 

Poned una resistencia de 330Ω de la salida del display a GND. Este es un display de cátodo común, o sea que todos los LEDS comparten la masa, pero necesita una resistencia de limitación o se quemará el display.

Una vez que hayáis conectado la masa común con una resistencia, se empieza cableando un solo un LED, el a por ejemplo,  se conecta al pin 2 de Arduino. Se escribe un programa en Arduino para iluminar el LED en el pin 2 y se verá como se enciende el segmento a.
Se puede ir conectando y probando el resto de los pines poco a poco, asegurando las conexiones. Cuidado es muy fácil equivocarse si no se está atento.
 
Para saber cual es el pin 1, poner el display de modo que viendo los numeros el punto decimal quede abajo a vuestra derecha. El pin numero 1 es en la parte inferior el primero por la izquierda, y luego ir contando en el sentido contrario a las agujas del reloj.
 
Materiales
placa de arduino
1 resistencia de 330
1 display de 7 segmento
Protoboard, cables para conexiones y el cable USB para conectar arduino al PC y que sirve además de alimentación
 
Esquema 
Lo primero es que el display de este esquema no tiene punto, por eso solo hay 7 conexiones, pero si tuviese el punto habria 8 conexiones.

También trae una sola patilla a la que va la resistencia y esta a masa. Lo normal es que los displays traiga dos una arriba y otra abajo, solo hay que conectar una de ellas.

Estamos hablando de un display de cátodo común.  Al comprar hay que tener en cuenta, de no equivocarse, porque también hay displays de ánodo común, en estos caso el positivo va a la resistencia y esta va conectada al ánodo común. El resto de los LEDs van a masa.  Pero este no es el caso que ocupa aquí. 
 
Este circuito es más sencillo
Lo más importante que seguir un esquema para que luego el programa coincida con las conexiones.

Por eso no es importante que pin de vuestro display es el segmento C (Que dependerá del fabricante y modelo), pero si que es importante que el segmento C vaya al pin digital 4 de Arduino y lo mismo para los demás. 
Montaje
A diferencia del esquema, en el montaje hemos montado un Display de 8 segmentos cableado según el patillaje del que tengo yo, siendo el segmento a la barra horizontal de abajo y ese va al pin 2. El segmento b es la barra vertical izquierda de abajo y va al pin 3. EL segmento c es la barra vertical izquierda de arriba y va al pin 4, el segmento d es la barra horizontal de arriba y va al pin 5, el segmento e es la barra vertical derecha de arriba y va al pin 6, el segmento f es la barra vertical derecha de abajo y va al pin 7, el segmento g es la barra vertical del centro y va a pin 8, el punto va al pin 9.  Así que partiendo desde arduino y siguiendo las conexiones se llega a las patilla que corresponden con el display que tengo yo.  Este es el orden para Arduino, aunque cambie el patillaje del display.  Por supuesto el cátodo común va a masa.





















Código
Lo primero es comprobar que las conexiones son correctas para ello vamos a usar este primer código

void setup(){
  for (int i = 2; i<11; i++){
    pinMode(i, OUTPUT);
  }  
}
void loop(){
  for ( int j= 2; j<11 ; j++){
    digitalWrite(j, HIGH);
    delay(400) ;
  }
  for ( int j= 2; j<11 ; j++){
    digitalWrite(j, LOW);
    delay(400) ;
  }
}

En el setup, inicializamos los 8 pines de salida con for y en el loop usamos una primera iteración que va iluminando los 8 segmentos con un delay, y en la segunda los borra y vuelta a empezar. La idea es comprobar que las conexiones son correctas. Se debe de ver que los segmentos se van encendiendo en el orden que hemos dicho, primero el a, luego el b y así sucesivamente y cuando estén todos encendidos se apagarán en el mismo orden y luego todo empieza de nuevo.

Lo siguiente es mostrar los dígitos del 0 al 9.
Para ello, lo más rápido es hacerte una tabla para ver que segmentos se tiene que iluminar para cada digito decimal, y se va apuntando cuales son 1 (encendido) o 0 (apagado).

  DIGITO a b c d e f g punto
  0 1 1 1 1 1 1 0 0
1 0 0 0 0 1 1 0 0
2 1 1 0 1 1 0 1 0
3 1 0 0 1 1 1 1 0
4 0 0 1 0 1 1 1 0
5 1 0 1 1 0 1 1 0
6 1 1 1 1 0 1 1 0
7 0 0 0 1 1 1 0 0
8 1 1 1 1 1 1 1 0
9 1 0 1 1 1 1 1 0

Ahora solo queda escribir el programa que dibuja los números en el display, así que vamos a ello.
 
La primera idea que se nos ocurre a todos es hacer una función por cada digito que queramos representar. Por ejemplo podríamos hacer:
void Display7()
   {
       digitalWrite(2, 1) ;        // Si, podemos decir 1 y 0 en lugar de HIGH y LOW
       digitalWrite(3,1);
       digitalWrite(4,1);
       digitalWrite(5,0);
       …………..
   }
Es decir, encendemos los pines correspondientes a cada segmento a imagen de la tabla previa.


El problema de este enfoque es que hay que hacer 10 funciones como esta y luego escribir en el programa principal algo que llame a la función correspondiente según el número que queramos mostrar.

Esta es, de nuevo, la solución de fuerza bruta y no es elegante, nos gustan las soluciones elegantes.

Por cierto, para ser alguien en la comunidad, hay que hablar de la elegancia del código siempre que surja la ocasión, para ser un buen programador es muy importante que empezar a adoptar las poses del gremio. 

Una solución más elegante es empezar por un array de 10 x 8  y se ve que el programa se simplifica mucho.

Vamos a empezar definiendo el array de dos dimensiones (porque es una tabla, otra cosa son el número de elementos por dimensión):
byte  Digit[10][8] =                // Arduino UNO va muy justo de memoria. Por eso lo
{                                   // definimos como byte y no como int
   { 1,1,1,1,1,1,0,0 },    // 0  
   { 0,0,0,0,1,1,0,0 },    // 1
   { 1,1,0,1,1,0,1,0 },    // 2
   { 1,0,0,1,1,1,1,0 },    // 3
   { 0,0,1,0,1,1,1,0 },    // 4
   { 1,0,1,1,0,1,1,0 },    // 5
   { 1,1,1,1,0,1,1,0 },    // 6
   { 0,0,0,1,1,1,0,0 },    // 7
   { 1,1,1,1,1,1,1,0 },    // 8
   { 1,0,1,1,1,1,1,0 }     // 9
};

Se ha copiado directamente la tabla de mostrar los dígitos, pero en un array de 10 elementos, cada uno de los cuales es un array de 8(segmentos). La sintaxis es más o menos complicada, pero no hay más.

Podemos ahora crear una función, que pasándole un número de 0 a 9, elija la fila del array en función de ese mismo número y busque el array interno correspondiente.
void Display(int N){
  for (int i= 0 ; i<8 ; i++){
    int valor = Digit[N][i] ;
    int pin = i+2;
    digitalWrite(pin , valor) ;
  }
}

Buscamos  valor en la tabla cuyo índice principal N apunta al array interno correspondiente.  El for i, va leyendo los 8 elementos del array para escribirlos en el pin correspondiente de salida, que lo calculamos como i +2, (Porque usamos los pines 2 al 10 para conectar los segmentos del display y así unos valores de 1 de 0 a 8 se convierten en pines de 2 al 10).
void setup(){
  for (int i= 2; i<11; i++){
    pinMode(i, OUTPUT);
  }  
}
void loop(){
  for ( int k=0 ; k<10 ; k++){    // Llama a Display para k de 0 a 9, los digitos
    Display(k);
    delay(1000);
  }
}
void Display(int N){
  for (int i= 0 ; i<8 ; i++){
    int valor = Digit[N][i];
    int pin = i+2;
    digitalWrite(pin , valor) ;    // digitalWrite(i+2 , Digit[N][i] ) ;
  }
}
Fijaros que podíamos haber escrito así (El código compacto también puntúa con los colegas):
void Display(int N){
  for (int i= 0 ; i<8 ; i++){
    int valor = Digit[N][i];
    int pin = i+2;
    digitalWrite(pin , valor) ;    // digitalWrite(i+2 , Digit[N][i] ) ;
  }
}

He aprovechado este ejemplo para insistir con los arrays, porque son muy útiles para resolver problemas que de otro modo se pueden complicar bastante.

Un problema que a priori, era muy pesado, o complejo, se transforma en una nimiedad recorriendo la tabla. He visto varios ejemplos por internet de este programa y la mayor parte de ellos me ha dado dolor de cabeza (Con algunas muy honrosas excepciones).

Aquí tienes el código completo
byte  Digit[10][8] =                // Arduino UNO va muy justo de memoria. Por eso lo
{                                   // definimos como byte y no como int
   { 1,1,1,1,1,1,0,0 },    // 0  
   { 0,0,0,0,1,1,0,0 },    // 1
   { 1,1,0,1,1,0,1,0 },    // 2
   { 1,0,0,1,1,1,1,0 },    // 3
   { 0,0,1,0,1,1,1,0 },    // 4
   { 1,0,1,1,0,1,1,0 },    // 5
   { 1,1,1,1,0,1,1,0 },    // 6
   { 0,0,0,1,1,1,0,0 },    // 7
   { 1,1,1,1,1,1,1,0 },    // 8
   { 1,0,1,1,1,1,1,0 }     // 9
};
void setup(){
  for (int i= 2; i<11; i++){
    pinMode(i, OUTPUT);
  }  
}
void loop(){
  for ( int k=0 ; k<10 ; k++){    // Llama a Display para k de 0 a 9, los digitos
    Display(k);
    delay(1000);
  }
}
void Display(int N){
  for (int i= 0 ; i<8 ; i++){
    int valor = Digit[N][i];
    int pin = i+2;
    digitalWrite(pin , valor) ;    // digitalWrite(i+2 , Digit[N][i] ) ;
  }
}
La cosa ha ido bastante bien con un digito, pero… ¿Y si queremos mostrar 4 dígitos? ¿Vamos a multiplicar 8 cables x 4 dígitos más tensión y GND = 34 pines?

En la próxima sesión veremos cómo manejar un display de 4 dígitos, porque para eso los venden hechos, y no es necesario volvernos locos enchufando no sé cuántos cables para hacer un reloj.

Como esta sesión ya es suficientemente densa, no incluiré el ejemplo de conectar un único digito a un shift register para gobernarlo, pero os recomiendo que lo hagáis como práctica, y si es preciso, colgamos el ejemplo en la página web.
 


No hay comentarios:

Publicar un comentario