miércoles, 1 de enero de 2020

Multiplexado LEDs

Vamos a abordar la realización de unas funciones que nos permitan realizar el multiplexado de la matriz de LEDs y visualizar en ella la imagen que deseemos. La idea es crear una imagen virtual de la matriz, utilizando un array de dos dimensiones:

boolean matrizLed[5][5]={{1,0,0,0,1},
                         {0,1,0,1,0},
                         {0,0,1,0,0},
                         {0,1,0,1,0},
                         {1,0,0,0,1}}; //matrizLed[fila][columna]

Con los ceros y los unos indicamos el estado de los LEDs (0 apagado, 1 encendido). Cada 6 milisegundos apagaremos, inicialmente, todos los LEDS, activaremos una de las tres filas internas y llevaremos a cabo el encendido/apagado de los LEDS correspondientes (teniendo en cuenta los datos de esta imagen virtual). En definitiva, los LEDs de la primera fila interna se encenderan durante 6 milisegundos, después se apagarán y serán los de la segunda fila los que se enciendan ese mismo tiempo y, finalmente, después de apagarse todos se encenderan los de la tercera fila otro 6 milisegundos y así sucesivamente. El programa es el siguiente:
/*
 * multiplexadoLed.ino
 * Multiplexado de la matriz de LEDs y creación de una
 * imagen virtual de la misma, que servirá para visualizar
 * con facilidad cualquier figura.
 */


byte pinFilas[3] = {26, 27, 28};
byte pinColumnas[9] = {3, 4, 10, 23, 24, 25, 9, 7, 6};

/*
 * boolean matrizLed[5][5];
 * Vamos a crear una imagen virtual de la matriz de LEDs,
 * para ello utilizamos un array de tipo booleano de dos
 * dimensiones (fila-Columna). 
 * Un 1 es encendido y un 0 apagado. Hemos dibujado una X
 */
boolean matrizLed[5][5]={{1,0,0,0,1},
                         {0,1,0,1,0},
                         {0,0,1,0,0},
                         {0,1,0,1,0},
                         {1,0,0,0,1}}; //matrizLed[fila][columna]

byte fila=0;       //la fila actual a encender en el multiplexado.

long millisInicialesLed=0;

void setup(){
  pinMatrizLedSalidas();
}

void loop(){
  multiplexaMatrizLed();
}

/************************************************* 
 *  Ahora vienen las funciones que hemos creado.
 *************************************************/

/*
 * pinMatrizLedSalidas()
 * Programa como salidas los 3 pines de las filas internas
 * y los 9 pines de las columnas
 */
void pinMatrizLedSalidas(){
  for (byte i=0; i<9; i++){
    pinMode(pinColumnas[i], OUTPUT);
  }
  for (byte i=0; i<3; i++){
    pinMode(pinFilas[i], OUTPUT);
  }
}

/*
 * multiplexaMatrizLed()
 * Cada 6 milisegundos llama a la función
 * multiplexadoFilasLed.
 */
void multiplexaMatrizLed(){
  if (millis() - millisInicialesLed > 6) {
    millisInicialesLed = millis();
    multiplexaFilasLed();
  }
}

/*
 * apagaMatrizLed()
 * Desactiva todos los pines tanto de las tres filas
 * como de las nueve columnas de la matriz de LEDS.
 */
void apagaMatrizLed(){
  for (byte i=0; i<3; i++){
    digitalWrite(pinFilas[i], LOW);
  }
  for (byte i=0; i<9; i++){
    digitalWrite(pinColumnas[i], HIGH);
  }
}

/*
 * multiplexaFilasLed()
 * Primero apaga toda los LEDs y después transfiere los 0 y 1
 * de la matriz virtual a los LEDs correspondiente.
 * Cada vez que se ejecuta (cada 6 mseg)se actualiza una sola
 * de las tres filas internas.
 * El código se puede simplificar utilizando "for" como veremos
 * posteriormente.
 * Recordamos los pines (fila columna) de los LEDs:
 *  (26-3)  27-23  26-4   27-24 (26-10)
 *   28-23 (28-24) 28-25 (28-9)  28-7
 *   27-4   26-6  (27-10) 28-6   27-3
 *   26-7  (26-9)  26-25 (26-24) 26-23
 *  (28-10) 27-9   28-3   27-25 (28-4)
 */
void multiplexaFilasLed(){
  apagaMatrizLed();
  if(fila==0){
    digitalWrite(26,HIGH);             //Activamos la fila 0.
    digitalWrite(3,!matrizLed[0][0]);  //Vamos transfiriendo
    digitalWrite(4,!matrizLed[0][2]);  //la imagen a los LEDs  
    digitalWrite(10,!matrizLed[0][4]);
    digitalWrite(23,!matrizLed[3][4]);
    digitalWrite(24,!matrizLed[3][3]);
    digitalWrite(25,!matrizLed[3][2]);
    digitalWrite(9,!matrizLed[3][1]);
    digitalWrite(7,!matrizLed[3][0]);
    digitalWrite(6,!matrizLed[2][1]);
  }
  else if(fila==1){
    digitalWrite(27,HIGH);             //Activamos la fila 1.
    digitalWrite(3,!matrizLed[2][4]);  //Vamos transfiriendo
    digitalWrite(4,!matrizLed[2][0]);  //la imagen a los LEDs
    digitalWrite(10,!matrizLed[2][2]);
    digitalWrite(23,!matrizLed[0][1]);
    digitalWrite(24,!matrizLed[0][3]);
    digitalWrite(25,!matrizLed[4][3]);
    digitalWrite(9,!matrizLed[4][1]);
    digitalWrite(7,1);
    digitalWrite(6,1);
  }
  else if(fila==2){
    digitalWrite(28,HIGH);             //Activamos la fila 2.
    digitalWrite(3,!matrizLed[4][2]);  //Vamos transfiriendo
    digitalWrite(4,!matrizLed[4][4]);  //la imagen a los LEDs
    digitalWrite(10,!matrizLed[4][0]);
    digitalWrite(23,!matrizLed[1][0]);
    digitalWrite(24,!matrizLed[1][1]);
    digitalWrite(25,!matrizLed[1][2]);
    digitalWrite(9,!matrizLed[1][3]);
    digitalWrite(7,!matrizLed[1][4]);
    digitalWrite(6,!matrizLed[2][3]);
  }
  fila++;
  if(fila==3) fila=0;
}

Para simplificar esta última función usando la instrucción "for" tenemos que declarar, al inicio del programa, dos nuevos array de 3x9. En ellos relacionamos la fila (Y) y la columna (X) de cada LED (5x5) con su posición en la matriz interna:
/*
 * coorY y coorX son dos array de 3x9 que representan la
 * fila (Y) y columna (X) de cada uno de los LED (matriz de 5x5)
 * en relación con su posición en la matriz interna de 3x9.
 */
byte coorY [3][9] = {{0,0,0,3,3,3,3,3,2},
                     {2,2,2,0,0,4,4,0,0},
                     {4,4,4,1,1,1,1,1,2}};                 
byte coorX [3][9] = {{0,2,4,4,3,2,1,0,1},
                     {4,0,2,1,3,3,1,0,0},
                     {2,4,0,0,1,2,3,4,3}};

Utilizando estos datos ya podemos incluir un "for" que simplifica considerablemente el código:
void multiplexaFilasLed(){
  apagaMatrizLed();
  digitalWrite(pinFilas[fila],HIGH);
  for (byte i=0; i<9; i++){
    digitalWrite(pinColumnas[i], !matrizLed[coorY[fila][i]][coorX[fila][i]]);
  }
  fila++;
  if(fila==3) fila=0;
}


En este programa se visualiza una X en la matriz de LEDs. Lógicamente, cambiando los ceros y unos del array matrizLed podemos ver la figura o las letras y números que deseemos.


No hay comentarios:

Publicar un comentario