Matriz 8x8 con motivo de Navidad

Hola, hoy estaré realizando una actualización a la matriz de led 8x8 que posiblemente ya conozcan de mis otros post http://electgpl.blogspot.com.ar/2013/11/matriz-8x8-mensaje-con-desplazamiento.html
En este caso, no hay nada nuevo, solo he agregado unas secuencias de animación, texto scroll y dibujos estáticos.
La idea era montarla en el árbol navideño junto a unas tiras de led RGB para hacer una navidad mas tecnológica.
Me queda como pendiente (aunque no tengo demasiado tiempo para ello) realizar una función audioritmica a esta matriz que realice figuras geometrías o algo asimilar en función del nivel de ruido ambiente, para aprovechar el resto de los pines y los canales analógicos de este microcontrolador PIC16F883.
En este caso el hardware es super simple, realizado a la mínima cantidad de componentes y alimentado con 3V a partir de dos pilas AA.
NOTA: el pack de 8 resistencias de 220 Ohms porque esta funcionando con 3V, si lo hacen funcionar con 5V deben aumentar a 470 Ohms para no sobrecargar las salidas del puerto.
O bien lo ideal podría ser poner inmediatamente a la salida de cada puerto (el A y el C) 8 resistencias de 220 o dejar solo un pack de 8 para un puerto y poner 8 diodos de conmutación 1N4148 para que la corriente cuando una salida es 1 y la otra 0 no vuelva al mismo puerto. Son algunas precauciones, pero igual si ponen el valor de resistencia adecuada no tendrán problemas eléctricos.
También he aprovechado el puerto B para poner un puerto ICSP y poder programar en circuito a este microcontrolador, por dos motivos, el primero es que las secuencias de la matriz suelen modificarse a menudo para probar cual queda mejor, y es un poco tedioso sacar el microcontrolador del zócalo y el otro motivo es que por el tamaño de este microcontrolador PDIP se me ocurrió realizarlo en encapsulado SOIC para que ocupe menos espacio, y siempre que utilicen SOIC es mas sencillo programarlo por ICSP.




