Contador decimal con 74HC595 y 7 segmentos


Rompiendo un poco con la inercia de este blog de combinar dos de mis tecnologías favoritas hoy os traigo un proyecto de electrónica 100% programado con C/C++ que aunque es muy básico puede tener infinidad de utilidades. Crearemos un Contador decimal usando el 74HC595 y 7 segmentos


¿En qué consiste este proyecto?


Hoy os traigo un contador decimal usando el circuito integrado 74HC595 y un display de 7 segmentos controlado por dos pulsadores, uno de ellos que sumará una unidad al contador y otro que lo resta.


Lista de materiales:

  • Una tarjeta de Arduino
  • Un display de 7 segmentos en mi caso de cátodo común
  • 2 pulsadores
  • 7 resistencias de 330Ω
  • Un condensador de 470µF a 16 v
  • El integrado 74HC595
Imagen de los componentes usados en el proyecto del contador decimal con 74HC595 y 7 segmentos

Nota: El condensador puede tener una capacidad mayor a la recomendada en este blog lo que es importante es que el voltaje no sea menor de 16.

Nota2: Si solo dispones de un display de 7 segmentos de ánodo común puedes ver la solución pinchando aquí


Como podemos comprobar este proyecto está construido con materiales que podemos encontrar fácilmente en cualquier kit de Arduino para principiantes por lo que cualquier persona puede llevarlo a cabo sin problemas.

Esquema de conexionado

El esquema de conexionado es el siguiente:

Esquema electrónico del Contador decimal con 74HC595 y 7 segmentos


Nota 3: El conexionado de los leds no ha sido al azar como veremos más adelante en esta ocasión y para que sea menos lioso he conectado las patas de salida del integrado de manera que la salida Q0 está conectado con el ánodo del LED A de mi display de 7 segmentos, la salida Q1 con el ánodo del LED B del display y así sucesivamente.

¿Cómo funciona nuestro programa?


Primeramente tenemos una serie de declaraciones #define donde declaramos las salidas digitales del Arduino que vamos a usar con los mismos nombres que reciben las patas de entradas de datos del integrado 74HC595.

//Definimos los pines de control
#define SER 7
#define RCLK 8
#define SRCLK 9


A continuación nos encontramos otro bloque con #define donde vemos configuramos las combinaciones de los led que forman el número decimal en el display 7 segmentos siguiendo este esquema:

Configuración de leds del Contador decimal con 74HC595 y 7 segmentos
/*
  Creamos la combinación de leds que forman los números decimales en nuestro display
  ver documentación completa ya que puede variar en función de como hayas conectado 
  las salidas del integrado con los ánodos o cátodos del display.
*/

#define numero0 LED0 + LED1 + LED2 + LED3 + LED4 + LED5 
#define numero1 LED1 + LED2 
#define numero2 LED0 + LED1 + LED6 + LED4 + LED3
#define numero3 LED0 + LED1 + LED2 + LED3 + LED6
#define numero4 LED1 + LED2 + LED5 + LED6
#define numero5 LED0 + LED2 + LED3 + LED5 + LED6
#define numero6 LED0 + LED2 + LED3 + LED4 + LED5 + LED6
#define numero7 LED0 + LED1 + LED2
#define numero8 LED0 + LED1 + LED2 + LED3 + LED4 + LED5 + LED6
#define numero9 LED0 + LED1 + LED2 + LED3 + LED5 + LED6
#define error   LED0 + LED3 + LED4 + LED5 + LED6


Seguimos con otro bloque de declaraciones #define donde vamos a darle a cada LED un peso en bits que nos servirá de gran utilidad en el void loop de nuestro programado

//Definimos un valor de peso en bits a los led
#define LED0 1
#define LED1 2
#define LED2 4
#define LED3 8
#define LED4 16
#define LED5 32
#define LED6 64


Por último declaramos las variables que usaremos en nuestro programa.

//Inicializamos las variables necesarias
int i = 0;
const int botonSuma= 11;
const int botonResta= 12;


En el void setup simplemente inicializamos cada una de las entradas y salidas y configuramos una salida por defecto, en el que se nos muestre el número 0 justo al cargar nuestro programa.

