miércoles, 1 de noviembre de 2023

Conectar un servo. Parking. (IDE Arduino)

El Shield multifunción deja libres algunos pines de Arduino, en concreto el 5, 6, 9 y A5. Además, en los tres primeros podemos conectar directamente un micro servo (tipo SG 90), sólo debemos tener cuidado en colocar el cable naranja donde está serigrafiado el número del pin.


Para trabajar con el microservo vamos a utilizar una librería auxiliar, se trata de un conjunto de funciones que nos facilitan su programación. La librería se denomina Servo y va incluida en el IDE Arduino, aunque hay que declararla al inicio del programa y definir los servos que vayamos a usar. El programa adjunto mueve el micro servo de un extremo al otro a intervalos de 45º:

#include <Servo.h>   //inluimos la librería 

Servo servo1;        //definimos nuestro servo como servo1,
                     //podemos darle el nombre que deseemos.
                     //Podemos declarar más, servo2, servo3,...
void setup()
{
  servo1.attach(5);  //conectamos servo1 en el pin 5
}

void loop()
{ 
  servo1.write(0);   //indicamos el ángulo en el debe posicionarse
  delay(500);
  servo1.write(45);
  delay(500);
  servo1.write(90);
  delay(500);
  servo1.write(135);
  delay(500);
  servo1.write(180);
  delay(500);
}

Ahora vamos a mover el servo con los pulsadores S1 y S2, en un sentido y en el contrario.

/*
 * servoPulsador.ino
 * Al accionar los pulsadores S1 y S2 movemos el servo
 * hacia la izquierda y la derecha respectivamente,
 * a intervalos de 5 grados.
 */

#include <Servo.h>  //incluimos la libreria Servo

Servo servo1;       //definimos nuestro servo como servo1

int angulo = 90;    //creamos la variable angulo
 
void setup()
{
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  servo1.attach(5);        //servo1 en el pin 5
  servo1.write(angulo);    //servo1 a 90º
}

void loop()
{ 
  if (digitalRead(A1) == LOW){        //si pulsamos A1
    angulo = angulo + 5;              //incrementamos angulo en 5º
    if (angulo > 180){angulo=180;}    //impedimos que sea > de 180º
  }
  if (digitalRead(A2) == LOW){        //si pulsamos A2
    angulo = angulo - 5;              //decrementamos angulo en 5º
    if (angulo < 0){angulo=0;}        //impedimos que sea < de 0º
  }
  servo1.write(angulo);               //posicionamos servo1
  delay(200);
}


Ejercicios propuestos:

1.- Queremos abrir y cerrar una barrera utilizando el micro servo; por ejemplo, 10º cerrada y 170º abierta. El control lo haremos con dos pulsadores, S1 para abrir y S2 para cerrar.

2.- Ahora vamos a utilizar un único pulsador, ya que, una vez abierta, la barrera se cerrará automáticamente transcurridos 20 segundos. Ampliar el programa para que en el display se muestre el número de veces que se acciona el pulsador (valorar la posibilidad de usar la función delayMillis(), analizada en la entrada anterior).

3.- Realizar un programa que nos permita controlar el funcionamiento de un aparcamiento. Podemos usar  micro servos para hacer las barreras de entrada y salida y controlarlos mediante los pulsadores. Uno de los LEDs se debe poner en rojo cuando el parking esté completo y el display debe mostrar, en todo momento, el numero de plazas que quedan libres.

domingo, 6 de noviembre de 2022

El display III. La instrucción "millis()" (IDE Arduino)

En la función que creamos en la entrada anterior para controlar el display ("display7Seg") sus dígitos se van encendiendo y apagando sucesivamente, como eso sucede a gran velocidad (se coloca dentro del bucle loop que se repite permanentemente) nuestros ojos ven encendidos los cuatro a la vez. Si el programa se detiene en algún momento, por ejemplo, porque usamos la instrucción "delay", sólo se quedará encendido uno de los dígitos. Eso es lo que va a suceder en el programa que vamos a hacer a continuación, se trata de que el display muestre los segundos que van transcurriendo desde que se inicia.

