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í.
- #include <16F883.h>
- #use delay(int=4000000)
- #define LARGO_FN 79 //Longitud de Frase de Navidad
- int const FelizNavidad[LARGO_FN+16]={ //Vector de Frase de Navidad
- 0,0,0,0,0,0,0,0, // 8 espacios
- 0x7F, 0x09, 0x09, 0x01, 0x01, 0x00, // F
- 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, // e
- 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00, // l
- 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00, // i
- 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, // z
- 0x00, 0x00, 0x00, // 3 espacios
- 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, // N
- 0x20, 0x54, 0x54, 0x54, 0x78, 0x00, // a
- 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00, // v
- 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00, // i
- 0x38, 0x44, 0x44, 0x48, 0x7F, 0x00, // d
- 0x20, 0x54, 0x54, 0x54, 0x78, 0x00, // a
- 0x38, 0x44, 0x44, 0x48, 0x7F, 0x00, // d
- 0x00, 0x5F, 0x00, 0x00, // !
- 0,0,0,0,0,0,0,0, // 8 espacios
- };
- int const ArbolNavidad[8]={ //Vector del dibujo Arbol
- 0x20, 0x30, 0x3C, 0xFF, 0xFF, 0x3C, 0x30, 0x20
- };
- int const EstNavidad[16][8]={ //Vector animado
- {0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81},
- {0x02, 0xc2, 0x24, 0x18, 0x18, 0x24, 0x43, 0x40},
- {0x04, 0x42, 0xa4, 0x18, 0x18, 0x25, 0x42, 0x20},
- {0x08, 0x04, 0x64, 0x98, 0x19, 0x26, 0x20, 0x10},
- {0x30, 0x08, 0x25, 0x59, 0x9a, 0xa4, 0x10, 0x0c},
- {0xe1, 0x11, 0x09, 0x3a, 0x5c, 0x90, 0x88, 0x87},
- {0x06, 0xf2, 0x8a, 0x3a, 0x5c, 0x51, 0x4f, 0x60},
- {0x08, 0x34, 0x4a, 0xba, 0x5d, 0x52, 0x2c, 0x10},
- {0x00, 0x18, 0x3c, 0x7e, 0x7e, 0x3c, 0x18, 0x00},
- {0x00, 0x3c, 0x34, 0x3c, 0x3c, 0x34, 0x3c, 0x00},
- {0x78, 0x3c, 0xf7, 0x3c, 0x3c, 0xf7, 0x3c, 0x78},
- {0x1e, 0xbc, 0x77, 0x3c, 0x3c, 0x77, 0xbc, 0x1e},
- {0x78, 0x3c, 0xf7, 0x3c, 0x3c, 0xf7, 0x3c, 0x78},
- {0x1e, 0xbc, 0x77, 0x3c, 0x3c, 0x77, 0xbc, 0x1e},
- {0x78, 0x3c, 0xf7, 0x3c, 0x3c, 0xf7, 0x3c, 0x78},
- {0x1e, 0xbc, 0x77, 0x3c, 0x3c, 0x77, 0xbc, 0x1e}
- };
- byte const bitMask[8]={1,2,4,8,16,32,64,128}; //Mascara
- int i,j,k,x; //Variables contadores
- void fraseNavidad(int1 Neg){
- for(i=0;i<LARGO_FN+8;i++){ //Recorrido de tabla
- for(k=0;k<20;k++){ //Refresco de matriz
- for(j=0;j<8;j++){ //Barrido de columnas
- output_a(~bitMask[j]); //Columnas ponderadas
- if(Neg) //Negativo
- output_c(~FelizNavidad[j+i]); //Desplazamiento de tabla
- else //Directo
- output_c(FelizNavidad[j+i]); //Desplazamiento de tabla
- delay_us(500); //Demora de multiplexado
- }
- }
- }
- }
- void animNavidad(){
- for(i=0;i<16;i++){ //Cambia de subVector
- for(k=0;k<30;k++){ //Persistencia
- for(j=0;j<8;j++){ //Barrido de columnas
- output_a(~bitMask[j]); //Columnas ponderadas
- output_c(EstNavidad[i][j]); //Desplazamiento de tabla
- delay_us(600); //Demora de multiplexado
- }
- }
- }
- }
- void dibujoArbol(int1 Neg){
- for(k=0;k<50;k++){ //Persistencia
- for(j=0;j<8;j++){ //Barrido de filas y columnas
- output_a(~bitMask[j]); //Columnas ponderadas
- if(Neg) //Negativo
- output_c(~ArbolNavidad[j]); //Desplazamiento de tabla
- else //Directo
- output_c(ArbolNavidad[j]); //Desplazamiento de tabla
- delay_us(700); //Demora de multiplexado
- }
- }
- }
- void main(){
- while(TRUE){ //Funcion Principal Repetitiva
- for(x=0;x<3;x++){ //Arbol de Navidad 3 veces
- dibujoArbol(FALSE); //Arbol de Navidad
- dibujoArbol(TRUE); //Arbol de Navidad Invertido
- }
- fraseNavidad(FALSE); //Frase de Navidad
- for(x=0;x<3;x++){ //Arbol de Navidad 3 veces
- dibujoArbol(FALSE); //Arbol de Navidad
- dibujoArbol(TRUE); //Arbol de Navidad Invertido
- }
- for(x=0;x<3;x++){ //Animacion de Navidad 3 veces
- animNavidad(); //Animacion de Navidad
- }
- fraseNavidad(TRUE); //Frase de Navidad Invertida
- }
- }
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 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.
muy buen proyecto
ResponderBorrarGracias!, Saludos!
Borrarcomo se puede hacer para trabajar el efecto de desvanecer pero q este multiplexado con 795
ResponderBorrarHola, 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.
BorrarEn 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.
Excelente proyecto. Mem considero un novato todavia pero gracias a tu blog voy asimilando conocimiento poco a poco. Un fuerte abrazo!
ResponderBorrarGracias!, me alegra! Saludos!
Borraramigo con programa realizas el codigo
ResponderBorrarHola, esta compilado con CCS dentro del IDE PCWH. http://www.ccsinfo.com/ccsfreedemo.php
BorrarSaludos.
Hola,
ResponderBorrarEl 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.
Muy buenos los vídeos, muy prolijo!, Si podes compartinos el firmware así lo miramos!
BorrarSaludos.
hola,
Borrartrate 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.
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.
BorrarSaludos.
disculpa no me supe explicar ,me refería a subir el firmware al foro para compartirlo.
BorrarNo 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.
BorrarSaludos
de nuevo estamos hablando de cosas diferentes ,jejejeje
ResponderBorrarme 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
Hola! aa perdon, no entendi! estoy con la cabeza quemada ultimamente.
Borrarsubilo a Pastebin, so subo todo ahi como backup de codigo y para compartir.
Saludos!
ahora si me entendiste colega,
Borrares 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
Hola! ahi lo vi! buenísimo tu firmware, muy completo!! Gracias por el aporte!!
BorrarSaludos.
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.
ResponderBorrarel 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
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?
BorrarViste el otro proyecto que tengo, el de la matriz de 8x32?
Saludos.
Hola Sebastian ,
ResponderBorrarDisculpa 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.
Este comentario ha sido eliminado por el autor.
ResponderBorrar