void setup() {

//Definimos los pines de entrada y salida
pinMode(SER, OUTPUT);
pinMode(RCLK, OUTPUT);
pinMode(SRCLK, OUTPUT);
pinMode(botonSuma,INPUT);
pinMode(botonResta,INPUT);

//Inicializamos el valor del display a 0
digitalWrite(RCLK, LOW);
shiftOut(SER,SRCLK,MSBFIRST,numero0); //MSBFIRST= Bit más significante primero
digitalWrite(RCLK, HIGH);

}


Pasamos a la función definida escribirNumeros donde dependiendo del valor que se tenga la variable de control i se nos ejecutará una u otra parte del código que cargará los datos al integrado y los mostrará a través del display de 7 segmentos.

// Función que controla la salida del integrado
void escribirNumeros(int i){
  switch(i){
    case 0:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero0); 
      digitalWrite(RCLK, HIGH);
      break;
    case 1:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero1);
      digitalWrite(RCLK, HIGH);
      break;
    case 2:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero2);
      digitalWrite(RCLK, HIGH);
      break;
    case 3:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero3);
      digitalWrite(RCLK, HIGH);
      break;
    case 4:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero4);
      digitalWrite(RCLK, HIGH);
      break;
    case 5:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero5);
      digitalWrite(RCLK, HIGH);
      break;
    case 6:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero6);
      digitalWrite(RCLK, HIGH);
      break;
    case 7:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero7);
      digitalWrite(RCLK, HIGH);
      break;
    case 8:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero8);
      digitalWrite(RCLK, HIGH);
      break;
    case 9:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero9);
      digitalWrite(RCLK, HIGH);
      break;
  }
}


Por último pasamos al loop de este programa donde nos encontramos con la if, dependiendo de que pin digital se haya activado sumaremos o restaremos una unidad a nuestra variable de control i, si el valor de la variable de control es mayor que nueve o menor que cero el display mostrará una E indicando un error.

void loop() {
  // Bucle principal de control

  //Sumamos una unidad a la variable
  if (digitalRead(botonSuma) == HIGH && i<10  ){
    i++;
    escribirNumeros(i);
    delay(250);
  }

  //Restamos una unidad a la variable
  if(digitalRead(botonResta) == HIGH && i>-1){
    i--;
    escribirNumeros(i);
    delay(250);
  }

  //Mostramos el mensaje de error E
  if (i>9 || i<0) {
    digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,error); 
      digitalWrite(RCLK, HIGH);

  }

}

Observaciones y posibles mejoras del proyecto

  • Una de mis características favoritas de este programa es que una vez llegado a ese mensaje de error no importa cuantas veces más sigamos pulsando el mismo botón ya que obtendremos el mismo resultado, pero tan solo con cambiar de pulsador y accionarlo una sola vez volveremos al correcto funcionamiento del programa.
  • Como todo siempre puede perfeccionarse mucho más como por ejemplo creando una librería que evite todas las líneas de código de declaraciones #define así como que la librería tenga solución tanto para displays de ánodo y cátodo, te invito a que permanezcas atento a las siguientes entradas del blog donde abordaremos estas posibles mejoras.

Código completo


El código que escribiremos en nuestro IDE será el siguiente:

/*
  Contador decimal usando el integrado 74HC595 y un display de 7 segmentos

  Este programa nos permite mostrar el valor decimal de una variable en un
  display de 7 segmentos usando el integrado 74HC595 controlado por dos botones
  que suman o restan una unidad a la variable de control (i)

  Autor: Alexdevrep
  Fecha: 18/02/2024
  Más contenido interesante en :
    -GitHub: https://www.github.com/alexdevrep
    -Instagram: https://www.instagram.com/alexdevrep/
    -Mi blog de WordPress: https://www.eltallerdealexdevrep.com
    -Youtube: https://www.youtube.com/channel/UCNlqgVY-CaQ2Lgc5xJChaKA

*/

//Definimos los pines de control
#define SER 7
#define RCLK 8
#define SRCLK 9

