arduino

Tutorial Arduino: 74hc595 y leds

Entendiendo distribución de pines del circuito integrado

El IC 74HC595 tiene 16 pines en total. Los que nos importan en este momento son los ocho que sirven como salida, los del suministro de energía y los que se encargan del latch, data y clock.

Distribución de pines

La distribución es así:

Aquí hay otra imagen de la distribución de pines:

Podemos identificar el orden de los pines guiándonos de la pequeña muesca que tiene. Si vemos la muesca arriba, los pines comienzan a la izquierda y terminan a la derecha de ella.

  • Con verde marqué las salidas. Tenemos ocho en total, comenzando con el pin 15 (la salida 0) y luego yendo del pin 1 al 7.
  • Con azul resalté los tres pines que irán conectados al Arduino. En este caso el pin 11 es el Clock, el 12 es el Latch y el 14 Data.
  • Finalmente, remarqué la tierra  y el voltaje individualmente. Es de gran importancia mencionar que debemos alimentar al circuito por sus dos pines: tanto por el 16 como por el 10. Y conectar a tierra el 13 y el 8.

Los demás, ni yo sé para qué funcionan, y tampoco importan por el momento.

¿Qué vamos a hacer?

Vamos a controlar 8 leds usando sólo 3 salidas usando el CI del título. Los materiales son:

  • Tarjeta Arduino, no importa el modelo
  • Circuito integrado 74HC595
  • 8 leds (o diodos emisores de luz) de cualquier color
  • 8 resistencias de 220 Ohms
  • Cables para conectar todo

 

Montando circuito

Hice el circuito en la maravillosa herramienta de Tinkercad. Los cables amarillos son de la salida, recordemos que los leds deben llevar una resistencia de 220 ?.

Puse todo ordenado para que se vea cómo funciona, pero en la práctica podemos conectar como sea.

¿Cómo funciona?

Una vez definidos nuestros pines de latch, clock y data, simplemente tenemos que llamar a la función ShiftOut de Arduino. Es una función nativa, así que no necesitamos ninguna librería. También cabe mencionar que no importa el modelo de la tarjeta que tengamos, la función se comportará de la misma manera, y podemos definir los pines como lo deseemos.

Al llamar a dicha función, le pasamos como primer argumento el pin de data, como segundo el pin de clock, después, como tercero, el orden de salida (Primero el bit más significativo o primero el bit menos significativo; es decir, comenzar de izquierda a derecha o de derecha a izquierda) y finalmente una variable de tipo byte que será casteada internamente en caso de que no la definamos como tal.

Ejemplo de llamada a función

shiftOut(PIN_DATA, PIN_CLOCK, MSBFIRST, 1);

En ese caso le indicamos que escriba el número 1. Entonces pondrá la salida número 8 a HIGH y las demás a LOW; ya que si recordamos, el 1 en binario es 00000001.

Si ahora le decimos que represente el número 20, pondrá solamente la salida número 4 y 6 a HIGH, porque el 20 en binario es 00010100.

Escribir un número arbitrario

Para comenzar con esto vamos a mostrar un número definido por nosotros mismos. Será el número 20. El código es muy simple. Definimos nuestros pines, los establecemos como salida y escribimos el valor.

/*
  Escribir un número decimal a binario usando leds

  @autor parzibyte
  @web parzibyte.me
*/
#define PIN_CLOCK 2
#define PIN_LATCH 3
#define PIN_DATA 4
void setup() {
  /*
    Al final de todo, son pines de salida,
    y debemos establecerlos como tal
  */  pinMode(PIN_CLOCK, OUTPUT);
  pinMode(PIN_LATCH, OUTPUT);
  pinMode(PIN_DATA, OUTPUT);

  /*
    Simplemente vamos a escribir un valor
  */  digitalWrite(PIN_LATCH, LOW); //Le decimos que vamos a escribir algo...
  shiftOut(PIN_DATA, PIN_CLOCK, LSBFIRST, 20); //Lo escribimos
  digitalWrite(PIN_LATCH, HIGH) ; //Y le indicamos que lo guarde
}
void loop() {}

Al subir y cargar nuestro código, el resultado será el siguiente:

Podemos observar que se encendieron los leds en la posición que representa al 16 y al 4 (16 + 4 = 20)

Puedes ver la simulación aquí (necesitarás registrarte).

Escribir los números del 0 al 255

Vamos a hacer esto un poco más divertido, ahora vamos a representar los números que se pueden representar con ocho bits, esto es, del 0 al 255. El código ahora sería:

/*
  Escribir los números del 0 al 255 en su representación binaria usando leds

  @autor parzibyte
  @web parzibyte.me
*/
#define PIN_CLOCK 2
#define PIN_LATCH 3
#define PIN_DATA 4
void setup() {
  /*
    Al final de todo, son pines de salida,
    y debemos establecerlos como tal
  */  pinMode(PIN_CLOCK, OUTPUT);
  pinMode(PIN_LATCH, OUTPUT);
  pinMode(PIN_DATA, OUTPUT);

}
void loop() {
  /*
    Vamos a hacer lo mismo pero ahora en un ciclo, y dentro de loop, para que cuando llegue a 255 inicie de nuevo
  */  for (int m = 0; m < 256; m++) {
    digitalWrite(PIN_LATCH, LOW); //Le decimos que vamos a escribir algo...
    shiftOut(PIN_DATA, PIN_CLOCK, LSBFIRST, m); //Escribimos el número en el que ahora está el ciclo
    digitalWrite(PIN_LATCH, HIGH) ; //Y le indicamos que lo guarde
    delay(500); //Esperamos un poco (medio segundo), para que se vea la animación. De otro modo, no veríamos correctamente cómo va "contando"
  }
}

Si ejecutamos el código, veremos cómo va contando. Primero enciende el led que representa al 1, luego al 2, luego al 2 y 1, y así sucesivamente. Puedes ver la simulación aquí (necesitarás registrarte).

Escribir un número definido por el usuario

Seguimos jugando. Ahora vamos a pedir un número por comunicación Serial, y ese número será escrito en los leds.

Veamos ahora el código:

/*
  Escribir un número proporcionado por el usuario a través de la comunicación Serial

  @autor parzibyte
  @web parzibyte.me
*/
#define PIN_CLOCK 2
#define PIN_LATCH 3
#define PIN_DATA 4
void setup() {
  /*
    Al final de todo, son pines de salida,
    y debemos establecerlos como tal
  */  pinMode(PIN_CLOCK, OUTPUT);
  pinMode(PIN_LATCH, OUTPUT);
  pinMode(PIN_DATA, OUTPUT);

  Serial.begin(9600); //Comenzar comunicación serial

}
void loop() {
  /*
    Vamos a hacer lo mismo pero ahora en un ciclo, y dentro de loop, para que cuando llegue a 255 inicie de nuevo
  */  if (Serial.available()) { //¿Hay algo que leer en el serial?
    int numero = Serial.parseInt(); //Si es que sí, lo leemos y lo convertimos a entero
    if (numero >= 0 && numero < 256) { //Recordemos que sólo tenemos 1 byte, por lo que no podemos representar números más grandes que 255
      digitalWrite(PIN_LATCH, LOW); //Le decimos que vamos a escribir algo...
      shiftOut(PIN_DATA, PIN_CLOCK, LSBFIRST, numero); //Escribimos el número que el usuario proporcionó
      digitalWrite(PIN_LATCH, HIGH) ; //Y le indicamos que lo guarde
    }
  }
}

Hacemos el mismo proceso, sólo que ahora leemos el número por comunicación Serial. También comparamos si el número cabe en un byte (si está entre 0 y 255) para no tener resultados inesperados. Al ejecutarlo e ingresar un número, este es el resultado:

Puedes ver la simulación aquí (necesitarás registrarte).

Escribir el código ASCII de un carácter

Para terminar con esto, vamos a escribir la representación de un carácter en binario. Por ejemplo, en ASCII, el arroba (@) es representado por el número 64. Y el 64 en binario es 01000000. Así que pediremos un carácter por comunicación Serial y pondremos su representación binaria con los leds.

/*
  Escribir la representación binaria de un carácter proporcionado por el usuario a través de la comunicación Serial

  @autor parzibyte
  @web parzibyte.me
*/
#define PIN_CLOCK 2
#define PIN_LATCH 3
#define PIN_DATA 4
void setup() {
  /*
    Al final de todo, son pines de salida,
    y debemos establecerlos como tal
  */  pinMode(PIN_CLOCK, OUTPUT);
  pinMode(PIN_LATCH, OUTPUT);
  pinMode(PIN_DATA, OUTPUT);

  Serial.begin(9600); //Comenzar comunicación serial

}
void loop() {
  /*
    Vamos a hacer lo mismo pero ahora en un ciclo, y dentro de loop, para que cuando llegue a 255 inicie de nuevo
  */  if (Serial.available()) { //¿Hay algo que leer en el serial?
    char caracter = Serial.read(); //Si es que sí, lo leemos. En este caso la variable será de tipo char
    if (caracter >= 0 && caracter < 256) { //Recordemos que sólo tenemos 1 byte, por lo que no podemos representar carácteres cuyo código no esté entre 0 y 255
      digitalWrite(PIN_LATCH, LOW); //Le decimos que vamos a escribir algo...
      shiftOut(PIN_DATA, PIN_CLOCK, LSBFIRST, caracter); //Escribimos el carácter que el usuario proporcionó
      digitalWrite(PIN_LATCH, HIGH) ; //Y le indicamos que lo guarde
    }
  }
}

Ahora en lugar de leer un entero leemos un carácter. Y lo escribimos. Por ejemplo, si yo pongo el @ se encenderá el led que representa al 64:

Nuevamente, se puede simular aquí, y se necesita registro.

Conclusión

Este circuito integrado es una maravilla, pues nos ahorra muchos pines. Ya que sólo usamos 3 y con ellos controlamos 8. Me parece que también existen de más salidas. Por otro lado, existen aquellos que son lo contrario. Es decir, que nos permiten leer muchos valores con pocas entradas.

Todo esto lo hice en el simulador porque es una manera fácil y rápida de que la gente pueda probar, sin necesidad de tener que armar el circuito, ni comprar los componentes. De todas maneras, lo he probado yo con un Arduino en la vida real, y una vez que lo logré y funcionó, lo simulé.

Espero que haya servido.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Ver comentarios

  • Hola que tal me gusto tu post pero me surgió una duda ¿Se puede conectar 4 leds en paralelo en un solo pin del microcontrolador 74HC595? pude ser que no se enciendan del todo bien pero si funciona como haría para añadir una fuente externa (para que funcione bien) para luego conectarlo al pin de ese microcontrolador. Agradeceria mucho tu respuesta Saludos

    • Hola, claro que sí. Si mandas la corriente normal, no creo que enciendan todos o será de manera baja. Tus opciones son usar un Transistor o un relevador/relé y una fuente externa, como lo mencionas.
      En resumen, claro que puedes conectar muchos leds a una sola salida, y no solamente leds, sino cualquier otra cosa.

  • Estimado. Tengo que resolver un problema con un vu meter. Este usa un ATtyni24.
    Yo estoy a penas aprendiendo, comenzando a aprender a programar. Me gustaria su puedes apoyarme en dicho proyecto.
    saludos

    • Hola, lo siento, no he trabajado con eso que mencionas, únicamente con Arduino. Espero que encuentres la solución pronto, saludos.

Entradas recientes

Creador de credenciales web – Aplicación gratuita

Hoy te voy a presentar un creador de credenciales que acabo de programar y que…

2 días hace

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

1 semana hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

1 semana hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

1 semana hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

1 semana hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

1 semana hace

Esta web usa cookies.