Los contadores son ampliamente usados en muchos sistemas electrónicos, como por ejemplo en máquinas herramientas, procesos industriales, acceso a sistemas de transporte, bancos, páginas Web, programas de computador, algoritmos matemáticos, etc. De ahí su importancia de saber cómo funcionan en los microcontroladores. En este articulo aprenderemos a construir un contador de 2 dígitos con la tarjeta Arduino Uno.

 

En la Figura 1 podemos ver la tarjeta Arduino Uno y el la Figura 2 el IDE o Interface de Desarrollo para escribir programas en Arduino Uno, comúnmente llamados Sketch. Esta IDE puede ser descargada del sitio web de Arduino.

 

 


 

 

 


 

 

 

Para el desarrollo del contador de 2 dígitos, vamos a usar los pines: 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, A0, A1 y A2. El primer digito, es decir, el que representa las unidades, está conectado a los pines: 2, 3, 4, 5, 6, 7 y 8. El segundo digito, es decir, el que representa las decenas, está conectado a los pines: 9, 10, 11, 12, A0, A1 y A2. En los diagramas de este artículo, se muestran los pines A0, A1 y A2, conectados a los pines e1, f1 y g1 del display. Es necesario interconectar estos pines a sus respectivos pines en el display.

En la Figura 3 podemos observar las letras asignadas a cada segmento en el display.

 


 

 

Estas son: a, b, c, d, e, f y g. Los display usados para este articulos tienen 2 digitos y en la Figura 4 podemos ver los pines y sus conexiones a los respectivos segmentos.

 

 


 

 

Ya, la Figura 5 muestra los pines usados en la tarjeta Arduino Uno para controlar el display de 7 segmentos.

 

 


 

 

El orden de pines es el siguiente:

 

Pin 2 - Segmento a2

Pin 3 - Segmento b2

Pin 4 - Segmento c2

Pin 5 - Segmento d2

Pin 6 - Segmento e2

Pin 7 - Segmento f2

Pin 8 - Segmento g2

 

Pin 9 - Segmento a1

Pin 10 - Segmento b1

Pin 11 - Segmento c1

Pin 12 - Segmento d1

Pin A0 - Segmento e1

Pin A1 - Segmento f1

Pin A2 - Segmento g1

 

 

 

CONTADOR INCREMENTAL POR PROGRAMA.

En este sketch implementamos un contador incremental por programa. El contador comienza en cero y se va incrementando hasta 99, luego se detiene por 10 segundos, volviendo a incrementarse hasta llegar a 99. Asi, se repite el mismo bucle infinitamente. La Figura 6 muestra el circuito electronico para implementar este contador.

 


 

 

 

El código para el contador incremental es el siguiente:

const int display_1_Pinout[7] = { 2, 3, 4, 5, 6, 7, 8 };

const int display_2_Pinout[7] = { 9, 10, 11, 12, A0, A1, A2 };

const byte anodeDisplay[10] =

{

0b1000000, //0

0b1111001, //1

0b0100100, //2

0b0110000, //3

0b0011001, //4

0b0010010, //5

0b0000010, //6

0b1111000, //7

0b0000000, //8

0b0010000, //9

};

 

***************************************************************
**************************************************************/
void setup()

{

for(int i = 0; i < 7; i++)

{

pinMode(display_1_Pinout[i], OUTPUT);

pinMode(display_2_Pinout[i], OUTPUT);

}

}

 

***************************************************************
**************************************************************/
void Display_2_Write(int number)

{

 

byte numberBit = anodeDisplay[number];

 

for (int i = 0; i < 7; i++)

{

int bit = bitRead(numberBit, i);

digitalWrite(display_2_Pinout[i], bit);

}

}

 

***************************************************************
**************************************************************/
void Display_1_Write(int number)

{

 

byte numberBit = anodeDisplay[number];

 

for (int i = 0; i < 7; i++)

{

int bit = bitRead(numberBit, i);

digitalWrite(display_1_Pinout[i], bit);

}

}

 

***************************************************************
**************************************************************/
void Display_Show(int number)

{

int units = number % 10;

int tens = number / 10;

 

Display_1_Write(units);

Display_2_Write(tens);

}

 

***************************************************************
**************************************************************/
void loop()

{

for(int cnt=0; cnt<100; cnt++)

{

Display_Show(cnt);

delay(1000);

}

 

delay(10000);

}

 

El incremento se hace por programa usando un bucle for(). La siguiente línea de código se encarga de ejecutar este bucle:

 

for(int cnt=0; cnt<100; cnt++)

 