//Definimos un valor de peso en bits a los led
#define LED0 1
#define LED1 2
#define LED2 4
#define LED3 8
#define LED4 16
#define LED5 32
#define LED6 64

/*
  Creamos la combinación de leds que forman los números decimales en nuestro display
  ver documentación completa ya que puede variar en función de como hayas conectado 
  las salidas del integrado con los ánodos o cátodos del display.
*/

#define numero0 LED0 + LED1 + LED2 + LED3 + LED4 + LED5 
#define numero1 LED1 + LED2 
#define numero2 LED0 + LED1 + LED6 + LED4 + LED3
#define numero3 LED0 + LED1 + LED2 + LED3 + LED6
#define numero4 LED1 + LED2 + LED5 + LED6
#define numero5 LED0 + LED2 + LED3 + LED5 + LED6
#define numero6 LED0 + LED2 + LED3 + LED4 + LED5 + LED6
#define numero7 LED0 + LED1 + LED2
#define numero8 LED0 + LED1 + LED2 + LED3 + LED4 + LED5 + LED6
#define numero9 LED0 + LED1 + LED2 + LED3 + LED5 + LED6
#define error   LED0 + LED3 + LED4 + LED5 + LED6

//Inicializamos las variables necesarias
int i = 0;
const int botonSuma= 11;
const int botonResta= 12;

void setup() {

//Definimos los pines de entrada y salida
pinMode(SER, OUTPUT);
pinMode(RCLK, OUTPUT);
pinMode(SRCLK, OUTPUT);
pinMode(botonSuma,INPUT);
pinMode(botonResta,INPUT);

//Inicializamos el valor del display a 0
digitalWrite(RCLK, LOW);
shiftOut(SER,SRCLK,MSBFIRST,numero0); //MSBFIRST= Bit más significante primero
digitalWrite(RCLK, HIGH);

}

// Función que controla la salida del integrado
void escribirNumeros(int i){
  switch(i){
    case 0:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero0); 
      digitalWrite(RCLK, HIGH);
      break;
    case 1:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero1);
      digitalWrite(RCLK, HIGH);
      break;
    case 2:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero2);
      digitalWrite(RCLK, HIGH);
      break;
    case 3:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero3);
      digitalWrite(RCLK, HIGH);
      break;
    case 4:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero4);
      digitalWrite(RCLK, HIGH);
      break;
    case 5:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero5);
      digitalWrite(RCLK, HIGH);
      break;
    case 6:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero6);
      digitalWrite(RCLK, HIGH);
      break;
    case 7:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero7);
      digitalWrite(RCLK, HIGH);
      break;
    case 8:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero8);
      digitalWrite(RCLK, HIGH);
      break;
    case 9:
      digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,numero9);
      digitalWrite(RCLK, HIGH);
      break;
  }
}

void loop() {
  // Bucle principal de control

  //Sumamos una unidad a la variable
  if (digitalRead(botonSuma) == HIGH && i<10  ){
    i++;
    escribirNumeros(i);
    delay(250);
  }

  //Restamos una unidad a la variable
  if(digitalRead(botonResta) == HIGH && i>-1){
    i--;
    escribirNumeros(i);
    delay(250);
  }

  //Mostramos el mensaje de error E
  if (i>9 || i<0) {
    digitalWrite(RCLK, LOW);
      shiftOut(SER,SRCLK,MSBFIRST,error); 
      digitalWrite(RCLK, HIGH);

  }

}

Vídeo de funcionamiento del Contador decimal con 74HC595 y 7 segmentos

Si todo ha ido bien el funcionamiento debe ser algo así:

Vídeo de funcionamiento del proyecto.


Y hasta aquí el proyecto de hoy ¿Qué os ha parecido? ¿Lo encuentras útil? Como siempre déjamelo saber en los comentarios así como si tienes alguna duda recuerda que en mi perfil de GitHub tienes toda la documentación de este proyecto listo para utilizar. Cualquier necesidad puedes dejarme un comentario estaré encantado de leeros.

Deja un comentario

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

Scroll al inicio