/*
 * displayCuentaSegundosDelay.ino
 * Queremos que el display vaya contando los segundos que van
 * transcurriendo desde que se inicia el programa.
 * Esta versión no funcionará bien, ya que al usar la
 * instrucción "delay(1000)" el programa se detiene un segundo
 * y durante ese tiempo sólo permanece encendido el último
 * digito de la función "display7Seg".
 * En una versión posterior veremos como resolverlo.
 */

byte codigo7seg[] = {B00000011, B10011111, B00100101, B00001101, B10011001, 
                     B01001001, B01000001, B00011111, B00000001, B00001001};
int segundos = 0;

void setup() {
  pinMode(4,OUTPUT);                     //pines display
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);  
}

void loop() {
  delay(1000);            //el programa se detiene 1 seg.
  segundos++;
  display7Seg(segundos);  //el último digito permanece encendido 1 seg.
}

void display7Seg(int numero){
  int millar = numero/1000;                                   
  int centena = (numero - millar*1000)/100;              
  int decena = (numero - millar*1000 - centena*100)/10;  
  int unidad = numero - millar*1000 - centena*100 - decena*10;
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[unidad]);
  shiftOut(8, 7, LSBFIRST, B00010000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[decena]);
  shiftOut(8, 7, LSBFIRST, B00100000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[centena]);
  shiftOut(8, 7, LSBFIRST, B01000000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[millar]);
  shiftOut(8, 7, LSBFIRST, B10000000);
  digitalWrite(4,HIGH);
}

Para evitar que esto se produzca  vamos a usar una nueva instrucción del IDE Arduino, "millis()". Se trata de un contador que se va incrementando cada milisegundo desde que se pone en marcha el programa. Para hacer una temporización tenemos que almacenar en una variable los milisegundos correspondientes al inicio de la misma, después vamos preguntando si los milisegundos transcurridos son superiores a los que hemos guardado mas el tiempo que queramos que dure la temporización.

/*
 * displayCuentaSegundosMillis.ino
 * Queremos que el display vaya contando los segundos que van
 * transcurriendo desde que se inicia el programa.
 * En este caso, hemos usado la instrucción "millis", que nos
 * da los milisegundos que van pasando desde que se inicia el
 * programa. Con esta instrucción podemos hacer temporizaciones
 * sin que el programa se detenga.
 */

byte codigo7seg[] = {B00000011, B10011111, B00100101, B00001101, B10011001, 
                     B01001001, B01000001, B00011111, B00000001, B00001001};

int segundos = 0;
unsigned long tiempoInicial;       //aquí guardaremos los miliseg que lleva
                                   //contados la instrución millis cuando
                                   //vayamos a iniciar una temporización.

void setup() {
  pinMode(4,OUTPUT);               //pines display
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  tiempoInicial = millis();        //guardamos los miliseg actuales,
                                   //millis seguirá incrementándose 
}

void loop() {
  if(millis() > tiempoInicial + 1000) {    //Si los millis actuales superan
                                           //a los guardados + 1000, es que
                                           //ha pasado 1 segundo.
    tiempoInicial = millis();              //Guardamos de nuevo el valor
                                           //actual de millis.
    segundos++;                            //Incrementamos segundos.
  }
  display7Seg(segundos);
}


void display7Seg(int numero){
  int millar = numero/1000;                               
  int centena = (numero - millar*1000)/100;     
  int decena = (numero - millar*1000 - centena*100)/10;
  int unidad = numero - millar*1000 - centena*100 - decena*10;
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[unidad]);
  shiftOut(8, 7, LSBFIRST, B00010000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[decena]);
  shiftOut(8, 7, LSBFIRST, B00100000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[centena]);
  shiftOut(8, 7, LSBFIRST, B01000000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[millar]);
  shiftOut(8, 7, LSBFIRST, B10000000);
  digitalWrite(4,HIGH);
}