La variable entera cnt, se inicializa con cero y por cada paso que la instrucción for() ejecute, se verifica si la variable cnt es menor que 100. Si es menor, el bucle for() se ejecuta, incrementado la variable cnt. Si es mayor o igual 100, se sale del bucle for() y se ejecuta la instrucción: delay(10000), la cual retarda el programa por 10 segundos.

La función Display_Show(), recibe un parámetro entero y se encarga de extraer las unidades (units) y las decenas (tens). Luego llamamos las funciones: Display_1_Write(units); y Display_2_Write(tens); para mostrar estos valores en el display de 7 segmentos.

 

CONTADOR DECREMENTAL POR PROGRAMA.

En este sketch implementamos un contador decremental por programa. El contador comienza en 99 y se va decrementando hasta cero, luego se detiene por 10 segundos, volviendo a decrementarse hasta llegar a cero. Así, se repite el mismo bucle infinitamente. La Figura 6 muestra el circuito electrónico para implementar este contador. El código para el contador decremental es el siguiente:

const int display_1_Pinout[7] = { 2, 3, 4, 5, 6, 7, 8 };

const int display_2_Pinout[7] = { 9, 10, 11, 12, A0, A1, A2 };

 

const byte anodeDisplay[10] =

{

0b1000000, //0

0b1111001, //1

0b0100100, //2

0b0110000, //3

0b0011001, //4

0b0010010, //5

0b0000010, //6

0b1111000, //7

0b0000000, //8

0b0010000, //9

};

 

***************************************************************
**************************************************************/
 

void setup()

{

for(int i = 0; i < 7; i++)

{

pinMode(display_1_Pinout[i], OUTPUT);

pinMode(display_2_Pinout[i], OUTPUT);

}

}

 

***************************************************************
**************************************************************/
void Display_2_Write(int number)

{

 

byte numberBit = anodeDisplay[number];

 

for (int i = 0; i < 7; i++)

{

int bit = bitRead(numberBit, i);

digitalWrite(display_2_Pinout[i], bit);

}

}

 

***************************************************************
**************************************************************/
void Display_1_Write(int number)

{

 

byte numberBit = anodeDisplay[number];

 

for (int i = 0; i < 7; i++)

{

int bit = bitRead(numberBit, i);

digitalWrite(display_1_Pinout[i], bit);

}

}

 

***************************************************************
**************************************************************/
void Display_Show(int number)

{

int units = number % 10;

int tens = number / 10;

 

Display_1_Write(units);

Display_2_Write(tens);

}

 

***************************************************************
**************************************************************/
void loop()

{

for(int cnt=99; cnt >= 0; cnt--)

{

Display_Show(cnt);

delay(1000);

}

 

delay(10000);

}

 

 

 

Básicamente el código de este sketch es igual al del ejemplo anterior. La función que se encarga del decremento es:

 

for(int cnt=99; cnt >= 0; cnt--)

 

Este bucle for(), inicializa la variable cnt en 99 y verifica si esta es mayor o igual a cero. Si así, entonces entra en el bucle, decrementando la variable cnt. Caso se menor de cero, el bucle for() sale y es temporizado el programa por 10 segundos. Las demás funciones, trabajan igual que las del ejemplo anterior.

 

CONTADOR INCREMENTAL DECREMENTAL POR PROGRAMA.

En este sketch implementamos un contador incremental decremental por programa. Este sketch es la combinación de los dos anteriores ejemplos. Se configura la entrada digital A3 para seleccionar incrementar o decrementar el contador. Esta selección tiene su efecto cuando el bucle for() salga del loop.

 

 


 

 

 

La Figura 7 muestra el circuito electrónico para testar este ejemplo. El código es el siguiente:

 

int incDecPinin = A3;

 

const int display_1_Pinout[7] = { 2, 3, 4, 5, 6, 7, 8 };

const int display_2_Pinout[7] = { 9, 10, 11, 12, A0, A1, A2 };

 

const byte anodeDisplay[10] =

{

0b1000000, //0

0b1111001, //1

0b0100100, //2

0b0110000, //3

0b0011001, //4

0b0010010, //5

0b0000010, //6

0b1111000, //7

0b0000000, //8

0b0010000, //9

};

 

***************************************************************
**************************************************************/
void setup()

{

pinMode(incDecPinin, INPUT_PULLUP);

 

for(int i = 0; i < 7; i++)

{

pinMode(display_1_Pinout[i], OUTPUT);

pinMode(display_2_Pinout[i], OUTPUT);

}

}

 

***************************************************************
**************************************************************/
void Display_2_Write(int number)

{

 

byte numberBit = anodeDisplay[number];

 

for (int i = 0; i < 7; i++)

{

int bit = bitRead(numberBit, i);

digitalWrite(display_2_Pinout[i], bit);

}

}

 

***************************************************************
**************************************************************/
void Display_1_Write(int number)

