Introducción

Byteman
Es muy común ver anuncios que utlizan luces led, ya sea desde los más basicos que solo tienen las letras formadas por leds, hasta unos muy sofisticados que tienen varias animaciones, con esa idea en mente decidí ver qué tan fácil o difícil resulta construir uno desde cero, asi es como terminé creando a Byteman, su diseño es básicamente un rectángulo con brazos y piernas, algo asi como los tipicos monos de circulos y palitos que dibujamos en el kinder, pero su simpleza es parte de su carisma, eso y el hecho de que es de la vieja escuela, por si no lo has notado, su nombre se conforma de la palabra byte y man o sea que es un hombrecillo virtual de 8 bits.
Antes de poner manos a la obra, hay algo de vital importancia, y es que este proyecto no está basado en arduino, por lo tanto, no cuenta con librerias mágicas ni módulos shield, también es necesario contar con un programador de picmicros, el código está creado en lenguaje de bajo nivel, la razón de porqué está escrito en ensamblador es porque cada animación ocupa un registro en la ROM por lo tanto, es importante optimizar el código, con esto conseguimos tener más animaciones comparado con un lenguaje de alto nivel.

IMPORTANTE:

Este proyecto utiliza un microcontrolador de microchip, por lo que es necesario tener un programador de picmicros.


Si no cuentas con un programador pero quieres tener tu Byteman o lo que necesitas, es mostrar tus animaciones sin la necesidad de pasar por todo el proceso de construcción e implementación del código, tengo la solución para tí ver más información....

Licencia de Creative Commons
Byteman by E. David Rojas Serrano is licensed under a Creative Commons Reconocimiento-CompartirIgual 4.0 Internacional License.
Creado a partir de la obra en www.edx-twin3.org/byteman.html.
Puede hallar permisos más allá de los concedidos con esta licencia en www.edx-twin3.org/

Teoria

Barrido
Lo primero que tenemos que hacer es encontrar una manera de dibujar una imágen en la matriz led de 8x8, la opción que me viene a la mente es basarnos en como lo hacen los televisores, el primer paso es el barrido esto significa desmenuzar la imágen linea por linea y dibujarla de la misma manera en la matriz.

En la imágen puedes ver como se va dibujando linea por linea la imágen, por cierto cabe mencionar, que el sentido de barrido de la imágen no importa en la práctica, pero si a la hora de implementar el circuito, a lo que me refiero es que puedes empezar a dibujar de arriba para abajo o viceversa y no afecta en nada la imagen, lo que afectaría es que el circuito empieze desde abajo pero tu secuencia corresponda a la de arriba, asi que mucho ojo con eso.

Por comodidad y en aras de la educación por ahora te recomiendo que sigas mi secuencia, una vez que sepas lo que haces puedes decidir cuál elegir, que insisto, no vas a notar ningún cambio significativo.

Si esto lo implementaras en cualquier microcontrolador no verias nada, y eso se debe a que el barrido es directamente proporcional al tiempo de ejecución de la instrucción, dicho de otra forma, el microcontrolador PIC16F886 tiene una frecuencia de trabajo de 4 Mhz, debido a su ciclo Fetch cada instrucción la ejecuta en 1µseg, por lo tanto, esas ocho secuencias le toma solo 8μseg, seguramente ya has de haber encontrado una solución basada en un loop para ser capaz de ver la imágen, pues lamento decirte que no es tan fácil, porque si te basaras en loops solo serias capaz de hacer animaciones secuenciales, eso estaría bien si por ejemplo haces algun cortometraje pero si quisieras hacer animaciones aleatoreas mediante el loop no serias capaz de lograrlo.

Por lo tanto, la solución es "retener" el mismo cuadro más de una vez, con retener me refiero a repetir la animación por más tiempo.


Refresco
Si te fijas, a esta imágen le toma exactamente el doble de tiempo completar la imágen a comparación de la de arriba, esto se debe a que estoy "reteniendo" el mismo cuadro por más tiempo, pero ambas imágenes tienen el mismo ciclo de cambio de cuadro a esto se le conoce como refresco o refresh en inglés.

El refresco es la frecuencia con la cual ocurre un cambio de cuadro, se mide en herzios, para calcular el refresco solo debes recordar que la frecuencia es inversamente proporcionales al periodo, por ejemplo, la imágen de arriba tiene un periodo de .5 segundos por lo tanto, su refresco es de 2 Hz, mientras que la segunda imágen tiene un periodo de 1 segundo por lo tanto, su refresco es de 1 Hz, entonces ¿un refresco con una frecuencia alta termina de dibujar la imágen más rápido en comparación de un refresco con una frecuencia más lenta?, la respuesta es NO.

¿Confundido?, ¿ entonces por que estamos "reteniendo" la imágen? pues bien, no te confundas, voy a volverlo a explicar para que no queden dudas.
Un refresco rápido no significa que sea mejor por ejemplo, el refresco real de la primer imágen es de 125kHz puesto que no estamos "reteniendo" el cuadro de la animación, esa frecuencia no la puede detectar el ojo humano, por tal motivo es necesario "retener" el cuadro por más tiempo. Ahora bien, si a la primer imágen le dieramos un tiempo de "retención" de 1 segundo a cada cuadro, entonces cada 8µsegundos la pantallita estaría cambiando, pero dado que lo estamos "reteniendo" veríamos el mismo cuadro, dicho de otra forma el refresco debe de pasar 125 mil veces antes de avanzar al siguiente cuadro, por lo tanto tal vez nos convendría un refresco más lento.

El tiempo de "retención" de cada imágen tiene que ser exactamente el mismo, de lo contrario la animación no se veria fluida, el tiempo exacto de retención no lo tengo, lo que sé es que la televisión recibe el audio en AM y el video en FM por lo tanto agarré frecuencias del orden de los kHz, pero eso ya lo veremos más adelante por ahora lo importante es entender lo básico.

Refresco
Por fin, lo hemos logrado ahora nuestra imágen es visible, vamos a recordar los pasos:

• El primer paso corresponde al barrido que no es otra cosa que mandar la secuencia de leds a encender.


• El segundo paso es "retener" esa imágen en pantalla para que el ojo sea capaz de verlo.


• El tercer paso es hacer un refresco a la imágen para pasar a la siguiente secuencia de la animación.




Esto son practicamente todos los pasos necesarios para mostrar imágenes en nuestra pantalla, si por algún motivo todavía no tienes claro todos los pasos no te preocupes, cuando estemos programando el algoritmo te darás cuenta de su funcionamiento, por ahora creo que ya fue suficiente de teoria y es hora de pasar al diseño del hardware.

Por cierto aprovechando que tenemos un pequeño receso antes de continuar, no se te olvide sugerir esta página en facebook, compartirla en tu círculo de g+ o bien, twitearla (espero que se escriba asi), los botones se encuentran en la parte inferior de la página.

Hardware

Diseñé el hardware para que fuera capaz de desempeñar los tres pasos anteriores.
El barrido va ser controlado por el microcontrolador.
La retención va a estar controlada por el microcontrolador.
El refresco lo controla el demultiplexor.

Esquematico

Lista de componentes:


• Microcontrolador (PIC16F886)
• Demultiplexor 3-a-8 (74HCT138D)
• Regulador de voltaje (LM7805)
• Matriz led 8x8 catodo a renglón (GMM2308W)
• 8 resistencias de 120 Ω @ 1/4 watt
• 1 resistencia 10kΩ @ 1/4 watt
• 8 diodos de recuperáción rapida (1N5819)
• Capacitor electrolitico de 1µF @ 16 Volts
• Pila o bateria de 9 Volts






El diagrama de conexión está creado en diptrace, presiona sobre la imágen para descargarlo.
La matriz led está creada a partir de dos headers por lo tanto, a la hora de pasarlo al pcb solo revisa las dimensiones que se encuentran en la hoja de datos, por último el header llamado TOP corresponde a la parte superior y el que se llama DOWN es la parte inferior, a que no te lo hubieras imaginado.

