Muchas veces corremos con el problema de no contar con suficientes salidas o entradas digitales en nuestros proyectos y recurrimos a utilizar otros microcontroladores de apoyo en una configuración maestro-esclavo. La verdad es que manejar más de 13 Leds (sin PWM) debería sonar como algo fácil, y en realidad lo es.
Los registros de desplazamiento (shifter registers) permiten expandir nuestra capacidad de entradas y de salidas digitales, basándose en el desplazamiento de una secuencia de bytes que se envía o recibe desde estos circuitos integrados.
Las dos variantes más populares de registros de desplazamiento son los de entrada en serie y los de entrada en paralelo. Ambos tipos de circuitos pueden tener salidas en serie o salidas en paralelo. En el mundo de los microcontroladores, se utiliza la primera para expandir la capacidad de salidas digitales y el segundo, para las entradas.
Otra ventaja que poseen este tipo de integrados es que solo requieres tres (3) pines digitales para las entradas y cuatro (4) para las salidas;con la condición de que puedes conectar una N cantidad de registros de desplazamiento en cadena.
1. Registros de desplazamiento de entrada en serie (SISO / SIPO)
Como se menciono anteriormente, se utilizarán para expandir nuestra capacidad de salidas digitales. En nuestro código, un uno (1) representará cuando un pin se desea que este en alta (HIGH) y un cero (0) cuando se desee que este en baja (LOW).
Para mostrar el funcionamiento de este tipo de circuitos, desarrollaremos un ejemplo en el cual controlaremos el estado lógico de 8 LEDs con sólo 3 pines digitales del Arduino. Utilizaremos el circuito integrado 74HC595N.
Conectaremos el circuito integrado al Arduino, acorde al siguiente diagrama:
Abriremos el IDE de Arduino y copiamos el siguiente código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
int ds = 2; //data int shcp = 3; // clock int stcp = 4; //latch int data = 0; //importante. Variables de el shift register boolean pinState[] = {0,0,0,0,0,0,0,0}; //Matriz que contiene los valores actuales void setup() { pinMode(ds, OUTPUT); //Establecer los pines a utilizar pinMode(shcp, OUTPUT); pinMode(stcp, OUTPUT); Serial.begin(9600); //Iniciar el monitor serie for(int x=0;x<8;x++) { digital_Write(x,LOW); //Apagar todos los pines } } void loop() { if(Serial.available()>0) { String y= Serial.readString(); //Leer un valor entre 0 y 7 int x = y.toInt(); //Se transforma el dato recibido en un entero if(x>=0 && x<8) { pinState[x]=!pinState[x]; //Matriz con nuestros valores digital_Write(x,pinState[x]); //Analogo a digitalWrite Serial.print("Pin: "); Serial.print(x); // Variable que contiene el pin Serial.print(", Estado: "); Serial.println((pinState[x]==1 ? "ENCENDIDO" : "APAGADO")); } } } void digital_Write(int myPin, boolean myState) //Funcion principal //Analogo a digitalWrite(), para el shift register. //myState = HIGH o LOW { bitWrite(data,myPin,myState); //Transformar nuestros datos shiftOut(ds, shcp, MSBFIRST, data); //Enviar al integrado digitalWrite(stcp, HIGH); // Procedimiento según el datasheet digitalWrite(stcp, LOW); // } |
El código anterior espera un valor entre cero (0) y siete (7) en el monitor serial. Cuando el usuario le introduce este valor, el cambia el estado de ese LED (sí esta encendido lo apaga, y viceversa). Además, deja un registro del estado en el monitor serial.
Si enumeramos los LEDs del 0 al 7, podremos cambiar el estado lógico de los LEDs a través de una llamada al número de posición del LED. Si en el Monitor Serie enviamos un «0», el primer LED de izquierda a derecha encenderá. Si enviamos nuevamente un «0», entonces el LED se apagarrá. Y así funcionará para todas y cada una de las posiciones.
2. Registros de desplazamiento de entrada en paralelo (PISO,PIPO)
Son utilizados para expandir la capacidad de entradas digitales. Detecta cuando un pin esta en ALTA ( su voltaje > 2.5V ) o cuando algún pin esta en baja (LOW). Para el funcionamiento correcto, utilizaremos cuatro pines digitales de la placa Arduino, además del circuito integrado 74HC165N.
Y lo conectaremos de acorde al siguiente circuito:
En este ejemplo lo que haremos será leer 8 botones con tan sólo 4 pines del Arduino. Abriremos el IDE de Arduino y copiamos el siguiente código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
int q7 = 6; //data int pl = 8; //Parallel load int cp = 7; //Clock int ce = 5; // Clock_enable void setup() { Serial.begin(9600); //Iniciar el monitor serial pinMode(pl, OUTPUT); //Establecer pines de entrada y salida pinMode(cp, OUTPUT); pinMode(q7, INPUT); pinMode(ce, OUTPUT); digitalWrite(cp, HIGH); //Estados iniciales segun el datasheet digitalWrite(pl, HIGH); } void loop() { digital_read(); //Leer e imprimir delay(1000); //Pequeño delay } void digital_read() { digitalWrite(pl, LOW); //Cargar los datos de los pines al 165N delayMicroseconds(5); // delay segun el datasheet digitalWrite(pl, HIGH); //Funcionamiento normal delayMicroseconds(5); //Delay segun el datasheet digitalWrite(cp, HIGH); //Enviar señal de lectura del arduino > 165N digitalWrite(ce, LOW); // Habilitar el reloj del 165N byte lectura = shiftIn(q7, cp, MSBFIRST); //Leer los bytes (estado de los pines) digitalWrite(ce, HIGH); // Deshabilitar el reloj del 165N Serial.print("Estado Actual: "); //Imprimir datos Serial.print(lectura); Serial.println(); //Nueva línea } |
El código anterior muestra los estados de los botones en terminos de uno (1) y cero(0) en el monitor serie.
Con esto nos damos cuenta que podemos obtener los estados lógicos de los 8 botones a través de una cadena de bits.
Este tipo de circuitos, junto con las técnicas presentadas en este artículo permitirá aumentar la capacidad de un Arduino común y corriente cuando sea necesario utilizar múltiples entradas y/o múltiples salidas.
Cualquier duda o sugerencia, por favor expresarla en la sección de comentarios. Espero que la información mostrada sea de utilidad. Saludos.
Hola el circuito y codigo para el 74hc165 no funciona ! podrian corregirlo
Por qué no funciona?