Otra opción es crear una nueva función para hacer temporizaciones, pero que no detenga totalmente el programa, sino que permita atender aquellos procesos que lo necesiten. Esta función va a utilizar una nueva instrucción condicional que ejecuta en bucle las instrucciones que le indiquemos mientras que la condición se cumpla, se trata de while (mientras que..). A continuación se muestra el programa con la nueva función, que hemos llamado delayMillis, ya que también usamos en ella la instrucción millis().

/*

 * displayCuentaSegundosDelayMillis.ino
 * Queremos que el display vaya contando los segundos que van
 * transcurriendo desde que se inicia el programa.
 * En este caso, hemos creado la función delayMillis, que hará
 * el retardo de 1 segundo pero manteniendo el refresco del 
 * display. Con esta función podemos hacer temporizaciones sin
 * desatender aquellos procesos que lo necesiten.
 * En la función utilizamos la instrucción while (mientras que):
 *     while (condición) {    //mientras que se cumpla la condición se
 *       instrucciones        //permanece ejecutando estas instrucciones, 
 *     }                      //cuando deje de cumplirse se sale del bucle
 */

byte codigo7seg[] = {B00000011, B10011111, B00100101, B00001101, B10011001, 
                     B01001001, B01000001, B00011111, B00000001, B00001001};

int segundos = 0;

void setup() {
  pinMode(4,OUTPUT);               //pines display
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
}

void loop() {         
  delayMillis(1000);                 //la nueva función
  segundos++;
  display7Seg(segundos);
}

void delayMillis(unsigned long tiempo){
  unsigned long tiempoFinal = millis() + tiempo;
  while (millis() < tiempoFinal){     //El programa se queda en este bucle 
    display7Seg(segundos);            //hasta que pase el tiempo fijado,
  }                                   //pero atiende al display.
}


void display7Seg(int numero){
  int millar = numero/1000;                               
  int centena = (numero - millar*1000)/100;     
  int decena = (numero - millar*1000 - centena*100)/10;
  int unidad = numero - millar*1000 - centena*100 - decena*10;
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[unidad]);
  shiftOut(8, 7, LSBFIRST, B00010000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[decena]);
  shiftOut(8, 7, LSBFIRST, B00100000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[centena]);
  shiftOut(8, 7, LSBFIRST, B01000000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[millar]);
  shiftOut(8, 7, LSBFIRST, B10000000);
  digitalWrite(4,HIGH);
}

Ejercicios propuestos.

1.- Hacer un programa que haga aparecer en el display el número 1234 durante 2 segundos y el número 5678 durante otros dos, el ciclo se repite permanentemente.

2.- Ahora queremos programar un reloj básico de horas y minutos. Crear dos variables, horas y minutos, y utilizar su valor inicial para la puesta en hora. Para visualizarlas juntas podemos usar la expresión 100*horas+minutos.


lunes, 1 de agosto de 2022

El display II. Funciones. (IDE Arduino)

En esta entrada vamos a utilizar las denominadas variables con índice, que van a servirnos para acceder con facilidad a los códigos 7 segmentos de las cifras numéricas. Veámoslo en el siguiente programa:

/*
* displayNumero0-9.ino * Va mostrando en el display (dígito más a la derecha) los * números del 0 al 9 a intervalos de 1 segundo. * Hemos hecho una especie de tabla con los códigos de 7 segmentos * de las diez cifras (del 0 al 9). Para acceder a estos códigos sólo * tenemos que indicar el nombre de la tabla y el orden del elemento * que queremos obtener entre los corchetes, empezando por 0. */                    //codigo7seg[], variable con índice para                    //guardar una tabla con los códigos de todas                    //las cifras decimales.                    //abcdefgp recordar que cero es encendido byte codigo7seg[] = {B00000011,     //código 7 segmentos del 0                     B10011111,     //código 7 segmentos del 1                     B00100101,     //código 7 segmentos del 2                       B00001101,     //código 7 segmentos del 3                     B10011001,     //código 7 segmentos del 4                     B01001001,     //código 7 segmentos del 5                     B01000001,     //código 7 segmentos del 6                     B00011111,     //código 7 segmentos del 7                     B00000001,     //código 7 segmentos del 8                     B00001001};    //código 7 segmentos del 9                                    //codigo7seg[0] sería 00000011                                    //codigo7seg[1] sería 10011111                                    //y así sucesivamente... int numero = 0;                       void setup (){  pinMode(4,OUTPUT);  pinMode(7,OUTPUT);  pinMode(8,OUTPUT); } void loop(){  digitalWrite(4,LOW);  shiftOut(8, 7, LSBFIRST, codigo7seg[numero]);  shiftOut(8, 7, LSBFIRST, B00010000);  digitalWrite(4,HIGH);  numero++;                            //incrementamos numero  if(numero == 10){                    //si llegamos a 10    numero = 0;                        //empezamos de nuevo en cero  }  delay(1000); }

En una entrada anterior hicimos un programa que mostraba la lectura del potenciómetro a través del Monitor Serie, ahora lo haremos con el display. Nosotros desconocemos cual es la lectura y, por tanto, no podemos enviar cuatro dígitos concretos al display; el programa tiene que ser capaz de separar en sus cuatro cifras (millar, centena, decena y unidades) el valor obtenido del potenciómetro. En el siguiente ejemplo se muestra como se puede hacer esa descomposición:

numero = 8547

                        millar = numero : 1000
                        millar =   8547 : 1000 = 8

                      centena = (numero - millar*1000) : 100
                      centena = (  8547   -    8*1000)    : 100
                      centena =           547                    : 100 = 5

                decena = (numero - millar*1000 - centena*100) : 10
                decena = (   8547  -     8000       -       500       ) : 10
                decena =                      47                                 : 10 = 4

             unidades = numero - millar*1000 - centena*100 - decena*10
             unidades =   8547   -     8000       -        500       -       40      = 7


El programa sería el siguiente:                          

/*
 * displayPotenciometro.ino
 * Visualizamos en el display los valores del potenciometro.
 * Una vez leido el numero hay que descomponenlo en sus cifras,
 * millar, centena, decena y unidad.
 */

byte codigo7seg[] = {B00000011,     //0
                     B10011111,     //1
                     B00100101,     //2  
                     B00001101,     //3
                     B10011001,     //4
                     B01001001,     //5
                     B01000001,     //6
                     B00011111,     //7
                     B00000001,     //8
                     B00001001};    //9
                      
int valorPot;              
int millar;
int centena;
int decena;
int unidad;

void setup (){
  pinMode(4,OUTPUT);    //pines display
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(A0, INPUT);   //pin potenciómetro
}

void loop(){
  valorPot = analogRead(A0);
  millar = valorPot/1000;
  centena = (valorPot - millar*1000)/100;
  decena = (valorPot - millar*1000 - centena*100)/10;
  unidad = valorPot - millar*1000 - centena*100 - decena*10;
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[unidad]);
  shiftOut(8, 7, LSBFIRST, B00010000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[decena]);
  shiftOut(8, 7, LSBFIRST, B00100000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[centena]);
  shiftOut(8, 7, LSBFIRST, B01000000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[millar]);
  shiftOut(8, 7, LSBFIRST, B10000000);
  digitalWrite(4,HIGH);
}

Vamos a modificar el programa anterior para incluir una especie de "instrucción propia" (función) que sirva para visualizar cualquier numero en el display, esta función la podríamos incluir también en otros programas.

/*
 * displayFuncion.ino
 * El programa muestra en el display las lecturas del
 * potenciómetro.
 * En este caso, vamos a crea una función denominada display7Seg
 * para poder visualizar cualquier número, bastará con escribir
 * el nombre de la función y, entre paréntesis, el número a mostrar.
 * Por ejemplo: display7Seg(1582);
 */
                    
byte codigo7seg[] = {B00000011, B10011111, B00100101, B00001101, B10011001, 
B01001001, B01000001, B00011111, B00000001, B00001001};
int valorPot;                            //para guardar el valor del potenciómetro
//las variables millar, centena, decena
//y unidad están declaradas en la función void setup (){  pinMode(4,OUTPUT); //pines display  pinMode(7,OUTPUT);  pinMode(8,OUTPUT);  pinMode(A0, INPUT); //pin potenciómetro } void loop(){  valorPot = analogRead(A0);             //leemos el potenciómetro  display7Seg(valorPot);                 //lo mostramos en el display }
                                         //Nuestra función
void display7Seg(int numero){
  int millar = numero/1000;                         
  int centena = (numero - millar*1000)/100;              
  int decena = (numero - millar*1000 - centena*100)/10;  
  int unidad = numero - millar*1000 - centena*100 - decena*10;  
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[unidad]);
  shiftOut(8, 7, LSBFIRST, B00010000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[decena]);
  shiftOut(8, 7, LSBFIRST, B00100000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[centena]);
  shiftOut(8, 7, LSBFIRST, B01000000);
  digitalWrite(4,HIGH);
  digitalWrite(4,LOW);
  shiftOut(8, 7, LSBFIRST, codigo7seg[millar]);
  shiftOut(8, 7, LSBFIRST, B10000000);
  digitalWrite(4,HIGH);
}

Ejercicios propuestos:

1.- Realizar un programa en el que el display muestre, inicialmente, el número "0000" y, mientras mantengamos presionado  el pulsador "S1", cambie el cero de las centenas por un uno. Utilizar la función display7Seg y crear la variable numero con el valor 0. Tener en cuenta que para hacer aparecer un 1 en la cifra de las centenas bastaría con sumar 100 y para quitarlo con restar dicha cantidad.

2.- Ahora queremos que si presionamos S1 aparezca un 1 en la cifra de las centenas, si presionamos S2 veamos un 1 en las decenas y si presionamos S3 aparezca un 1 en la cifra de las unidades.

3.- Vamos a hacer una especie de "marcador deportivo". Con el pulsador S1 incrementamos el valor de los dos dígitos situados más a la izquierda, con S2 incrementamos el de los dos dígitos de la derecha. Si se llega a 20 se vuelve a empezar desde cero.





martes, 12 de julio de 2022

El display de 7 segmentos I (IDE Arduino)

Se trata de un display de cuatro dígitos en el que, principalmente, podemos visualizar números y también algunas letras y símbolos. Cada uno de los dígitos está compuesto por 8 diodos LED, los 7 segmentos y el punto decimal. Estos diodos se encienden con un "0" y permanecen apagados cuando se les suministra un "1".

En la figura adjunta podemos apreciar el nombre de los segmentos, su orden y los códigos binarios de 7 segmentos correspondientes a algunos números y letras. 

   a b c d e f g p
2  0 0 1 0 0 1 1 0
8  0 0 0 0 0 0 0 0
L  1 1 1 0 0 0 1 0
A  0 0 0 1 0 0 0 0


Para encender el número "2". en el dígito más a la izquierda del shield multifunción, Arduino debe enviar dos códigos binarios, el de 7 segmentos del número "2" (00100101) y otro para indicar cual es el dígito que se enciende, en este caso, el situado a la izquierda (10000000). Estos códigos se envían en serie, un bit tras otro, a través del pin 8, utilizando la instrucción "siftOut" que se encarga de hacer todo el proceso. Además son necesarios dos pines más, el pin 4, (una especie de permiso que se activa cuando está en "0", tenemos que hacerlo nosotros) y el pin 7 (unos pulsos de reloj para indicar cuando son válidos cada uno de los bit); de este pin y de generar esos pulsos se encarga la propia instrucción "siftOut". En la imagen podemos ver este proceso:


En definitiva, el programa para visualizar el número 2 en el display de la izquierda quedaría de la siguiente manera:
/*
 * display2.ino
 * Visualiza el número 2 en el dígito más a la izquierda del display
 * de 7 segmentos.
 * Los leds del display se encienden con un cero y se apagan con un 1. 
 * El código del numero 2 sería: a b c d e f g p
 *                               0 0 1 0 0 1 0 1
 * Arduino envía los datos (DATA) al shield multifunción en serie, usando
 * el pin 7. A través del pin 8 manda unos pulsos de "reloj" (CLOCK)para 
 * indicar la validez de los datos presentes en el pin 7. Por último, el
 * pin 4 sirve de cerrojo (LATCH), para que el shield multifunción sepa
 * cuando empieza y termina la transmisión de datos.
 * Hay que enviar dos números: el primero se corresponde con el código
 * 7 segmentos que queremos visualizar, el segundo indica (con un 1) el
 * dígito que estará encendido.
 */

void setup (){
  pinMode(4,OUTPUT);     //LATCH, habilita recepción de datos
  pinMode(7,OUTPUT);     //DATA, para enviar los datos
  pinMode(8,OUTPUT);     //CLOK, indica cuando los datos son válidos
}
void loop(){
  digitalWrite(4,LOW);                   //Un 0 habilita la llegada de datos
  shiftOut(8, 7, LSBFIRST, B00100101);   //envía el código 7 segmentos
  shiftOut(8, 7, LSBFIRST, B10000000);   //envía el dígito que se enciende
  digitalWrite(4,HIGH);                  //Un 1 deshabilita la transmisión
}

Ahora vamos a mostrar el número "0134"; primero dígito a dígito y, posteriormente, con una pequeña modificación, los veremos los cuatro a la vez.

/*
 * display0134.ino
 * Vemos en el display los números 0, 1, 3 y 4, de uno en uno
 * a intervalos de 1 segundo. Cada número aparece en un dígito
 * diferente, el 0 en el más a la izquierda.
 * Para ver el número completo 0134 a la vez, tenemos que quitar
 * los retardos (delay) de 1 segundo. Se sigue encendiendo un solo
 * dígito, pero al no haber retardos y estar en un bucle que se
 * repite rapidísimamente nuestros ojos los ven todos encendidos.
 */

void setup (){
  pinMode(4,OUTPUT);     //LATCH
  pinMode(7,OUTPUT);     //DATA
  pinMode(8,OUTPUT);     //CLOCK
}

void loop(){
  digitalWrite(4,LOW); 
  shiftOut(8, 7, LSBFIRST, B00000011);    //el 0
  shiftOut(8, 7, LSBFIRST, B10000000);    //en el dígito de la izquierda
  digitalWrite(4,HIGH);
  delay(1000);
  digitalWrite(4,LOW); 
  shiftOut(8, 7, LSBFIRST, B10011111);    //el 1
  shiftOut(8, 7, LSBFIRST, B01000000);    //en el siguiente dígito
  digitalWrite(4,HIGH);
  delay(1000);
  digitalWrite(4,LOW); 
  shiftOut(8, 7, LSBFIRST, B00001101);    //el 3
  shiftOut(8, 7, LSBFIRST, B00100000);    //en el siguiente dígito
  digitalWrite(4,HIGH);
  delay(1000);
  digitalWrite(4,LOW); 
  shiftOut(8, 7, LSBFIRST, B10011001);    //el 4
  shiftOut(8, 7, LSBFIRST, B00010000);    //en el último de la derecha
  digitalWrite(4,HIGH);
  delay(1000);                            //quitar todos los delay
                                          //para ver los cuatro a la vez
}

Ejercicios propuestos:

1.- Escribir un programa que haga aparecer en el display (en el dígito más a la derecha) los números del 0 al 5 a intervalos de un segundo.

2.- Mostrar en el display la palabra "HOLA".

3.- Hacer un programa que vaya encendiendo y apagando de uno en uno los segmentos exteriores del display, dándole la vuelta completa: