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
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:
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:
/*
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í:
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.