{

 

byte numberBit = anodeDisplay[number];

 

for (int i = 0; i < 7; i++)

{

int bit = bitRead(numberBit, i);

digitalWrite(display_1_Pinout[i], bit);

}

}

 

***************************************************************
**************************************************************/
void Display_Show(int number)

{

int units = number % 10;

int tens = number / 10;

 

Display_1_Write(units);

Display_2_Write(tens);

}

 

***************************************************************
**************************************************************/
void loop()

{

 

if ( digitalRead(incDecPinin) == HIGH )

{

for(int cnt=0; cnt<100; cnt++)

{

Display_Show(cnt);

delay(1000);

}

}

else

{

for(int cnt=99; cnt >= 0; cnt--)

{

Display_Show(cnt);

delay(1000);

}

}

 

delay(10000);

}

 

 

CONTADOR INCREMENTAL POR PULSO.

En este sketch implementamos un contador incremental por pulso. El circuito para testar este ejemplo puede ser observado en la Figura 8.

 


| Haga click en la imagen para ampliar |

 

 

Para generar los pulsos del contador, usamos un interruptor o pulsador. La mayor parte de los pines de la tarjeta Arduino Uno, tienen una resistencia interna conectada a positivo y que puede ser habilitada usando el parámetro INPUT_PULLUP, cuando se configure el pin como entrada. En lo que respecta al programa del contador, la Figura 9, muestra una máquina de estados usada para este ejemplo y que explicaremos más adelante.

 

 


 

 

 

El código para este ejemplo es el siguiente:

 

enum States

{

High,

Low

};

 

enum Events

{

EV_HIGH,

EV_LOW,

};

 

 

int buttonPinin = A3;

int buttonValue = 0;

int counter = 0;

int state = High;

 

 

const int display_1_Pinout[7] = { 2, 3, 4, 5, 6, 7, 8 };

const int display_2_Pinout[7] = { 9, 10, 11, 12, A0, A1, A2 };

 

const byte anodeDisplay[10] =

{

0b1000000, //0

0b1111001, //1

0b0100100, //2

0b0110000, //3

0b0011001, //4

0b0010010, //5

0b0000010, //6

0b1111000, //7

0b0000000, //8

0b0010000, //9

};

 

***************************************************************
**************************************************************/
void setup()

{

pinMode(buttonPinin, INPUT_PULLUP);

 

for(int i = 0; i < 7; i++)

{

pinMode(display_1_Pinout[i], OUTPUT);

pinMode(display_2_Pinout[i], OUTPUT);

}

 

Display_Show(counter);

}

 

***************************************************************
**************************************************************/
void Display_2_Write(int number)

{

 

byte numberBit = anodeDisplay[number];

 

for (int i = 0; i < 7; i++)

{

int bit = bitRead(numberBit, i);

digitalWrite(display_2_Pinout[i], bit);

}

}

 

***************************************************************
**************************************************************/
void Display_1_Write(int number)

{

byte numberBit = anodeDisplay[number];

 

for (int i = 0; i < 7; i++)

{

int bit = bitRead(numberBit, i);

digitalWrite(display_1_Pinout[i], bit);

}

}

 

***************************************************************
**************************************************************/
void Display_Show(int number)

{

int units = number % 10;

int tens = number / 10;

 

Display_1_Write(units);

Display_2_Write(tens);

}

 

***************************************************************
**************************************************************/
void StateMachine(Events e)

{

switch (state)

{

case High:

switch (e)

{

case EV_LOW:

counter++;

if(counter>=100)

counter=0;

Display_Show(counter);

state = Low;

}

break;

 

case Low:

switch (e)

{

case EV_HIGH:

state = High;

}

break;

 

}

}

 

***************************************************************
**************************************************************/
void loop()

{

buttonValue = digitalRead(buttonPinin);

 

if (buttonValue == HIGH)

{

StateMachine(EV_HIGH);

}

else

{

StateMachine(EV_LOW);

}

}

 

 

Las máquinas de estado son códigos basados en instrucciones de decisión (switch), la cual determina en qué estado se encuentra un programa y así ejecutar algún respectivo código. Para este ejemplo tenemos los estados High y Low, los cuales determinan el estado del pulsador. Si el programa se encuentra en estado High, y es presionado el pulsador, el programa, envía el evento EV_LOW, a este estado y es llamado un código para incrementar el contador y mostrarlo en display.