Ahora hablaremos del programa, pero para ello primero lo presentare aquí.

  1. #include <16F883.h>
  2. #use delay(int=4000000)
  3. #define LARGO_FN 79                                //Longitud de Frase de Navidad
  4. int const FelizNavidad[LARGO_FN+16]={              //Vector de Frase de Navidad
  5. 0,0,0,0,0,0,0,0,                                   //    8 espacios          
  6. 0x7F, 0x09, 0x09, 0x01, 0x01, 0x00,                // F
  7. 0x38, 0x54, 0x54, 0x54, 0x18, 0x00,                // e
  8. 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,                // l
  9. 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,                // i
  10. 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,                // z
  11. 0x00, 0x00, 0x00,                                  //    3 espacios
  12. 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,                // N
  13. 0x20, 0x54, 0x54, 0x54, 0x78, 0x00,                // a
  14. 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,                // v
  15. 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,                // i
  16. 0x38, 0x44, 0x44, 0x48, 0x7F, 0x00,                // d
  17. 0x20, 0x54, 0x54, 0x54, 0x78, 0x00,                // a
  18. 0x38, 0x44, 0x44, 0x48, 0x7F, 0x00,                // d
  19. 0x00, 0x5F, 0x00, 0x00,                            // !
  20. 0,0,0,0,0,0,0,0,                                   //    8 espacios  
  21. };
  22. int const ArbolNavidad[8]={                        //Vector del dibujo Arbol
  23. 0x20, 0x30, 0x3C, 0xFF, 0xFF, 0x3C, 0x30, 0x20
  24. };
  25. int const EstNavidad[16][8]={                      //Vector animado
  26. {0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81},
  27. {0x02, 0xc2, 0x24, 0x18, 0x18, 0x24, 0x43, 0x40},
  28. {0x04, 0x42, 0xa4, 0x18, 0x18, 0x25, 0x42, 0x20},
  29. {0x08, 0x04, 0x64, 0x98, 0x19, 0x26, 0x20, 0x10},
  30. {0x30, 0x08, 0x25, 0x59, 0x9a, 0xa4, 0x10, 0x0c},
  31. {0xe1, 0x11, 0x09, 0x3a, 0x5c, 0x90, 0x88, 0x87},
  32. {0x06, 0xf2, 0x8a, 0x3a, 0x5c, 0x51, 0x4f, 0x60},
  33. {0x08, 0x34, 0x4a, 0xba, 0x5d, 0x52, 0x2c, 0x10},
  34. {0x00, 0x18, 0x3c, 0x7e, 0x7e, 0x3c, 0x18, 0x00},
  35. {0x00, 0x3c, 0x34, 0x3c, 0x3c, 0x34, 0x3c, 0x00},
  36. {0x78, 0x3c, 0xf7, 0x3c, 0x3c, 0xf7, 0x3c, 0x78},
  37. {0x1e, 0xbc, 0x77, 0x3c, 0x3c, 0x77, 0xbc, 0x1e},
  38. {0x78, 0x3c, 0xf7, 0x3c, 0x3c, 0xf7, 0x3c, 0x78},
  39. {0x1e, 0xbc, 0x77, 0x3c, 0x3c, 0x77, 0xbc, 0x1e},
  40. {0x78, 0x3c, 0xf7, 0x3c, 0x3c, 0xf7, 0x3c, 0x78},
  41. {0x1e, 0xbc, 0x77, 0x3c, 0x3c, 0x77, 0xbc, 0x1e}
  42. };
  43. byte const bitMask[8]={1,2,4,8,16,32,64,128};      //Mascara
  44. int i,j,k,x;                                       //Variables contadores
  45. void fraseNavidad(int1 Neg){
  46.    for(i=0;i<LARGO_FN+8;i++){                      //Recorrido de tabla
  47.       for(k=0;k<20;k++){                           //Refresco de matriz
  48.          for(j=0;j<8;j++){                         //Barrido de columnas
  49.             output_a(~bitMask[j]);                 //Columnas ponderadas
  50.             if(Neg)                                //Negativo
  51.                output_c(~FelizNavidad[j+i]);       //Desplazamiento de tabla
  52.             else                                   //Directo
  53.                output_c(FelizNavidad[j+i]);        //Desplazamiento de tabla
  54.             delay_us(500);                         //Demora de multiplexado
  55.          }  
  56.       }
  57.    }
  58. }
  59. void animNavidad(){
  60.    for(i=0;i<16;i++){                              //Cambia de subVector
  61.       for(k=0;k<30;k++){                           //Persistencia
  62.          for(j=0;j<8;j++){                         //Barrido de columnas
  63.             output_a(~bitMask[j]);                 //Columnas ponderadas
  64.             output_c(EstNavidad[i][j]);            //Desplazamiento de tabla
  65.             delay_us(600);                         //Demora de multiplexado
  66.          }  
  67.       }
  68.    }
  69. }  
  70. void dibujoArbol(int1 Neg){
  71.    for(k=0;k<50;k++){                              //Persistencia
  72.       for(j=0;j<8;j++){                            //Barrido de filas y columnas
  73.          output_a(~bitMask[j]);                    //Columnas ponderadas
  74.          if(Neg)                                   //Negativo
  75.             output_c(~ArbolNavidad[j]);            //Desplazamiento de tabla
  76.          else                                      //Directo
  77.             output_c(ArbolNavidad[j]);             //Desplazamiento de tabla
  78.          delay_us(700);                            //Demora de multiplexado
  79.       }  
  80.    }  
  81. }
  82. void main(){    
  83.    while(TRUE){                                    //Funcion Principal Repetitiva
  84.       for(x=0;x<3;x++){                            //Arbol de Navidad 3 veces
  85.          dibujoArbol(FALSE);                       //Arbol de Navidad
  86.          dibujoArbol(TRUE);                        //Arbol de Navidad Invertido
  87.       }
  88.       fraseNavidad(FALSE);                         //Frase de Navidad
  89.       for(x=0;x<3;x++){                            //Arbol de Navidad 3 veces
  90.          dibujoArbol(FALSE);                       //Arbol de Navidad
  91.          dibujoArbol(TRUE);                        //Arbol de Navidad Invertido
  92.       }
  93.       for(x=0;x<3;x++){                            //Animacion de Navidad 3 veces
  94.          animNavidad();                            //Animacion de Navidad
  95.       }      
  96.       fraseNavidad(TRUE);                          //Frase de Navidad Invertida
  97.    }
  98. }

