Tabla de contenido:

Matriz de LED RGB: 5 pasos
Matriz de LED RGB: 5 pasos

Video: Matriz de LED RGB: 5 pasos

Video: Matriz de LED RGB: 5 pasos
Video: COMO MANEJAR UN PANEL MATRICIAL RGB DE 64x32 PX(Flexible RGB LED Matrix-4mm Pitch) 2024, Mes de julio
Anonim
Image
Image
Diseño de hardware
Diseño de hardware

Busque Instructable y podrá encontrar muchos proyectos de matriz de LED. Ninguno de ellos era exactamente lo que quería, que era explorar las interacciones del diseño de hardware y software para producir algo, y producir el producto final en una PCB ordenada con un controlador que me permitiera dibujar en la "pantalla LED" usando construcciones (por ejemplo, dibujar una línea en lugar de establecer píxeles específicos). Esta parte fue importante para mí, ya que muchos de los controladores de la matriz de LED son básicos y no proporcionan mucho en la forma de crear una imagen o animación mediante programación. Esto no significa que no pueda crear imágenes y animaciones con los otros controladores, solo que tendría que hacer un trabajo más repetitivo de un proyecto a otro.

Así que me propuse lograr mi visión. El primer paso fue diseñar el hardware. Este fue probablemente el más desafiante para mí, ya que mi experiencia es más software. Una vez más, había muchos diseños prefabricados, y ciertamente los usé como inspiración, pero quería aprender haciendo, así que hice un prototipo de una matriz 4x4 en una placa de pruebas. Aprendí mucho a través de ese proceso, ya que mis primeras iteraciones no funcionaron. Pero hice un diseño de hardware que funcionó, lo que a su vez me permitió comenzar a desarrollar un controlador.

Elegí Arduino como mi plataforma de controladores porque está ampliamente disponible y tiene muchas referencias en línea. Si bien la experiencia profesional me permitió llegar a una versión funcional de un controlador más hábilmente que mis esfuerzos de hardware, todavía hubo muchas iteraciones mientras optimizaba el rendimiento del controlador para el microcontrolador ATMega y desarrollaba una API de programación que me gustó.

Este Instructuctable documenta el diseño y algunos aprendizajes clave de mi proyecto. Puede encontrar más información sobre este proyecto en mi sitio web aquí, incluidos los kits completos que puede comprar para construir su propia matriz de LED RGB.

Paso 1: Diseño de hardware

El objetivo principal de mi diseño de hardware era crear una serie de LED RGB que pudiera programar, pero tampoco quería gastar mucho dinero. El enfoque que elegí fue usar registros de cambio 74HC595 para controlar los LED. Para minimizar la cantidad de registros de desplazamiento necesarios, coloqué los LED RGB en un diseño de matriz donde los ánodos comunes se unían en filas y los cables de cátodo rojo, verde y azul se unían en columnas. Para la matriz 4x4, el diagrama de circuito se parecía al diagrama de circuito adjunto.

Una cosa que notará de inmediato es que, dado el circuito de matriz, hay algunas configuraciones de iluminación LED que no se pueden hacer con todos los LED deseados encendidos al mismo tiempo. Por ejemplo, la matriz no puede iluminar simultáneamente dos LED que están en diagonal entre sí porque la alimentación tanto de las filas como de las columnas hará que los dos LED opuestos se enciendan en la diagonal perpendicular a los LED deseados. Para solucionar esto, usaremos la multiplexación para escanear cada fila. Hay muchos recursos en la web que cubren la técnica de multiplexación, no voy a intentar replicarlos aquí.

Dado que estoy usando LED de ánodo común, eso significa que las filas proporcionan energía positiva y las columnas se hunden a tierra. La buena noticia es que los registros de cambio 74HC595 pueden generar y absorber energía, pero la mala noticia es que tienen un límite en la cantidad de energía que pueden generar o absorber. Los pines individuales del 74HC595 tienen un consumo de corriente máximo de 70 mA, pero es mejor mantener menos de 20 mA. Cada uno de los colores individuales de nuestros LED RGB tiene un consumo de aproximadamente 20 mA. Esto significa que el 74HC595 no puede alimentar directamente una fila completa de LED si deseo encenderlos todos.

