En este tutorial vamos a ver cómo generar diferentes codificaciones con un DIP switch que Arduino pueda interpretar y actuar en consecuencia.
Para ello utilizaremos 7 leds y un DIP swtich de 3 posiciones. Codificaremos 7 combinaciones deferentes que encenderán los correspondientes leds.
Puedes consultar la codificación en la siguiente tabla:
Led encendido | Codificación |
Ninguno | 000 |
1 | 001 |
2 | 010 |
3 | 011 |
4 | 100 |
5 | 101 |
6 | 110 |
7 | 111 |
En el siguiente vídeo puedes ver una demostración de lo que vamos a implementar:
Materiales
Estos son todos los materiales que necesitamos para codificar con un DIP switch y Arduino:
Una placa Arduino (Yo usaré Arduino UNO) | ||
Un DIP switch de 3 posiciones | ||
3 resistencias de 10KΩ | ||
7 leds de 5 mm | ||
7 resistencias de 330Ω | ||
Cables | ||
Una protoboard | ||
Un ordenador con el IDE de Arduino instalado |
Conexiones
El circuito que vamos a implementar es el siguiente:
He enumerado los leds para que quede más claro cuál debemos encender cuando hagamos la codificación del DIP switch.
Los ánodos de los leds los he conectado a los pines digitales de Arduino de la siguiente forma:
Led | Pin digital |
1 | 5 |
2 | 6 |
3 | 7 |
4 | 8 |
5 | 9 |
6 | 10 |
7 | 11 |
Cada uno de los cátodos lleva una resistencia de 330Ω y esta a su vez va conectada a GND.
Si no sabes cómo conectar un led con Arduino mira este artículo donde lo explico en detalle.
En cuanto al DIP switch, he conectado sus interruptores (están etiquetados en el propio DIP) a los pines digitales de Arduino así:
Interruptor | Pin digital |
1 | 4 |
2 | 3 |
3 | 2 |
Estos pines llevan una resistencia de 10KΩ cada uno que a su vez va conectada a GND.
Los pines opuestos del DIP switch, es decir los que están en el lado de la etiqueta ON van conectados a 5V.
Si tienes dudas mira este artículo en el que explico cómo conectar un DIP switch con Arduino.
Sketch
El sketch completo para la codificación del DIP switch es el siguiente:
//DECLARACIONES
const int DIP[3]={2, 3, 4};
const int LEDS[7]={5,6,7,8,9,10,11};
int anterior = 0;
//CONFIGURACIÓN
void setup() {
for(int i=0; i<3; i++){
pinMode(DIP[i], INPUT);
}
for(int i=0; i<7; i++){
pinMode(LEDS[i], OUTPUT);
}
}
//FUNCIONES
int toDecimal(int estado[3]){
return (estado[0]*4 + estado[1]*2 + estado[2]);
}
//FUNCIÓN LOOP
void loop() {
int estado[3]={LOW, LOW, LOW};
for(int i=0; i<3; i++){
estado[i]=digitalRead(DIP[i]);
}
int decimal = toDecimal(estado);
digitalWrite(LEDS[anterior], LOW);
if(decimal>0){
decimal--;
digitalWrite(LEDS[decimal], HIGH);
}
anterior = decimal;
}
Declaraciones
Vamos a declarar un array de constantes enteras para almacenar los pines digitales en los que hemos conectado el DIP swich. En mi caso son los pines 2, 3 y 4:
const int DIP[3] = {2, 3, 4};
La relación entre los interruptores del DIP switch, los pines digitales y las posiciones del array queda así:
Nº interruptor | Pin digital | Posición array DIP |
1 | 2 | 0 |
2 | 3 | 1 |
3 | 4 | 2 |
Esta relación es importante. La tendremos más adelante en cuenta.
También necesitamos otro array similar para los pines digitales en los que hemos conectado los leds. En mi caso son los pines 5, 6, 7, 8, 9, 10 y 11.
const int LEDS[7] = {5, 6, 7, 8, 9, 10, 11};
De nuevo te dejo la relación entre los leds, los pines digitales y la posición dentro del array LEDS. Más adelante la necesitaremos:
Nº led | Pin digital | Posición array LEDS |
1 | 5 | 0 |
2 | 6 | 1 |
3 | 7 | 2 |
4 | 8 | 3 |
5 | 9 | 4 |
6 | 10 | 5 |
7 | 11 | 6 |
Lo último que necesitamos declarar es una variable de tipo entero inicializada a 0. Yo la he llamado anterior:
int anterior = 0;
Esta variable nos servirá para saber cuál fue el último led encendido y así poder apagarlo antes de iluminar el siguiente. En el caso en que la codificación es 000 todos los leds estarán apagados, por lo que el valor de esta variable será 0.
Configuración
Dentro de la función setup() configuraremos los pines del DIP switch como entrada:
for(int i=0; i<3; i++){
pinMode(DIP[i], INPUT);
}
Con la ayuda de un bucle for recorremos el array DIP y utilizando la función pinMode() configuramos cada pin (i) como entrada con INPUT. Recuerda la relación entre los pines digitales y las posiciones del array, la posición 0 es el pin 2, la 1 es el pin 3 y la 2 es el pin 4.
En el caso de los leds también haremos la configuración con un bucle for puesto que los pines están guardados en un array:
for(int i=0; i<7; i++){
pinMode(LEDS[i], OUTPUT);
}
En este caso los pines son salida (OUTPUT) puesto que hay leds conectados.
Funciones
Vamos a definir una función que nos será de ayuda para convertir a decimal la codificación del DIP switch que tendrá un formato binario.
int toDecimal(int estado[3]){
return (estado[0]*4 + estado[1]*2 + estado[2]);
}
La función recibe estado como parámetro, que es un array de 3 enteros. Este array contendrá la codificación del DIP switch.
Por ejemplo, si los interruptores están en esta posición la codificación será 100:
Cada dígito de la codificación se almacena en una posición del array estado. En la posición 0 el 1 y en las posiciones 1 y 2 los 0s.
Para convertir este valor a decimal tenemos que hacer potencias de 2:
1 * 22 + 0 * 21 + 0 * 20
Si calculas las potencias tendrás esto otro que se parece más a lo que está escrito en el código:
1 * 4 + 0 * 1 + 0
El resultado de este ejemplo es 4 (en binario 100) y ese es el valor que devolverá la función toDecimal().
Prueba con otro valor binario de 3 dígitos y verás que la conversión a decimal es correcta.
Recuerda, si ponemos todos los interruptores del DIP switch en posición OFF el resultado devuelto por toDecimal() será 0 puesto que la codificación es 000:
Función loop
Hemos llegado a la función loop de nuestro sketch. Aquí es donde realizaremos la lectura del DIP switch en binario, lo convertiremos a decimal y encenderemos el led correspondiente apagando previamente el que estuviese encendido.
void loop() {
int estado[3]={LOW, LOW, LOW};
for(int i=0; i<3; i++){
estado[i]=digitalRead(DIP[i]);
}
int decimal = toDecimal(estado);
digitalWrite(LEDS[anterior], LOW);
if(decimal>0){
decimal--;
digitalWrite(LEDS[decimal], HIGH);
}
anterior = decimal;
}
Lectura de la codificación del DIP switch
Primero vamos a declarar un array llamado estado de tipo entero e inicializado con 3 valores LOW (0):
int estado[3]={LOW, LOW, LOW};
Ahora vamos a leer los valores de los pines digitales en los que está conectado el DIP y los vamos a almacenar en el array estado:
for(int i=0; i<3; i++){
estado[i]=digitalRead(DIP[i]);
}
Recuerda que habíamos almacenado los pines digitales del DIP switch en el array DIP. Por eso necesitamos un bucle for.
Recorremos el array y por cada valor que toma la variable i hacemos una lectura del pin que se encuentra en dicha posición del array: digitalRead(DIP[i]).
El valor devuelto por digitalRead() lo almacenamos en la posición i del array estado: estado[i].
Cuando el bucle for termine, el array estado tendrá los valores de los interruptores del DIP switch. Se habrá almacenado un 0 cuando el interruptor esté en posición OFF y un 1 cuando esté en posición ON. Tendremos una codificación binaria.
Es el momento de convertir el valor binario a decimal llamando a nuestra función toDecimal():
int decimal = toDecimal(estado);
El resultado quedará almacenado en la variable decimal. Este valor es el número del led correspondiente a la codificación, por tanto lo tendremos que encender.
Apagar el led anterior
Pero antes, debemos apagar el led anterior:
digitalWrite(LEDS[anterior], LOW);
Si recuerdas, habíamos declarado una variable entera llamada anterior y la habíamos inicializado a 0.
La primera vez que se ejecute la función loop no habrá led anterior, pero al haber inicializado la variable con valor 0 la instrucción digitalWrite(LEDS[anterior], LOW) apagará el led que está en la primera posición del array LEDS. Como estarán todos inicialmente apagados no producirá ningún efecto.
Cuando la función loop haga más repeticiones se producirán otras lecturas del DIP switch y entonces esta variable tendrá otros valores. Veremos un poco más abajo cuándo tendremos que modificarla.
Encender el led
Ha llegado el momento de encender el led apropiado según la codificación:
if(decimal>0){
decimal--;
digitalWrite(LEDS[decimal], HIGH);
}
Primero tenemos que hacer una comprobación. Recuerda que toDecimal() nos devuelve 0 si la codificación es 000 (todos apagados). En ese caso no encenderíamos ningún led. Por eso utilizamos una instrucción if en la que comprobamos si el valor de la variable decimal es mayor a 0 (decimal>0). Si la comprobación es cierta entonces encendemos el led.
Fíjate que decrementamos una unidad a la variable decimal (decimal–). ¿Por qué? Pues porque la variable tiene el número del led, no la posición del array LEDS en el que está el pin digital correspondiente.
Como vimos en la tabla de los leds del apartado declaraciones, el número del led es 1 más que la posición que ocupa en el array LEDS, por eso restamos 1. De esta forma la variable decimal nos sirve de indice.
Con el índice correcto calculado podemos encender el led utilizando la instrucción digitalWrite(LEDS[decimal], HIGH).
Guardar el led anterior
Y ya solo nos queda un último detalle. ¿Recuerdas la variable anterior? Pues es el momento de cambiarla:
anterior = decimal;
Le asignamos el valor de la variable decimal porque es la que contiene la posición del array en la que está el último led encendido. Así lo podremos apagar en la siguiente iteración de la función loop.
Si la codificación actual es 000 entonces le estaremos asignando a la variable anterior el valor 0. Y ya vimos cómo funcionaría en este caso.
¡Hemos terminado! Carga ahora el sketch en tu Arduino y haz diferentes combinaciones con los interruptores del DIP switch, a ver qué pasa.
¡Suscríbete a la newsletter y no te pierdas nada!
Te avisaré cuando publique nuevo contenido en paraarduino.com y en mi canal de YouTube (@ParaArduino).