Circuito
 Por parte del hardware lo importante es lo siguiente:
 •Las secuencias de las animaciones salen por el puerto A del microcontrolador por lo tanto, debes de configurarlas como salidas digitales, el registro 0x85 = 0x00, y no olvides configurar los registros ANSELX 0x188 y 0x189.
 •El demultiplexor está controlado por los 3 LSB del puerto C por lo tanto el puerto C, debe de tener una configuración de la forma 0xF8, o 0x00 para mayor facilidad.
 •La frecuencia de trabajo del microcontrolador es de 4Mhz con el oscilador interno, no es necesario subirlo a 8Mhz ni tampoco utilizar un cristal.
 •Ten cuidado con la dirección de los diodos, recuerda que el catodo se dirije a las salidas del demultiplexor.
 •A la hora de conectar la matriz recuerda que el pin uno corresponde a la parte inferior, si pones la matriz al reves no va a funcionar.

 Aquí les dejo una imagen de cómo me quedo, tiene más componentes de los necesarios, pero es porque en esta protoboard tenia otros proyectos lo importante es que se ve la matriz led al centro, el microcontrolador está del lado superior izquierdo y el demultiplexor se encuentra debajo del microcontrolador, se pueden ver las resistencias y los diodos, asi como el capacitor en paralelo con la fuente.

Software

Una vez que ya tenemos claro como se dibujan imágenes en la matriz led y ya teniendo el hardware listo, ya solo queda programar el código.

Matriz Led Studio
Lo primero que tenemos que hacer es crear nuestra animación, puede ser una simple figurita sin movimiento, o bien, algo un poco más sofisticado, ya depende de ti.
Para diseñar las animaciones recomiendo que utilicen el siguiente software:
Este programa es gratuito, está especialmente diseñado para trabajar con matrices de todo tipo desde 7x7 hasta 64x64, ofrece herramientas como flips, mirrors, gradientes, figuras geométricas y demás opciones que te pueden ser de gran utilidad a la hora de modelar tus animaciones.
Cuenta con varias opciones de exportación, soporta configuraciones little indian y big indian, macros, y una cantidad de opciones que no he encontrado en ningún otro software libre de este tipo.
Una de las características que más me ha gustado es el soporte para exportar en formato ensamblador de microchip, ahorrando horas de trabajo.


Exportacion
Ya que hayas terminado tu animación, expórtalo presionando F3

Yo utilizo el formato pequeño indio, por lo tanto, el LSB está a la derecha.

La animación se desplaza de arriba para abajo, ¿ recuerdas que lo habia comentado al principio?.

Los números se van a agrupar por bytes (8 bits).

Cada linea de salida establécelo en frame.

El formato de número no es importante, pero recomiendo ponerlo en hexadecimal.


Si tienes alguna duda presiona sobre la imágen para verla más grande.

Voy a dejar mi archivo de animación para que te sirva de guia: byteman.leds

Te recomiendo que tu animación por ahora sea menor de 10 cuadros, una vez que sepas como funciona el motor ya puedes hacer animaciones más grandes, entonces vamos a lo que sigue, que es programar el algoritmo para mostrar tu animación en la matriz led.

Código ASM


NOTA: El código no utiliza las definiciones del archivo inc.

Barrido: Vamos a mandar las secuencias de la animación por el puerto A.

Utilizamos un registro general para guardar el número de cuadros de animación, puedes elegir cualquier registro, yo elegí el 0x25, en mi caso el numero total de animaciones son ocho:

movlw 0x08
movwf 0x25

Definimos cinco registros, contador vertical(0x20), indexador(0x21), control de marco(0x23), contador aux(0x24) y switch(0x2A).

clrf 0x20
clrf 0x21
clrf 0x23
clrf 0x24
movlw 0x10
movwf 0x2A

Definimos los cuadros de la animación y utilizamos el PC como index.

byte_man addwf 0x02,1
dt .0, .24, .24, .60, .90, .24, .36, .102
dt .0, .24, .24, .62, .88, .24, .36, .102
dt .0, .24, .26, .62, .88, .24, .36, .102
dt .0, .24, .25, .62, .88, .24, .36, .102
dt .0, .24, .26, .62, .88, .24, .36, .102
dt .0, .24, .25, .62, .88, .24, .36, .102
dt .0, .24, .24, .62, .88, .24, .36, .102
dt .0, .24, .24, .60, .90, .24, .36, .102

Lo más seguro es que hagamos diferentes animaciones por lo tanto, conviene crear una subrutina para inicializar los registros.

recarga clrf 0x20
clrf 0x21
movlw .8
movwf 0x23
clrf 0x24
swapf 0x2A,1
return

Mandamos los datos de animación por el puerto.

anim_byteman movf 0x21,0
call byte_man
movwf 0x05
call sec_ani
btfss 0x2A,0
goto anim_byteman
call recarga
return

Hemos terminado con el primer paso, ahora vamos al siguiente.

Refresco: Antes de "retener" necesitamos controlar el demultiplexor para que haga los cambios de cuadros de la animación.

Vamos a utilizar el TMR0 para controlar la velocidad de refresco (a mayor pre-escalador más lento el refresco):

movlw 0x82
movwf 0x81

Establecemos la subrutina de refresco:

refresh clrf 0x01
btfss 0x0B,2
goto $-1
bcf 0x0B,2
return

Ahora incrementamos el demultiplexor para que pase al siguiente cuadro de animación:

sec_ver movf 0x20,0
movwf 0x07
incf 0x20,1
xorlw 0x07
btfss 0x03,2
return
clrf 0x20
return

Eso sería todo en cuanto al refresco, ahora solo queda la última etapa.

Retención: Para retener el cuadro hice un algoritmo que retenga el bloque actual y aparte pueda acceder a cualquier cuadro de la animación.

Establecemos el número de veces que se va a repetir el mismo cuadro:

movlw 0x40
movwf 0x22

Ahora creamos el algoritmo para retener el cuadro:

sec_ani call sec_ver
call refresh
decfsz 0x22,1
goto $+2
goto $+9
incf 0x21,1
movf 0x21,0
xorwf 0x23,0
btfss 0x03,2
return
movf 0x24,0
movwf 0x21
return
movlw .64
movwf 0x22
movf 0x23,0
movwf 0x24
movwf 0x21
movlw .8
addwf 0x23,1
decfsz 0x25,1
return
swapf 0x2A,1
return

Eso es todo, ya solo queda llamar la subrutina para que empiece la animación:

call anim_byteman

¿Pero qué está pasando? despues de ver la animación la pantalla se queda en negro :'(
Es por eso que implementé en el algoritmo la capacidad de acceder al número de cuadro que queramos que se repita :B.
Como son 8 cuadros totales, quiero que se repita el último por lo tanto, 8*7 = 56 los límites serían 56 y 64, cargamos esos números a los registros de control:

recarga_byte clrf 0x20
movlw .1
movwf 0x25
movlw .64
movwf 0x23
movlw .56
movwf 0x24
movwf 0x21
return

Si te preguntas por qué multipliqué por 8, es simple, recuerda que cada cuadro de animación es de 1 byte (8 bits).
Llamamos la nueva subrutina y veamos que pasa:

call anim_byteman
call recarga_byte
call anim_byteman
goto $-2

Resultado y palabras finales

Resultado
Si hiciste bien todos los pasos deberías de ver la imágen que diseñaste en la matriz led, si por algún motivo no es así, revisa primero lo "obvio"

Revisa si está conectado el circuito y que tienes energía en la linea, polaridad de los circuitos integrados, revisa de nuevo las conexiones, si todo está bien conectado y en su lugar, lo más probable es que sea error de programación.

Depura tu código utilizando las herramientas del IDE que estés utilizando, en mi caso, estoy utilizando Mplab versión 8.92, debo de admitir que el MplabX me recuerda un tanto a mikroC, en ese aspecto MplabX tiene nuevas funciones que ayuda en la depuración, lo que sigue sin convencerme es tener todas los registros de depuración importantes (al menos para mi) SFR, ROM y Watch en una sola ventana, supongo que es cuestión de gustos.

Una vez revisado tu código, ya que esté libre de errores y estés 100% seguro que todo está correcto vuelve a programar el microcontrolador, seguro que esta vez seras capaz de ver tu animación en la matriz led.

De todas maneras aquí les dejo el archivo asm: byteman.asm

Y el archivo hex para que prueben su hardware antes de seguir adelante byteman.hex

Con esto hemos terminado, ahora solo dedicate a diseñar tus animaciones, logotipos o cualquier cosa que se te ocurra.
No se olviden de recomendar esta pagina en facebook, twitter, google plus o cualquier otra red social, foro, pagina web, o medio de comunicación, tambien pueden seguirme en twitter @edx_twin3 donde pongo las ultimas noticias sobre la página.
Como siempre cualquier duda, sugerencia, comentario, etc ...., la pueden enviar ya sea mediante la pagina de contacto, mediante correo electrónico edx@edx-twin3.org o utilizando la pestaña de Comentarios de este tutorial.
Por último pero no menos importante cualquier donativo es de gran ayuda para seguír haciendo tutoriales como este, gracias :1.

Comentarios, dudas o sugerencias

Comprar ahora ....