Note, que el contador es verificado para ver si ya llego a 100, y de este modo resetearlo a cero (0). Luego llamamos la función: Display_Show(counter); para escribir el valor del contador en los displays. También, es cambiado el estado del pulsador para Low. Esta técnica es usada para incrementar el contador, solamente cuando el pulsador pase de alto para bajo, es decir cuando sea presionado por el usuario. Note que es colocado un capacitor de 0.22 microfaradios, para evitar los ruidos producidos por los pulsadores o interruptores, pues estos al ser mecánicos, envían muchos pulsos al circuito, cuando son presionados.

La función loop(), se encarga de leer el pulsador y llamar la función: StateMachine(Events e), enviando como parámetro el evento apropiado.

 

 

CONTADOR INCREMENTAL CON SETPOINT.

En este sketch implementamos un contador incremental por pulso con setpoint. Cuando se llegue al valor programado en el setpoint, se encenderá un LED. El circuito para testar este programa puede ser visto en la Figura 10. El siguiente es el código ejemplo:

 


 

 

enum States

{

High,

Low

};

 

enum Events

{

EV_HIGH,

EV_LOW,

};

 

const int SETPOINT = 37;

const int buttonPinin = A3;

const int ledPinout = A4;

 

int buttonValue = 0;

int counter = 0;

int state = High;

 

 

const int display_1_Pinout[7] = { 2, 3, 4, 5, 6, 7, 8 };

const int display_2_Pinout[7] = { 9, 10, 11, 12, A0, A1, A2 };

 

const byte anodeDisplay[10] =

{

0b1000000, //0

0b1111001, //1

0b0100100, //2

0b0110000, //3

0b0011001, //4

0b0010010, //5

0b0000010, //6

0b1111000, //7

0b0000000, //8

0b0010000, //9

};

 

***************************************************************
**************************************************************/
void setup()

{

pinMode(ledPinout, OUTPUT);

Led_Off();

pinMode(buttonPinin, INPUT_PULLUP);

 

for(int i = 0; i < 7; i++)

{

pinMode(display_1_Pinout[i], OUTPUT);

pinMode(display_2_Pinout[i], OUTPUT);

}

 

Display_Show(counter);

 

}

 

***************************************************************
**************************************************************/
void Led_On()

{

digitalWrite(ledPinout, LOW);

}

 

***************************************************************
**************************************************************/
void Led_Off()

{

digitalWrite(ledPinout, HIGH);

}

 

***************************************************************
**************************************************************/
void Display_2_Write(int number)

{

 

byte numberBit = anodeDisplay[number];

 

for (int i = 0; i < 7; i++)

{

int bit = bitRead(numberBit, i);

digitalWrite(display_2_Pinout[i], bit);

}

}

 

***************************************************************
**************************************************************/
void Display_1_Write(int number)

{

byte numberBit = anodeDisplay[number];

 

for (int i = 0; i < 7; i++)

{

int bit = bitRead(numberBit, i);

digitalWrite(display_1_Pinout[i], bit);

}

}

 

***************************************************************
**************************************************************/
void Display_Show(int number)

{

int units = number % 10;

int tens = number / 10;

 

Display_1_Write(units);

Display_2_Write(tens);

}

 

***************************************************************
**************************************************************/
void StateMachine(Events e)

{

switch (state)

{

case High:

switch (e)

{

case EV_LOW:

counter++;

 

if(counter == SETPOINT)

{

Led_On();

}

else if(counter > SETPOINT)

{

counter=1;

Led_Off();

}

else

{

Led_Off();

}

 

Display_Show(counter);

state = Low;

}

break;

 

case Low:

switch (e)

{

case EV_HIGH:

state = High;

}

break;

 

}

}

 

***************************************************************
**************************************************************/
void loop()

{

buttonValue = digitalRead(buttonPinin);

 

if (buttonValue == HIGH)

{

StateMachine(EV_HIGH);

}

else

{

StateMachine(EV_LOW);

}

}

 

 

 En este programa usamos la misma técnica del programa contador visto anteriormente en este artículo. Mas se ha agregado un constante entera definida en la siguiente línea de código:

 

const int SETPOINT = 37;

 

Este valor define el setpoint del contador. El valor se puede alterar para ajustarlo a la necesidad, pero debe estar en el rango de 1 hasta 99, para poder ser visualizado en el display. También, se definió un pin de salida para conectar un LED. La siguiente línea de código hace esto:

 

const int ledPinout = A4;

 

 

CONCLUCIÓN.

El manejo de display de 7 segmentos es relativamente fácil y sus aplicaciones son casi ilimitadas. Este código está dirigido a dos dígitos. Los contadores son la base para construir, temporizadores digitales, frecuencímetros digitales, velocímetros, tacómetros, etc.

Nota: No olvidar conectar el capacitor de 0.22 uF al pin de entrada A3, pues esto evitara el ruido producido por los rebotes mecánicos de los pulsadores.

 

 

Buscador de Datasheets



N° de Componente