Entonces, en lugar de alimentar la fila directamente, el 74HC595 impulsará un transistor para cada fila, y el transistor encenderá o apagará la corriente que alimenta la fila. Dado que el diseño utiliza un LED de ánodo común, el transistor de conmutación será PNP. Si estuviéramos usando un LED de cátodo común, el transistor de conmutación sería NPN. Tenga en cuenta que con el uso de un transistor PNP para conducir una fila, la configuración del registro de desplazamiento para encenderlo ahora se vuelve baja ya que un transistor PNP necesita un voltaje negativo entre el emisor y la base para encenderse, lo que permitirá que la corriente positiva fluya hacia el hilera.

Otra cosa a considerar es la disposición de bits deseada de los registros de desplazamiento. Es decir, entre los registros de desplazamiento, qué bits controlan qué filas o columnas en la matriz. El diseño con el que envié es donde el primer bit, o "bit más significativo", enviado a los registros de desplazamiento encadenados controlan la columna de LED del elemento rojo, el segundo bit controla el elemento verde de la primera columna, el tercer bit controla el elemento verde de la primera columna. elemento azul, el cuarto bit controla el elemento rojo de la segunda columna,… este patrón se repite en las columnas de izquierda a derecha. Luego, el siguiente bit enviado controla la última fila o la última fila, la siguiente la penúltima fila, … esto se repite hasta que el último bit enviado, o el "bit menos significativo", controla la primera fila o la superior de la matriz..

Finalmente, necesitaba determinar qué resistencias usaría para cada uno de los LED en el LED RGB. Si bien puede usar la fórmula estándar que combina el voltaje directo y la corriente deseada para calcular la resistencia requerida, descubrí que configurar la corriente de cada LED en 20 miliamperios daba como resultado un color blanquecino cuando todos los LED rojos, verdes y azules estaban encendidos. Así que comencé a mirarlo. Demasiado rojo en el blanco significaba aumentar los ohmios de la resistencia del LED rojo para reducir la corriente. Repetí intercambiando resistencias de diferentes ohmios hasta que encontré una combinación que produjo un color blanco que sentí que era correcto. La combinación final fue de 180 Ω para el LED rojo, 220 Ω para el LED verde y 100 Ω para el LED azul.

Paso 2: Construcción de hardware - Placa de pruebas

Construcción de hardware: placa de pruebas
Construcción de hardware: placa de pruebas
Construcción de hardware: placa de pruebas
Construcción de hardware: placa de pruebas

La primera fase del constructor de hardware fue el breadboarding. Aquí hice una matriz 4x4 con los LED RGB. Esta matriz requeriría 16 bits para controlar, 12 para las columnas RGB y 4 para cada fila. Dos registros de cambios 74HC595 pueden manejarlo todo. Primero investigué y diseñé un circuito que pensé que funcionaría, luego lo construí en la placa de pruebas.

Probablemente el mayor desafío de la construcción de la placa de pruebas fue administrar todos los cables. Cogí un kit de cables preformados para placas de prueba, pero luego fue un poco difícil de manejar. Un truco que me pareció útil fue crear un "puerto" para conectarse a la placa Arduino. Es decir, en lugar de conectar los pines del Arduino directamente a los diversos pines IC en la placa de pruebas, dedique algunas filas en la placa de pruebas para que sean el punto de conexión para el Arduino y luego conecte los pines de identificación relevantes a esas filas. Para este proyecto, solo necesita cinco conexiones al Arduino: + 5V, tierra, datos, reloj y pestillo.

Una vez que se hizo la construcción de la placa de pruebas, necesitaba probarla. Sin embargo, sin algún tipo de controlador para enviar las señales correctas a los registros de turno, no pude probar para ver si el diseño del hardware funcionaba.

Paso 3: Diseño del software del controlador

Image
Image

