Learning Examples | Foundations | Hacking | Links
Carlyn Maw and Tom Igoe Nov, 06 Traducción Francisco Reinoso Jun, 10
En algun momento surge la necesidad de usar mas pines de salida que las que trae la propia Arduino y necesitas ampliarlas, esto se hace con un registro de desplazamiento. Este ejemplo está basado en el integrado 74HC595. En la hoja tecnica de datos se refieren a este integrado como un "registro de desplazamiento de 8 bits con entrada serie, salida serie o paralelo con latch (bloqueo); 3 estados.". En otras palabras, puedes usarlo para controlar 8 salidas simultaneas usando unos pocos pines del microcontrolador. Incluso se pueden enlazar varios integrados de manera que ampliamos el numero de salidas mucho mas. (Para encontrar integrados equivalentes en otros fabricantes hay que buscar "595" o "596" en sus números de referencia, hay muchos. El integrado STP16C596 por ejemplo posee 16 salidas y elimina la resistencias en serie.)
El modo de funcionamiento es algo llamado "comunicación serie sincrona", por ejemplo, tu puedes transmitir un byte enviando pulsos altos y bajos por un pin mientras en un segundo pin, el pin de reloj (clock) vas enviando pulsos constantes para diferenciar los bits enviados por el primer pin. Este modo de comunicación difiere con la "comunicación seri asincrona" de la función Serial.begin() en la que emisor y receptor fijan de forma independiente una velocidad de transferencia. Una vez que se ha transmitido el byte completo al registro los valores altos (HIGH) y bajos (LOW) de cada bit se asignan a los pines de salida. Esta es la "salida paralelo", teniendo los valores situados en los pines que deseamos.
La "salida serie" de este integrado se basa en un pin extra que retransmite la información serie recibida desde el microcontrolador sin cambios. Esto significa que podemos encadenar dos integrados 74HC595 y transmitir 16 bits (2 bytes) donde los primeros 8 bits "atraviesen" el primer integrado almacenandose en el segundo. Esto lo veremos en uno de los ejemplos.
"3 estados" se refiere al hecho de que podemos seleccionar los pines de salida como alto (HIGH), bajo (LOW) or "alta impedancia." Al contrario que HIGH y LOW no podemos seleccionar los pines para alta impedancia de forma individual. Solo podemos seleccionarlo para todos los pines a un tiempo, esto es algo tan especializado que no es mostrado en los ejemplos.
Aqui tenemos la definicion de los pines obtenida de Phillip's datasheet.
| PINS 1-7, 15 | Q0 " Q7 | Pins de salida |
| PIN 8 | GND | Ground, Vss | |
| PIN 9 | Q7" | Salida Serie | |
| PIN 10 | MR | Master Reset, activo = low | |
| PIN 11 | SH_CP | Pin Clock | |
| PIN 12 | ST_CP | Pin Latch | |
| PIN 13 | OE | Salida disponible, activo = low | |
| PIN 14 | DS | Entrada Serie | |
| PIN 16 | Vcc | Voltaje |
El primer paso es ampliar tu Arduino con un registro de desplazamiento
Haz las siguientes conexiones:
Esta configuración hace que todas las salidas estén activas y disponibles todo el tiempo. El inconveniente de esta configuracion es que los leds parpadearan en su ultimo estado o de forma aleatoria cada vez que encendemos el circuito y antes de que el programa arranque. Esto se puede corregir controlando los pines MR y OE desde la Arduino pero por el momento funciona y deja libres mas pines en la Arduino.

Desde ahora serán conocidos como dataPin (DS), clockPin (SH_CP) y latchPin (ST_CP) respectively. Aviso sobre el condensador de 0.1uF (100nF), si detecta parpadeos cuando activa el latchpin puede cambiar este valor hasta corregirlo.

En este caso conectamos el catodo (patilla corta) de cada led a masa (gnd), y el anodo (patilla larga) de cada led a su pin respectivo del integrado. Usando el registro de desplazamiento como suministrador de corriente para encender los led se denomina "fuente de corriente". Algunos registros de desplazamiento no pueden hacer esto y solo pueden funcionar como "sumidero de corriente" en cuyo caso tendrás que cambiar la dirección de los leds poniendo los anodos (patilla larga) directamente a 5V y los catodos (patilla corta) a las salidas del integrado. Puedes verificar esto en la hoja de datos específica de tu chip "595". NOTA: no olvides añadir una resistencia de 220 ohmios en serie con cada led para protegerlo de sobrecargas.


Aqui tenemos tres codigos de ejemplo. El primero es el tipico codigo "Hola Mundo" que simplemente muestra un byte con valor entre 0 y 255. El segundo programa enciende un led cada vez. El tercero efectua ciclos en un array.
COMPARAR DESCRIPCIÓN CON CODIGOS FUENTE, PARECE QUE HAN AÑADIDO PROGRAMAS SIN DOCUMENTAR CORRECTAMENTE
Este código está basado en la información de arriba, temporizaciones y tabla logica. La tabla logica nos muestra basicamente lo que nos interesa saber sobre lo que ocurre cuando usamos el integrado, como la forma en que los datos se almacenan en la memoria interna del registro de desplazamiento, la manera en que los datos pasan de la memoria a los pines al pasar el latchpin de LOW a HIGH haciendo que se enciendan los LEDS.
Code Sample 1.1 Hola mundo
Code Sample 1.2 Uno a Uno
Code Sample 1.3 Dos registros de desplazamiento
En este ejemplo añadiremos un segundo integrado, duplicando el número de pines de salida usando el mismo número de pines de la Arduino.
Comenzando desde el ejemplo anterior podemos añadir un segundo integrado en la protoboard. Usamos las mismas conexiones de tensión y masa.

Dos de esas conecciones simplemente alargan las lineas de reloj y latch desde la Arduino hasta el segundo integrado (cables amarillo y verde). El cable azul sale desde la salida serie del primer integrado (pin 9) hasta la entrada serie del segundo integrado (pin 14).

En este caso añadimos leds de color verde para diferenciar los bytes enviados a cada integrado con mas facilidad.


De nuevo tenemos tres códigos fuente. Si eres curioso intentarás por ti mismo extender el primer ejemplo para usar ambos integrados y ver lo que ocurre.
Codigo de ejemplo 2.1 Doble Contador Binario
Solo tenemos que añadir una linea de codigo al ejemplo 1 para enviar un segundo byte. Esto fuerza al primer registro de desplazamiento pasar el primer byte a traves de él hacia el segundo registro encendiendo los LEDs verdes. El segundo byte se muestra en los LEDs rojos.
Codigo de ejemplo 2.2 2 Bytes uno a uno
Comparando este codigo con el del ejemplo 1 veras que hay muy poca diferencia. La funcion blinkAll() ha sido cambiada por la funcion blinkAll_2Bytes() para incorporar los 16 bits. En la version 1 la activacion del latchpin estaba dentro de la subfuncion lightShiftPinA() y lightShiftPinB(), en este ejemplo lo hemos movido al bucle principal por la necesidad de ejecutar cada subfunción dos veces por linea una para los LEDs verdes y otra para los rojos.
Codigo de ejemplo 2.3 - Definicion de doble arrayl
Como en el ejemplo 2.2 este ejemplo 2.3 utiliza la nueva función blinkAll_2bytes(). La gran diferencia con respecto al ejemplo 1.3 es solo que en vez de existir una variable llamada "data" y un simple array llamado "dataArray" ahora tenemos definidos dataRED, dataGREEN, dataArrrayRED y dataArrayGREEN.
Esto siginfica que esta linea
data = dataArray[j];
se convierte en
dataRED = dataArrayRED[j];
dataGREEN = dataArrayGREEN[j];
por otro lado esta llamada
shiftOut(dataPin, clockPin, data);
pasa a formularse así.
shiftOut(dataPin, clockPin, dataGREEN);
shiftOut(dataPin, clockPin, dataRED);