Estoy buscando controlar unas tiras de LEDs WS2812 5050 RGB desde un microcontrolador. He jugado con éxito con la librería Neopixel de Adafruit y he escrito algo de código en un PIC18F2455 que también he conseguido que funcione para algunas cosas sencillas (cambiar progresivamente de color de rojo, a verde a azul, y viceversa, etc).
Sin embargo, todo eso fue para una sola cadena. Idealmente, ya que estoy usando PORTB en el micro PIC, sería genial usar los 8 bits para manejar hasta 8 cadenas desde un solo chip.
Sí, sé que me estoy volviendo codicioso :)
Mi pregunta es, qué enfoque me recomiendan tomar dado que tengo como máximo el tiempo involucrado para enviar un 1 o un 0 en cualquier canal individual es de unos pocos ciclos de instrucción y el protocolo de señalización es de tipo 1-hilo no estándar por lo que el PIC no tiene un periférico dedicado para descargar el trabajo (enviar un 1 implica 'escribir 1, nop, escribir 0' y enviar un 0 implica 'escribir 1, escribir 0, nop').
Además, es probable que sólo haya como mucho un centenar de ciclos de instrucción entre el final de un bit y el comienzo del siguiente antes de que llegues al "código de fin" de 50us y todo lo que has estado escribiendo se quede enganchado en los LEDs y el protocolo de datos vuelva a esperar el primer bit.
Para una sola cadena he estado tomando los tres bytes para el verde, el rojo y el azul (ese es el orden que usan estas cosas) y haciendo 24 declaraciones "if (green & 0x80) write1(); else write0();" etc. Pero está claro que ese mismo enfoque no va a funcionar para 8 bits a la vez.
Algunas opciones que consideré:
-
Computar un byte basado en el primer bit del valor verde, luego usar un ensamblaje cuidadosamente elaborado para (a) escribir 0xff en el puerto, (b) escribir el byte computado en el puerto, y luego (c) escribir un 0x00 en el puerto. Repite 23 veces más para el primer LED de cada una de las 8 cadenas, y luego repite de nuevo durante el tiempo que sea necesario para emitir la cadena completa. El único problema es que toda esa computación toma una buena cantidad de ciclos y es muy posible que tome tanto tiempo que termine interfiriendo con su salida.
-
En lugar de almacenar cada uno de los datos de la cadena de LEDs como una matriz de valores de bytes de PSG y luego calcularlos en el momento de la salida, almacénelos como una matriz de bits "difuminada" (por ejemplo, los datos del LED 1 de la primera cadena se almacenan a través de 24bytes de memoria en el primer bit de cada byte, los de la segunda cadena a través del segundo bit de cada byte, etc). La ventaja es que la salida es muy fácil y rápida, la desventaja es que la carga de trabajo se traslada a la parte de creación del proceso y ahora necesitas funciones para obtener o establecer valores individuales.
¿Qué opinas? ¿Alguien tiene alguna razón por la que haría o no haría alguna de las anteriores? ¿Alguien sabe de algún truco inteligente para "voltear" rápidamente una matriz de 8 bytes para que el byte 1 se convierta en el primer bit de los 8 bytes en el resultado?)