16 dic. 2012

Aumentando el número de salidas digitales en Arduino

En la reciente entrada "primeros experimentos con Arduino" hice un montaje que utilizaba un display 7 segmentos de 4 dígitos para mostrar datos numéricos. En ese momento tuve que utilizar una salida digital para cada uno de los siete segmentos del display y dos salidas más para controlar el dígito en el que se iba a mostrar el dato numérico. Evidentemente necesitar 9 salidas digitales para mostrar datos por un display 7 segmentos no es nada eficiente, teniendo en cuenta que nuestro arduino cuenta con sólo 14. Es por esto que necesitaba de algún método para poder utilizar el display con menos salidas digitales. Y es aquí donde entró en juego el registro de desplazamiento, que permite conversión de datos serie a paralelo y viceversa. En mi caso disponía de un registro de desplazamiento de serie a paralelo 74HC164D que obtuve (al igual que el display) del despiece de un TDT estropeado. Había olvidado un poco qué misión tenían los registros de desplazamiento, así que entre la múltiple información existente en internet utilicé ésta y éste tutorial de arduino con 7 segmentos para refrescarme la memoria. Con el circuito integrado a mano y con los conocimientos de su funcionamiento sólo restaba por realizar la programación en Arduino.  Y tengo que decir que más fácil es imposible, ya que existe una función en Arduino denominada ShiftOut en la cuál indicas cuál salida vas a utilizar como pin de datos, cuál como reloj, el orden (si usando el bit más significativo o el menos) y el byte que que quieres pasar. De esta forma, en lugar de 7 salidas digitales hemos utilizado 2. Un ejemplo de código pasa a ser algo tan reducido como

int clockPin=8;
int dataPin=9;
int digito1=11;//Indica la posición en el display del número a mostrar
int digito2=12;
byte cero=255-252;/*Para pintar un 0 en un 7 segmentos hay que enviar un valor binario de 1111110. Como el registro de desplazamiento tiene 8 bits, añadimos un bit más a esa cadena (da igual el valor) y tendremos entonces 11111100, que en decimal se corresponde con el 252. Este sería en principio el valor a enviar por el registro de desplazamiento, pero para el display que estoy utilizando necesito enviar los bits invertidos (un 0 enciende el led y un uno lo apaga), así que el valor a enviar, en binario, es 00000011, que en decimal es el 3 (255-252). Esto mismo hay que hacer para el resto de valores. */
byte uno=255-96;
byte dos=255-109;
byte tres=255-121;
byte cuatro=255-102;
byte cinco=255-182;
byte seis=255-190;
byte siete=255-224;
byte ocho=255-0;
byte nueve=255-230;

void setup(){
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(digito1, OUTPUT);
  pinMode(digito2, OUTPUT);
}
void loop(){
  shiftOut(dataPin,clockPin,LSBFIRST,siete);//Pintamos el valor 7 en el primer dígito
  delay(1000);
  digitalWrite(digito1,LOW);
  digitalWrite(digito2,HIGH);
  shiftOut(dataPin,clockPin,LSBFIRST,uno);//Pintamos el valor 1 en el primer digito
  delay(1000);
  digitalWrite(digito1,HIGH);
  digitalWrite(digito2,LOW);
  shiftOut(dataPin,clockPin,LSBFIRST,cinco);//PIntamos el valor 5 en el segundo dígito
  delay(1000);
  digitalWrite(digito1,HIGH);
  digitalWrite(digito2,LOW);
  shiftOut(dataPin,clockPin,LSBFIRST,cuatro);//Pintamos el valor 4 en el segundo dígito
  delay(1000);
  digitalWrite(digito1,LOW);
  digitalWrite(digito2,HIGH);
}