Bueno lo primero que notamos a primera vista es que hay mucho vector con variables de 8 bit, esto es porque la matriz es de 8x8 y realizamos grupos de 8 variables de 1byte para conformar los 64 puntos de la matriz.
Para realizar los dibujos y letras he utilizado una matriz virtual online que permite encender y apagar cada punto y automáticamente genera el código en hexadecimal y binario.

El programa principal mantiene el llamado a varias funciones que cada una realiza una secuencia o animación diferente en la matriz, como pueden ver, alguna de ellas poseen lazos de iteracion for para llamar la función varias veces (todo esto es customizable por el desarrollador).
Lo principal son las funciones que hablaremos ahora:

La función fraceNavidad(); es una función que llama al vector "FelizNavidad" que el mismo posee la frase "Feliz Navidad!", el proceso para el multiplexado y scroll lo pueden ver en el post de la matriz de 8x8 que he dejado al principio. Luego la función tiene como argumento una variable de 1bit que cumple la función de flag, es decir puede estar en true o en false, y este estado tiene acción en un if dentro de esta función que lo que hace es agregar en el vector el símbolo ~ que invierte el valor que lee en el vector, es decir si decía 00001100 al invertirlo dirá 11110011, esto hace que podamos ver la frase en negativo.

La función animaNavidad(); es una función similar a la anterior pero en esta no se produce el efecto de scroll ya que no hay texto que leer, pero en cambio se utiliza un vector de dos dimensiones "EstNavidad" que posee cada registro de 8 variables de 8 bit para realizar diferentes "dibujos" o "animaciones" en la matriz, el for de iteracion va recorriendo cada variable de 8 bit de cada por cada registro para formar el dibujo.

La función dibujoArbol(); es la función mas sencilla, ya que solo tiene un registro para dibujar un árbol o pino de navidad y al igual que la función de texto posee la inversión a negativo del dibujo para darle un efecto extra.