Dada mi propia experiencia profesional con el desarrollo de software, esta fue la parte del proyecto en la que probablemente tuve más claro el camino a seguir. Estudié muchos de los otros controladores de matriz LED basados en Arduino. Si bien es cierto que hay buenos controladores disponibles, ninguno tenía el diseño que yo quería. Mis objetivos de diseño del controlador fueron:

  • Proporcione una API de alto nivel para poder crear imágenes y animaciones mediante programación. La mayoría de los conductores que vi estaban más enfocados en imágenes codificadas. Además, dado que soy un programador de C ++ de oficio, quería utilizar un buen diseño orientado a objetos para implementar y administrar las actividades de dibujo en la matriz de LED.
  • Utilice un enfoque de doble búfer para administrar la imagen en la pantalla. Un búfer es el que se introduce mediante programación, mientras que el otro representa el estado de los píxeles de la matriz en un momento dado. La ventaja de este enfoque es que no es necesario que renderice completamente la siguiente actualización de fotogramas para la pantalla entre los ciclos de actualización de la multiplexación.
  • Utilice PWM para permitir más de los siete colores primitivos que un RGB puede representar mediante combinaciones simples de elementos rojo, verde y azul.
  • Escriba el controlador de manera que "simplemente funcione" con matrices LED RGB de diferentes tamaños que siguieron mi enfoque general de diseño de matrices. Tenga en cuenta que, si bien el diseño de mi hardware utiliza registros de desplazamiento 74HC595, esperaría que mi controlador funcione con cualquier mecanismo de activación / desactivación de estilo de registro de desplazamiento que esté diseñado con un diseño de bits similar al diseño de mi hardware. Por ejemplo, esperaría que mi controlador funcione con un diseño de hardware que usa chips DM13A para controlar las columnas y un chip 74HC595 para controlar las filas.

Si desea ir directamente a buscar el código del controlador, puede encontrarlo en GitHub aquí.

La primera iteración de mi controlador fue una pequeña curva de aprendizaje sobre las capacidades de la plataforma Arduino. La limitación más obvia es la RAM, que es de 2K bytes para Arduino Uno y Nano. El uso de objetos C ++ en tal escenario con frecuencia no se recomienda debido a la sobrecarga de memoria de los objetos. Sin embargo, sentí que si se hacía bien, el beneficio de los objetos en C ++ superaba su costo (en RAM).

El segundo gran desafío fue averiguar cómo implementar la modulación de ancho de pulso a través de los registros de desplazamiento para poder generar más de los siete colores primitivos del LED RGB. Habiendo programado durante muchos años en plataformas Linux, estaba acostumbrado a usar construcciones como subprocesos para administrar procesos que requieren una sincronización constante. El tiempo de la operación de actualización del registro de desplazamiento termina siendo bastante crítico cuando se crea un controlador para una matriz de LED que usa multiplexación. La razón es que a pesar de que la multiplexación ocurre tan rápido que sus ojos no pueden ver los LED individuales parpadeando, sus sí pueden detectar diferencias en el tiempo agregado total que cualquiera de los LED está encendido. Si una fila de LED está encendida de manera constante durante un período de tiempo más largo que las demás, se verá más brillante durante la multiplexación. Esto puede provocar un brillo desigual en la matriz o un estroboscopio periódico de la matriz en su conjunto (esto ocurre cuando un ciclo de actualización lleva más tiempo que los demás).

Como necesitaba un mecanismo de temporización consistente para hacer que las actualizaciones del registro de desplazamiento fueran consentidas, pero Arduino no admite formalmente el hilo, tuve que crear mi propio mecanismo similar al de un hilo. Mi primera iteración de esto fue simplemente para crear un temporizador de bucle que dependiera de la función loop () de Arduino y dispararía una acción cuando haya transcurrido una cierta cantidad de tiempo desde la última vez que se disparó la acción. Esta es una forma de "multitarea cooperativa". Suena bien, pero en la práctica esto resultó ser inconsistente cuando la velocidad de disparo se midió en microsegundos. La razón de esto es que si tuviera dos de estos temporizadores de bucle funcionando, una de sus acciones con frecuencia tomaba el tiempo suficiente para hacer que la segunda acción se disparara más tarde de lo deseado.

Descubrí que la solución a este problema es utilizar el mecanismo de interrupción del reloj nativo de Arduino. Este mecanismo le permite ejecutar una pequeña cantidad de código a intervalos muy consistentes. Así que diseñé el código del controlador en torno al elemento de diseño de usar una interrupción de reloj para activar el código para enviar los registros de desplazamiento de la matriz la próxima actualización en el ciclo de multiplexación. Para hacer esto y permitir que se produzcan actualizaciones en la imagen de la pantalla para que no interfieran con un volcado activo en los registros de cambio (algo que llamaríamos una "condición de carrera"), utilicé un enfoque de tener búferes gemelos para los bits del registro de cambio, uno para escribir y otro para leer. Cuando el usuario está actualizando la imagen de la matriz, estas operaciones ocurren en el búfer de escritura. Cuando esas operaciones se completan, las interrupciones se suspenden temporalmente (esto significa que la interrupción del reloj no se puede disparar) y el búfer de escritura se intercambia con el búfer de lectura anterior y no es el nuevo búfer de lectura, luego se vuelven a habilitar las interpretaciones. Luego, cuando se activa la interrupción del reloj, lo que indica que es hora de enviar la siguiente configuración de bits a los registros de desplazamiento, esa información se lee del búfer de lectura actual. De esta manera, nunca se produce ninguna escritura en un búfer del que se esté leyendo actualmente durante una interrupción del reloj, lo que podría corromper la información enviada a los registros de turno.

Diseñar el resto del controlador fue un caso relativamente sencillo de diseño orientado a objetos. Por ejemplo, creé un objeto para administrar la imagen de bit del registro de desplazamiento para cualquier estado de pantalla dado. Al encapsular el código perteneciente a la gestión de imágenes de bits, la creación del enfoque de búferes gemelos antes mencionado fue en sí mismo un ejercicio sencillo. Pero no escribí este Instructable para ensalzar las virtudes del diseño orientado a objetos. Otro elemento de diseño incluye el concepto de un glifo y una imagen RGB. Un glifo es una construcción de imagen básica que no tiene información de color innata. Puedes pensar en ella como una imagen en blanco y negro. Cuando se dibuja el glifo en la pantalla LED, se proporciona información de color para indicar cómo se deben colorear los píxeles "blancos". Una imagen RGB es una imagen en la que cada píxel tiene su propia información de color.

Le animo a que revise los ejemplos de bocetos de Arduino y revise la documentación del encabezado del controlador para familiarizarse con cómo usar el controlador para crear imágenes y animaciones en una matriz de LED RGB.

Paso 4: LED fantasma

LED fantasma
LED fantasma
LED fantasma
LED fantasma

En una matriz de LED, el "efecto fantasma" es el fenómeno de un LED en la matriz que se ilumina cuando no se desea, generalmente a un nivel muy reducido. Mi diseño de hardware original era susceptible a las imágenes fantasma, sobre todo en la última fila. La causa de esto se debe a dos cosas: los transistores no se apagan inmediatamente y la capacitancia parásita en los LED RGB.

A medida que escaneamos las filas, debido al hecho de que los transistores no se apagan inmediatamente, la fila anterior en el ciclo de escaneo todavía está parcialmente encendida cuando se enciende la siguiente fila. Si una columna determinada que estaba apagada en la fila anterior se enciende nuevamente cuando se enciende la nueva fila, el LED de esa columna en la fila anterior se iluminará por un momento mientras el transistor de conmutación de la fila anterior todavía está en proceso de encender apagado. Lo que hace que el transistor tarde un tiempo notable en apagarse es la saturación en la base del transistor. Esto hace que la ruta del transistor colector-emisor continúe conduciendo cuando se elimina la corriente de la base, al menos hasta que la saturación se disipa. Dado que nuestro ciclo de actualización de multiplexación hace que las filas estén deliberadamente encendidas durante un período de tiempo medido en microsegundos, la cantidad de tiempo que el transistor saturado de la fila anterior permanece conductor puede ser una fracción notable de eso. Como resultado, su ojo puede percibir esa pequeña cantidad de tiempo que el LED de la fila anterior está encendido.

Para solucionar el problema de saturación del transistor, se puede agregar un diodo Schottky al transistor entre la base y el colector para causar un poco de contracorriente a la base cuando el transistor está encendido, evitando que el transistor se sature. Esto, a su vez, hará que el transistor se apague más rápidamente cuando se elimine la corriente de la base. Consulte este artículo para obtener una explicación detallada de este efecto. Como puede ver en la imagen de esta sección, sin el diodo, el efecto fantasma es bastante notable, pero agregar el diodo al circuito para cada fila elimina significativamente el efecto fantasma.

Los LED RGB son susceptibles a otro fenómeno llamado capacitancia parásita. La causa principal de esto es el hecho de que cada uno de los tres LED de color en la unidad de LED RGB tiene diferentes voltajes de avance. Esta diferencia en los voltajes directos puede causar el efecto de la capacitancia eléctrica entre cada uno de los colores de LED individuales. Dado que se acumula una carga eléctrica en la unidad LED cuando se enciende, cuando se corta la energía, la capacitancia parásita debe descargarse. Si esa columna de LED está encendida de otra manera para la alimentación de otra fila, la carga parásita se descargará a través de esa columna de LED y hará que brille brevemente. Este efecto se explica muy bien en este artículo. La solución es agregar una ruta de descarga para esta carga parásita que no sea a través del LED mismo, y luego darle tiempo al LED para que se descargue antes de que la columna se encienda nuevamente. En mi diseño de hardware, esto se logra agregando una resistencia a la línea eléctrica de cada fila que conecta la fuerza a tierra. Esto hará que se extraiga más corriente con la fila alimentada, pero proporciona una ruta de descarga para la capacitancia parásita cuando la fila no está alimentada.

Sin embargo, vale la pena señalar que, en la práctica, encuentro que el efecto de la capacitancia parásita es apenas perceptible (si lo busca, puede encontrarlo), por lo que considero que agregar esta resistencia adicional es opcional. El efecto del tiempo de desaceleración para transistores saturados es mucho más fuerte y notable. No obstante, si inspecciona las tres fotos proporcionadas en esta sección, puede ver que las resistencias eliminan por completo cualquier imagen fantasma que aún se produzca más allá de los tiempos de inactividad del transistor lento.

Paso 5: Fabricación final y próximos pasos

Image
Image

La fase final de este proyecto fue para mí crear una placa de circuito impreso (PCB). Usé el programa de código abierto Fritzing para diseñar mi PCB. Si bien hubo muchas tareas repetitivas que realizar para diseñar 100 LED en una placa de 10x10, en realidad encontré esta fase del proyecto extrañamente satisfactoria. Averiguar cómo se distribuiría cada vía eléctrica fue como un rompecabezas, y resolver ese rompecabezas creó una sensación de logro. Como no estoy preparado para fabricar las placas de circuito, utilicé uno de los muchos recursos en línea que hacen pequeñas tiradas de PCB personalizadas. Soldar las piezas fue bastante sencillo ya que mi diseño utilizó todas las piezas de orificio pasante.

En el momento de escribir este Instructable, tengo los siguientes planes para mis proyectos de matriz de LED RGB:

  1. Continúe mejorando el controlador en la capa de API para permitir más funciones de alto nivel para el programador, sobre todo el desplazamiento de texto.
  2. Cree diseños matriciales más grandes, como 16x16 o incluso 16x32.
  3. Explore el uso de MOSFET en lugar de BJT para la conmutación de alimentación de fila
  4. Explore el uso de controladores de corriente constante DM13A en lugar de 74HC595 para la conmutación de columnas
  5. Crea controladores para otras plataformas de microcontrol, como Teensy, ODROID C2 o Raspberry Pi.

Tenga en cuenta que tanto el diseño de hardware como el controlador se publicaron bajo la licencia de código abierto GPL v3 en este repositorio de GitHub. Además, dado que a pesar de que los fabricantes de PCB hacen "pequeñas tiradas" de mi diseño de PCB, todavía obtengo mucho más de lo que personalmente necesito. Así que estoy vendiendo kits completos para mis diversos diseños de matrices LED RGB (PCB y todas las piezas incluidas) desde mi sitio web aquí.

Recomendado: