LEDs usando técnica Multiplexing | Arduino

Multiplexing LEDs & Arduino

Muchas veces tenemos la necesidad de utilizar varios de los pines de nuestro microcontrolador, lo cual nos impide agregar mas instrucciones para nuestro proyecto, como lo es el uso de servomotores, una comunicación serial o bluetooth, switches o indicadores de voltaje, por mencionar algunos.

Ejemplo de Multiplexing para dos display de 7 segmentos:

Resultado de imagen para 7 segment display multiplexing

Para ello utilizaremos el siguiente ejemplo donde mostraremos el uso de la técnica de Multiplexing y convertidor serial a paralelo. Un cubo de leds formado por 9 ánodos, que representan los 9 leds de un cubo de 3x3x3; y 3 cátodos para los tres niveles que existen.

Esto nos da un total de 12 pines que debemos programar en nuestra tarjeta Arduino, en mi caso uso un Arduino Nano que cuenta con 14 pines digitales, de tal manera que solo queda un total de 2 pines disponibles para poder usar en lo que nos plazca.

 


 

Pero, ¿si quiero usar menos pines?

Bueno esto es posible utilizando un integrado, especificamente, un 74HC595 (Registro de corrimiento) que nos permite cambiar de serial a paralelo.

Resultado de imagen para 74hc595

 

Ejemplo:

Realizaremos algo parecido al ejemplo mostrado arriba pero digamos que un poco menos complejo, aunque de igual manera es posible su implemnetacion usando los mismo registros de corrimiento.

 

Pin map:


 

¿Cómo funciona?

La información es transmitida por un pin y un segundo se encarga de escribirla dentro del registro de corrimiento cuando este lista, mientras un reloj mantiene la sincronía entre los datos.

Resultado de imagen para 74hc595 funcionamiento

Mas información detalla:


 

El integrado 74HC595 es relativamente barato, lo podemos encontrar en las tiendas de electrónica por alrededor de un dolar.

Para nuestro cubo de leds necesitaremos dos registros de corrimiento ya que éste solo es de 8 bits, es decir que nos permite manipular 8 salidas digitales. Supongamos que tenemos un cubo de leds de 8x8x8, simplemente seguiremos agregando mas registros de corrimiento hasta completar todos los pines a utilizar, con los mismos 3 pines del Arduino.

Ahora veamos el diagrama de conexiones para nuestro cubo de leds, usaremos los pines digitales D5, D6 y D7 ademas de la alimentación. Clic en la imagen para ampliar.


Observamos que para los niveles es necesario utilizar un transistor (2N2222 ó 2N3904), de esta manera conmutamos a tierra y cerramos el circuito. Cada ánodo tiene una resistencia de 220Ω de protección.

Una vez todo conectado correctamente, vamos a ver de que trata la programación.

Código:

NOTA: El lógica del código esta escrita para activar los niveles del cubo de leds con estado bajo o cero.

//Pin ST_CP de 74HC595
int latchPin = 6;
//Pin SH_CP de 74HC595
int clockPin = 7;
//Pin DS de 74HC595
int dataPin = 5;

// Info
byte dataP;
byte dataN;
byte dataA[10];
byte dataC[10];

void setup() {
// Salida
pinMode(latchPin, OUTPUT);
Serial.begin(9600);

// Array Anodos
dataA[0] = 0x07; //00000111
dataA[1] = 0x24; //00100100
dataA[2] = 0xC0; //11000000
dataA[3] = 0x49; //01001001
dataA[4] = 0xFF; //11111111
dataA[5] = 0xFF; //11111111
dataA[6] = 0xFF; //11111111
dataA[7] = 0xFF; //11111111
dataA[8] = 0xFF; //11111111
dataA[9] = 0x10; //00010000

// Array Catodos
dataC[0] = 0x00; //00000000
dataC[1] = 0x01; //00000001
dataC[2] = 0x01; //00000001
dataC[3] = 0x00; //00000000
dataC[4] = 0x07; //00000111
dataC[5] = 0x0B; //00001011
dataC[6] = 0x0D; //00001101
dataC[7] = 0x0B; //00001011
dataC[8] = 0x07; //00000111
dataC[9] = 0x00; //00000000
}

void loop() {

for (int j = 0; j < 10; j++) {
// Carga secuencia de encendido
dataP = dataA[j];
dataN = dataC[j];
// Latch a estado bajo
digitalWrite(latchPin, 0);
// move on!
shiftOut(dataPin, clockPin, dataN);
shiftOut(dataPin, clockPin, dataP);
// Latch pin estado alto
digitalWrite(latchPin, 1);
delay(350);
}
}

// El corazón del código
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
// Cambio de 8 bits con MSB primero,
// durante el flanco de subida del clock,

// Configuración inicial
int i=0;
int pinState;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);

// Limpia todo y prepara para corrimiento
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);

// Cada bit se recorre una posicion para detemrinar
// el estado alto o bajo y a partir de esto, se
// escribe su correspondiente en el pin DATA
for (i=7; i>=0; i–) {
digitalWrite(myClockPin, 0);

// Corrimiento bit por bit
if ( myDataOut & (1<<i) ) {
pinState= 1;
}
else {
pinState= 0;
}

// Establece estado alto o bajo
digitalWrite(myDataPin, pinState);
// Estado alto de reloj (edge)
digitalWrite(myClockPin, 1);
// Baja estado de DATA para preparar futuros bits
digitalWrite(myDataPin, 0);
}

// Estado bajo de reloj (falling)
digitalWrite(myClockPin, 0);
}

 

He colocado cable tipo Ribbon con headers macho para usarlo dentro del protoboard.

Registros de corrimiento y conexiones:

Resultados finales:

Y asi es como podemos controlar todo un cubo de leds con distintas secuencias utilizando solamente 3 pines del arduino y alimentación.

 

Estructura del arreglo:

Tamaño total: 12 bits

Bits de ánodos: 9 bits
Bits de cátodos: 3 bits

8 bits –> Primer Registro de corrimiento

4 bits –> Segundo Registro de corrimiento –> 1 bit para la novena columna de leds y los 3 restantes para los cátodos.

 

Próximamente estaré agregando al post un video de demostración, recuerda que puedes modificar la secuencia de encendido por medio de los arreglos.

, , , , , , , , , , , , , , , , , , , ,








.



About Notf0und

Estudiante de Ingeniería Electrónica, Coder, Editor, InfoSec Practice, Hardware & Software Libre, Linux User, Hacking, WebDeveloper, Drawings. Actualmente, dedica parte de su tiempo libre publicando artículos de interés y participando en foros. Colaborador y miembro del proyecto OpenSUSE. Open downloads, for open minds.
View all posts by Notf0und →