22 comentarios:

  1. como se puede hacer para trabajar el efecto de desvanecer pero q este multiplexado con 795

    ResponderBorrar
    Respuestas
    1. Hola, si bien el 74595 no tiene salidas PWM (que seria lo ideal para el fade), podes "jugar" con los tiempos de habilitación del latch de salida, es decir, usualmente controlas el latch para que una vez que enviaste los 8 bit serie y se encuentra cada uno en su salida paralela, recién ahí habilitas el latch y mostras los 8 bit, de esa forma no se ve el traspaso de bit a bit de serie a paralelo. Pero si ese latch lo haces rápido (activas y desactivas la salida) a una velocidad rápida podes dar ese efecto de poco encendido, podes tratar de enviar PWM en ese control, necesitas un control mucho mayor sobre el 74595 pero se puede hacer.
      En resumen podes aplicar PWM al pin de latch del 74595, si aplicas PWM a un tiempo menor que el que se switchean las 8 salidas del 74595, vas a aplicar una variación de brillo a todos los leds por igual, lo ideal es que el brillo se aplique a cada led por individual, para eso tu pwm en el latch tiene que ser mas rápido que el switcheo de leds, o bien si queres verlo de otra manera, envias el led 1 al 74595 y los otros 7 apagados y ahí modificas pwm del latch (0000 0001 + PWM para led 1), después lo haces para los demás (0000 0010 + PWM para led 2) y así, si es suficientemente rápido podes darle el efecto individual a cada led. Asi lo hacen con arduino al menos.
      Saludos.

      Borrar
  2. Excelente proyecto. Mem considero un novato todavia pero gracias a tu blog voy asimilando conocimiento poco a poco. Un fuerte abrazo!

    ResponderBorrar
  3. amigo con programa realizas el codigo

    ResponderBorrar
    Respuestas
    1. Hola, esta compilado con CCS dentro del IDE PCWH. http://www.ccsinfo.com/ccsfreedemo.php
      Saludos.

      Borrar
  4. Hola,
    El projecto esta muy Bueno, hace ya un tiempo hice algo parecido ,despues encontre tu web y reutilize parte de tu codgo,no soy esperto ni nada de eso solo un hoobista de CCS .
    aqui les dejo el enlase de mi projecto y si les interesa el codigo dejarme saber .
    gracias por compartir tus conocimientos.
    este es el projecto en protobord:
    https://www.youtube.com/watch?v=FlxRZNscBMw&t=3s
    aqui ya terminado:
    https://www.youtube.com/watch?v=3geIbQzH6Xc.

    ResponderBorrar
    Respuestas
    1. Muy buenos los vídeos, muy prolijo!, Si podes compartinos el firmware así lo miramos!
      Saludos.

      Borrar
    2. hola,
      trate de subir el firware pero me sale un warning que solo me hacepta 4096 Characteres.
      si sabes otra forma para subirlo dejame saber .

      Estoy trabajando en una matriz de 24 coluumnas ya termine el hardware ,cuando la
      termine la comparto
      Saludos.

      Borrar
    3. Hola, si claro, es probable porque llegaste al limite de la memoria, tenes que usar o bien un microcontrolador mas grande (mas memoria) o una memoria externa EEPROM y cargar la tabla ahi dentro, luego leerla de la misma forma que lees la interna.
      Saludos.

      Borrar
    4. disculpa no me supe explicar ,me refería a subir el firmware al foro para compartirlo.

      Borrar
    5. No lo tengo echo, tendría que hacer el desarrollo nuevo para otro MCU, ahora mismo no lo puedo hacer la verdad, tendrías que darme tiempo porque tengo varias cosas encoladas. Si queres encararlo vos como modificación yo te puedo dar soporte.
      Saludos

      Borrar
  5. de nuevo estamos hablando de cosas diferentes ,jejejeje
    me refiero al firmware ,a mi código ,al que viste en el vídeo del enlace que deje en post anteriores.
    mi código es el que trate de subirlo ha este hilo para compartirlo con otros usuarios y de paso me le echas una mirada y me dices , pero no pude porque el html del blog no tiene suficiente memoria y me da un error .( warning que solo me acepta 4096 Characteres).
    Saludos

    ResponderBorrar
    Respuestas
    1. Hola! aa perdon, no entendi! estoy con la cabeza quemada ultimamente.
      subilo a Pastebin, so subo todo ahi como backup de codigo y para compartir.
      Saludos!

      Borrar
    2. ahora si me entendiste colega,
      es hora de refrescar la cabeza o vas a fundir la maquina.
      ya ablando en serio hay les dejo el firmware de la matriz de 8x8, la fabrique con el fin de ponerla detaras del auto para indicar cuando freno y como indicador de direccion ,pero ya sabes somos del tipo de persona que no nos conformamos y dije cuando no este frenando ni doblando la matriz va a estar apagada "!Que desperdicio"y decidí agregarle los anuncios y claro que la del video es solo experimental para probar el firmware ,la Real es mas grande y luce Very Nice.
      Saludos.
      https://pastebin.com/LuhjSiMv

      Borrar
    3. Hola! ahi lo vi! buenísimo tu firmware, muy completo!! Gracias por el aporte!!
      Saludos.

      Borrar
  6. Hola ,como dije antes estuve trabajando en el projecto de hacer una matriz de 8x24 y ya casi la termino, hay les dejo un link para que la puedan ver funcionando.
    el firmware bastante parecida a la de 8x8 no muchos cambios solo en la forma que enciendo las colummas que tuve que hacer una funcion nueva ,ya que probe con el metodo de sebastian y no me funciono.hay les dejo el codigo:
    void write_data(unsigned int number){ //FUNCION PARA ESCRBOR LOS DIGITOS EN EL DISPLAY
    for(int32 j= 0x800000;j>0;j=j>>1){
    //for(int32 j= 0x4000000;j>0;j= j>>1){
    if(number & j) //and ligico entre j y number para detectar bit a bit 0 o 1 de number
    output_high(data_pin);
    else
    output_low(data_pin);
    output_high(clock_pin);
    output_low(clock_pin);
    }
    output_high(latch_pin);
    output_low(latch_pin);

    //delay_ms(100);
    }

    int32 filas(int32 ref){
    switch(ref){
    //case 0: return 0xffffff;
    case 0: return 0x3fffffe;
    case 1: return 0x3FFFFFD;
    case 2: return 0x3FFFFFb;
    case 3: return 0x3FFFFF7;
    case 4: return 0x3FFFFEF;
    case 5: return 0x3FFFFDF;
    case 6: return 0x3FFFFBF;
    case 7: return 0x3FFFF7F;
    case 8: return 0x3FFFEFF;
    case 9: return 0x3FFFDFF;
    case 10: return 0x3FFFBFF;
    case 11: return 0x3FFF7FF;
    case 12: return 0x3FFEFFF;
    case 13: return 0x3FFDFFF;
    case 14: return 0x3FFBFFF;
    case 15: return 0x3FF7FFF;
    case 16: return 0x3FEFFFF;
    case 17: return 0x3FDFFFF;
    case 18: return 0x3FBFFFF;
    case 19: return 0x3F7FFFF;
    case 20: return 0x3EFFFFF;
    case 21: return 0x3DFFFFF;
    case 22: return 0x3BFFFFF;
    case 23: return 0X37FFFFF;
    case 24: return 0x02FFFFFF;
    case 25: return 0x01FFFFFF;
    }
    }
    y aqui el link:
    https://youtu.be/DfsPXaMLpcE

    ResponderBorrar
    Respuestas
    1. Muy bueno el vídeo! te quedo muy bien!!, armaste un set de caracteres para ir escribiendo de forma dinámica, o lo tenes en una tabla?
      Viste el otro proyecto que tengo, el de la matriz de 8x32?
      Saludos.

      Borrar
  7. Hola Sebastian ,
    Disculpa Estaba bien Ocupado con el trabajo y no tuve tiempo ni para revisar los EMails.
    Muchas Gracias por tu comentario, Los caracteres los tengo en una tabla ,estoy pensando en hacer una funcion que me pida lo que quiero que mustre la matriz, lo convierta en exadecimal y rellene la tabla porque de forma manual es un poco pesado ,pero ahi vamos eso es para cuando tenga mas tiempo.
    Todo el programa es muy parecido a los demas la diferrencia solo es en la forma de despalazar las columnas ,por mas que trate con tus funciones no me trabajo y decidi hacer una .
    la funcion es sencilla , en el switch estan las clumn definidas y write_data lo que hace es una comparacion bit a bit para saber cuando estoy en presencia de un "0" o de un "1".
    ya se que de esa forma consumo mas ciclos de maquina pero fue haci como pude.
    El hardware trabaje con un high-side switching(UDN22981) y un 74H595 para manejar la corriente que pasa por la matriz y aislarla totalmente del Microcontrolador.
    Y bueno eso es todo , espero mas adelante vengan mas projectos .
    Saludos.

    ResponderBorrar
  8. Este comentario ha sido eliminado por el autor.

    ResponderBorrar