01 · Punto de partida
Del LED al píxel
Una matriz multiplexada (tema 35) ahorra pines pero obliga al microcontrolador a barrer filas sin parar. Una tira direccionable invierte el reparto: cada LED trae su propio chip, que recuerda su color y mantiene el PWM por su cuenta. El microcontrolador solo envía una vez los datos de toda la imagen y se desentiende hasta el cuadro siguiente. Es el modelo de un búfer de imagen (frame buffer) con una salida serie.
Los tres asuntos del tema, en orden de aparición:
- Datos: cómo viaja el color por el cable (un hilo con tiempos estrictos, o reloj más datos) y cuánto tarda cada cuadro.
- Energía: cada píxel a blanco pleno consume unos 60 mA; una tira de 300 LEDs puede pedir 18 A y su tensión cae a lo largo del cobre.
- Software: el color se calcula en un arreglo en memoria, se atenúa, se corrige y se envía; las animaciones deben avanzar sin bloquear el resto del programa (tema 41).
02 · Los chips
El WS2812 y su familia
El WS2812 (comercializado por Adafruit como NeoPixel) integra en una cápsula de 5 × 5 mm tres LEDs (rojo, verde, azul) y un controlador. Tiene cuatro terminales: alimentación (5 V), masa, entrada de datos (DIN) y salida de datos (DOUT). Cada chip es, en la práctica, un registro de desplazamiento de 24 bits con PWM de 8 bits por canal:
- El primer LED toma los primeros 24 bits que llegan por DIN y los guarda como su color.
- Todo lo que llega después lo regenera (amplifica y reconforma) y lo envía por DOUT al siguiente LED.
- Una pausa larga en nivel bajo (el reset o latch) hace que todos los LEDs adopten a la vez el color recibido.
Como cada LED regenera la señal, la tira se alarga sin degradar los datos; el límite no es la señal sino el tiempo de trama y la energía. El orden de los bytes es verde, rojo, azul (GRB), no RGB, y se envía primero el bit más significativo. El PWM interno trabaja a unos 400 Hz, suficiente para el ojo pero visible en cámaras de alta velocidad.
| Chip | Tensión | Datos | Observación |
|---|---|---|---|
| WS2812B | 5 V | Un hilo, 800 kHz | El más difundido; un LED por chip |
| WS2811 | 12 V | Un hilo, 400 kHz | Un controlador cada 3 LEDs (tiras de 12 V) |
| WS2813 | 5 V | Un hilo, con línea de respaldo | Si un LED falla, la señal sigue por la segunda línea |
| WS2815 | 12 V | Un hilo, con respaldo | Menos corriente por metro, menos caída de tensión |
| SK6812 RGBW | 5 V | Un hilo, 800 kHz | Cuarto canal blanco: 32 bits por LED |
| APA102 (DotStar) | 5 V | Reloj y datos | PWM de unos 20 kHz y brillo global de 5 bits |
03 · Comunicación
El protocolo de un hilo
El WS2812 no tiene reloj: la duración del pulso en alto codifica el bit. Cada bit dura unos 1,25 µs (800 kHz) y el nivel alto es corto para un 0 y largo para un 1:
| Bit | Nivel alto | Nivel bajo | Total |
|---|---|---|---|
| 0 | 0,40 µs | 0,85 µs | 1,25 µs |
| 1 | 0,80 µs | 0,45 µs | 1,25 µs |
| Reset | Nivel bajo durante más de 50 µs (los WS2812B recientes piden unos 280 µs; se usan 300 µs de margen) | — | |
El receptor decide con un umbral intermedio, de modo que un 0 cuyo nivel alto se alarga a más de unos 0,6 µs se lee como un 1. Un LED ocupa 24 bits = 24 × 1,25 = 30 µs; una tira de N LEDs tarda 30·N µs + 300 µs. Con 60 LEDs, 2,1 ms (476 cuadros por segundo como máximo); con 300, 9,3 ms (108); con 1000, 30,3 ms (33). Es un tiempo en el que el programa no puede hacer otra cosa si genera los pulsos por software.
Generar esos pulsos con digitalWrite es imposible (cada llamada tarda más de 1 µs); en un AVR se usan secuencias de ensamblador de ciclos contados, con las interrupciones desactivadas durante toda la trama: si una interrupción cae en medio de un bit alto, lo alarga y cambia el dato. Por eso, mientras se envían 300 LEDs en una placa Arduino, se pierden milisegundos de millis() y bytes de la puerta serie. Hay varias salidas:
- Hardware dedicado: en el ESP32, el periférico RMT (o I2S con DMA) genera los pulsos sin intervención de la CPU; en el RP2040, un programa de PIO. Es la solución para tiras largas y programas con comunicaciones.
- El truco del SPI: un bus SPI a 2,4 MHz envía tres bits por cada bit del WS2812 (
100para un 0 y110para un 1), con DMA y sin bloquear. - Menos LEDs por salida: varias tiras en varios pines, que se envían en paralelo con hardware que lo permita.
- Enviar solo cuando hay cambios: cada
show()cuesta lo mismo, se haya modificado el color o no.
04 · La alternativa
El APA102: reloj y datos
El APA102 (DotStar) usa dos hilos, reloj y datos, como un bus SPI de solo escritura. No tiene tiempos críticos: los datos se toman en el flanco del reloj, de modo que el SPI de hardware lo maneja sin bloquear y a cualquier frecuencia (en la práctica 4 a 8 MHz; hasta unos 20 MHz en tiras cortas). Una trama consta de:
- Inicio: 32 bits en cero.
- Un bloque de 32 bits por LED: tres bits en 1, 5 bits de brillo global (0 a 31) y luego azul, verde y rojo (8 bits cada uno).
- Fin: al menos N/2 bits en 1, para empujar el reloj hasta el último LED.
El tiempo es (32 + 32·N + bits de fin) / freloj: 300 LEDs a 8 MHz tardan 1,22 ms, ocho veces menos que el WS2812. Además, el APA102 regenera el PWM a unos 20 kHz (el WS2812, a 400 Hz) y no muestra rayas en las cámaras, y el campo de brillo global permite atenuar sin tocar los valores de color. Cuesta más y consume algo más.
| Aspecto | WS2812 | APA102 |
|---|---|---|
| Cables de señal | 1 (datos) | 2 (reloj y datos) |
| Tiempos críticos | Sí (±150 ns) | No |
| Tiempo de 300 LEDs | 9,3 ms | 1,2 ms (8 MHz) |
| Frecuencia de PWM | ~400 Hz | ~20 kHz |
| Brillo | Escalando los valores RGB | Campo global de 5 bits, además del RGB |
| Precio | Menor | Mayor |
05 · Energía
Consumo y alimentación
Cada canal del LED toma unos 20 mA a pleno: 60 mA por píxel a blanco, más aproximadamente 1 mA de reposo del chip. Eso se multiplica rápido:
| LEDs | Blanco pleno | Arcoíris | Fuente sugerida (+20 %) |
|---|---|---|---|
| 30 | 1,83 A | 0,93 A | 3 A |
| 60 | 3,66 A | 1,86 A | 5 A |
| 144 | 8,78 A | 4,46 A | 11 A |
| 300 | 18,3 A | 9,3 A | 22 A |
Un puerto USB da 0,5 a 0,9 A y un adaptador común de 2 A: no alcanzan para una tira larga a blanco. Hay dos estrategias, que se combinan:
- Limitar por software: el brillo máximo (rara vez se necesita el 100 %; el 30 a 50 % se ve brillante en interiores) y, mejor, un presupuesto de corriente que escale todo el cuadro si la suma supera el límite (en FastLED,
setMaxPowerInVoltsAndMilliamps(5, 2000)). - Dimensionar la fuente con margen del 20 %, con fusible y cables de sección acorde (para 10 A, al menos 1,5 mm²; los cables finos de la tira no son para eso).
El segundo problema es la caída de tensión. El cobre de la tira tiene resistencia: la corriente de todos los LEDs que están más allá circula por el tramo inicial, y a 5 V un descenso de 1 V ya es una pérdida del 20 %. En un modelo simple, con 5 mΩ de ida y vuelta por LED y 60 mA por LED, un tramo de k LEDs alimentado por un extremo pierde R × I × k(k+1)/2: 0,14 V con 30 LEDs, 0,55 V con 60, 1,5 V con 100 y 3,4 V con 150 (el modelo exagera los valores altos, porque la corriente cae con la tensión, pero el orden de magnitud es el que se observa). Los efectos al caer la tensión son típicos: los LEDs azules y verdes, con mayor tensión directa, se apagan primero, y el blanco del final de la tira vira a amarillo y luego a rojo; por debajo de unos 3,5 V, los datos se corrompen.
La solución es la inyección de alimentación: conectar la fuente también en puntos intermedios (cada 1 a 2 metros en una tira de 60 LEDs por metro a blanco) y a ambos extremos, con la masa unida a la de todo el sistema. Los datos siguen viajando por el hilo único.
06 · Conexión
Cableado y nivel lógico
- Nivel lógico: un WS2812B alimentado con 5 V exige que la entrada de datos supere
0,7 × VDD = 3,5 V. Una salida de 3,3 V (ESP32, RP2040) está por debajo: a veces funciona y a veces no, según la temperatura y el largo del cable. La solución es un adaptador de nivel de un solo sentido, como el 74AHCT125 alimentado con 5 V. - Resistencia en serie de 300 a 500 Ω en la línea de datos, cerca del primer LED: limita las oscilaciones y protege la entrada.
- Capacitor de 1000 µF (de 6,3 V o más) entre alimentación y masa al principio de la tira: absorbe el pico de corriente al conectar y los cambios bruscos de carga.
- Masa común entre la fuente de la tira y el microcontrolador, y conectar la masa primero: si se alimenta la tira sin masa compartida, la entrada de datos queda flotante y puede dañarse.
- Cable de datos corto entre el microcontrolador y el primer LED (idealmente menos de 30 cm); en distancias mayores, un transceptor diferencial.
- Nunca alimentar la tira con el regulador de la placa: su corriente es de cientos de miliamperios.
Y un cuidado con las tiras cortadas o empalmadas: el sentido de los datos está marcado con una flecha (DIN → DOUT), y los cortes se hacen en las marcas de cobre. Al empalmar, se conserva el sentido.
07 · Color
Color, brillo y resolución
Los conceptos del tema 35 se aplican aquí, con una limitación: cada canal tiene 8 bits y un solo registro. Tres consecuencias:
- Gamma: el valor 128 no es «medio brillo». Para atenuados y degradados uniformes, se pasa cada canal por una tabla gamma (de 2,2 o 2,8). Pero con 8 bits de entrada y de salida, los primeros valores se aplastan a cero, y los fundidos a negro se ven escalonados.
- Brillo global: escalar los tres canales por un factor reduce los niveles disponibles. Al 10 % quedan 26 niveles por canal; al 5 %, 13; al 2 %, 6. Los canales se redondean por separado y el tono se desvía (hasta 1,9° al 10 %, 4,0° al 5 % y 11,1° al 2 % en el peor tono). El APA102 evita parte del problema con su campo de 5 bits, que atenúa el PWM sin tocar los valores RGB; a cambio, ese campo solo tiene 31 pasos.
- Dithering temporal: alternar entre dos valores vecinos en cuadros sucesivos da valores intermedios. Las bibliotecas como FastLED lo hacen de forma automática y mejoran mucho los atenuados lentos, a costa de mostrar cuadros a unos 100 Hz o más.
Para crear colores, se trabaja en HSV (tono, saturación, valor) y se convierte a RGB al final: variar solo el tono recorre el arcoíris, y variar solo el valor atenúa sin cambiar el color. Y hay que conocer el orden de bytes de la tira (GRB, RGB, BRG): una tira con el orden equivocado muestra el verde como rojo. Las tiras RGBW (SK6812) agregan un LED blanco, que da un blanco más puro y consume menos que mezclar los tres canales.
08 · Imágenes en movimiento
Animaciones y matrices
La estructura de todo programa de tiras es la misma: un arreglo leds[N] en memoria (3 bytes por LED: 900 bytes para 300, que son casi la mitad de los 2 KB de un Arduino Uno, y 3000 bytes para 1000, que ya no caben), una función que lo modifica según el tiempo y un show() que lo envía. La animación debe ser no bloqueante: se calcula un cuadro cuando venció el período, no con delay(), para que el resto del programa (sensores, botones) siga funcionando.
- Arcoíris: el tono de cada LED es
desplazamiento + i × 255 / N; el desplazamiento avanza en cada cuadro. - Cometa o persecución: un píxel avanza y los demás se atenúan un poco en cada cuadro (
fadeToBlackBy), lo que deja una cola sin dibujarla. - Respiración: el valor sigue una onda senoidal, con gamma para que parezca uniforme.
- Reaccionar a sensores: el nivel de un sensor de sonido (tema 23) o un potenciómetro se dibuja como una barra de LEDs, o un acelerómetro (tema 20) mueve un punto.
Una matriz de LEDs es una tira plegada. Lo habitual es la disposición en serpentina, en la que las filas pares van de izquierda a derecha y las impares de derecha a izquierda, para que los cables de unión sean cortos. El índice del LED se calcula con una función:
En una matriz de 16 × 16 (256 LEDs), la fila 0 va de 0 a 15 y la fila 1, de 31 a 16. Con esa función, el resto del programa dibuja con coordenadas (x, y) y desconoce el cableado, algo que se agradece cuando el panel se rearma de otra manera. Una matriz de 256 LEDs a blanco necesita 15 A, de modo que el brillo máximo es un parámetro de diseño, no un detalle.
09 · Programación
Código para manejar tiras
Tres piezas: una animación de arcoíris no bloqueante con la biblioteca Adafruit NeoPixel, el mapeo de una matriz en serpentina y el envío de una trama APA102 por SPI.
#include <Adafruit_NeoPixel.h>
const uint8_t PIN_TIRA = 6;
const uint16_t N = 60;
Adafruit_NeoPixel tira(N, PIN_TIRA, NEO_GRB + NEO_KHZ800);
const uint32_t PERIODO_MS = 20; // 50 cuadros por segundo
uint32_t ultimoCuadro = 0;
uint16_t desplazamiento = 0;
void setup() {
tira.begin();
tira.setBrightness(80); // 31 % del máximo: limita la corriente
}
void loop() {
if (millis() - ultimoCuadro >= PERIODO_MS) { // sin delay: el resto del programa sigue vivo
ultimoCuadro += PERIODO_MS;
for (uint16_t i = 0; i < N; i++) {
uint16_t tono = desplazamiento + (uint32_t)i * 65536UL / N;
tira.setPixelColor(i, tira.gamma32(tira.ColorHSV(tono))); // HSV -> RGB y corrección gamma
}
tira.show(); // ~2,1 ms con 60 LEDs, con interrupciones desactivadas
desplazamiento += 256;
}
// aquí se leen sensores y botones sin esperar
}
// --- Matriz en serpentina: (x, y) -> índice del LED ---
uint16_t indice(uint8_t x, uint8_t y, uint8_t ancho) {
return y * ancho + ((y & 1) ? (ancho - 1 - x) : x);
}
// --- Trama APA102 por SPI (reloj y datos) ---
struct Pixel { uint8_t r, g, b; };
void enviarApa102(const Pixel *p, uint16_t n, uint8_t brilloGlobal) { // brilloGlobal: 0 a 31
SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
for (uint8_t i = 0; i < 4; i++) SPI.transfer(0x00); // inicio: 32 bits en cero
for (uint16_t i = 0; i < n; i++) {
SPI.transfer(0xE0 | (brilloGlobal & 0x1F)); // 111 + 5 bits de brillo
SPI.transfer(p[i].b); SPI.transfer(p[i].g); SPI.transfer(p[i].r);
}
for (uint16_t i = 0; i < (n + 15) / 16; i++) SPI.transfer(0xFF); // fin: N/2 bits en 1
SPI.endTransaction();
}
La separación es la de siempre: el programa trabaja con indice(x, y) y colores HSV, y solo el módulo de la tira conoce el protocolo, el orden de bytes y el límite de brillo. Pasar de WS2812 a APA102 cambia ese módulo y nada más.
10 · Verificación
Fallas y verificación
| Síntoma | Causa | Defensa |
|---|---|---|
| Parpadeos o colores al azar | Señal débil (3,3 V), sin masa común, cable largo | Adaptador de nivel, masa común, resistencia de 330 Ω, cable corto |
| El primer LED se ve mal o se daña | Alimentación conectada antes que la masa; picos de arranque | Capacitor de 1000 µF, masa primero |
| El blanco vira a amarillo o rojo al final | Caída de tensión | Inyección de alimentación, limitar el brillo |
| Colores permutados (verde en lugar de rojo) | Orden de bytes equivocado | Configurar GRB, RGB o BRG |
| Los LEDs más allá de uno nunca se encienden | Ese LED o su DIN está dañado | Cortar y puentear; usar WS2813 con línea de respaldo |
Pérdida de millis() o de bytes serie | show() con interrupciones desactivadas | Menos LEDs por salida, RMT o DMA, o APA102 |
| Reinicios de la placa al encender blanco | Fuente débil o regulador de la placa sobrecargado | Fuente propia, presupuesto de corriente por software |
| Atenuado escalonado en tonos oscuros | Pocos niveles de 8 bits | Dithering temporal, campo global del APA102 |
| Rayas en la cámara | PWM de 400 Hz | APA102 (20 kHz) |
- Probá con pocos LEDs primero (uno, luego diez): un programa que funciona con 10 y falla con 300 apunta a tiempo o a energía.
- Encendé todo en blanco al 100 % un instante, con la fuente a mano, y medí la tensión en el último LED.
- Medí el tiempo de
show()conmicros()y compará con 30·N + 300 µs. - Verificá el orden de colores con un rojo, un verde y un azul puros.
- Mirá el peor caso de la animación: no solo el cuadro típico, sino el de más corriente.
11 · Analogía con programación
Tramas, consumo, caída de tensión y resolución
Calculemos los cuatro elementos del tema: el tiempo de trama de las dos familias, la corriente de una tira, la caída de tensión con inyecciones y la pérdida de resolución de color al atenuar.
Python en tu navegador. Los bloques son editables: cambiá los valores y presioná «Ejecutar Python». La primera vez tarda unos segundos en cargar.
import colorsys
import math
T_BIT, RESET = 1.25e-6, 300e-6 # WS2812B a 800 kHz y pausa de latch con margen
I_LED, I_REPOSO = 0.060, 0.001 # A por LED a blanco pleno y en reposo
R_LAZO = 0.005 # ohm de ida y vuelta por LED (modelo ilustrativo)
def t_ws2812(n):
return n * 24 * T_BIT + RESET
def t_apa102(n, f):
bits = 32 + 32 * n + 8 * ((n + 15) // 16)
return bits / f
print("LEDs WS2812: trama fps APA102 a 8 MHz fps RAM (3 B/LED)")
for n in (30, 60, 144, 300, 1000):
tw, ta = t_ws2812(n), t_apa102(n, 8e6)
print(f"{n:5d} {tw * 1000:9.3f} ms {1 / tw:6.0f} {ta * 1000:10.3f} ms {1 / ta:7.0f} {3 * n:8d} B")
print(f"Tiempo de un LED: {24 * T_BIT * 1e6:.0f} µs; bits en 1 s: {1 / T_BIT:.0f}")
def arcoiris_medio():
suma = 0.0
for h in range(360):
r, g, b = colorsys.hsv_to_rgb(h / 360, 1, 1)
suma += (r + g + b) / 3
return suma / 360
print()
print("LEDs blanco pleno arcoíris (%.0f %% del pleno) fuente 5 V sugerida" % (arcoiris_medio() * 100))
for n in (30, 60, 144, 300):
pleno = n * I_LED + n * I_REPOSO
medio = n * I_LED * arcoiris_medio() + n * I_REPOSO
print(f"{n:5d} {pleno:8.2f} A {medio:14.2f} A {math.ceil(pleno * 1.2):4d} A")
print()
for k in (30, 60, 100, 150):
caida = R_LAZO * I_LED * k * (k + 1) / 2
print(f"inyección cada {k:3d} LEDs en blanco pleno: caída {caida:5.2f} V -> {5 - caida:4.2f} V al final del tramo")
def tono(r, g, b):
return colorsys.rgb_to_hsv(r / 255, g / 255, b / 255)[0] * 360
print()
for escala in (0.50, 0.10, 0.05, 0.02):
peor = 0.0
for h in range(360):
r, g, b = (round(c * 255) for c in colorsys.hsv_to_rgb(h / 360, 1, 1))
r2, g2, b2 = int(r * escala), int(g * escala), int(b * escala)
if max(r2, g2, b2) == 0:
continue
d = abs(tono(r, g, b) - tono(r2, g2, b2))
peor = max(peor, min(d, 360 - d))
print(f"brillo {escala * 100:3.0f} %: {int(255 * escala) + 1:3d} niveles por canal, error de tono hasta {peor:4.1f}°; con el campo global de 5 bits: {round(escala * 31)}/31 sin tocar los valores")
def indice(x, y, ancho):
return y * ancho + (x if y % 2 == 0 else ancho - 1 - x)
print()
print("Matriz 16 x 16 en serpentina:", [indice(x, 1, 16) for x in (0, 1, 15)], "y la fila 0:", [indice(x, 0, 16) for x in (0, 1, 15)])
Resultado: un LED WS2812 tarda 30 µs; 60 LEDs, 2,100 ms (476 cuadros por segundo); 300 LEDs, 9,300 ms (108) y 1000 LEDs, 30,3 ms (33). Un APA102 a 8 MHz envía 300 LEDs en 1,223 ms (818 cuadros por segundo). La memoria es de 3 bytes por LED (900 B para 300). A blanco pleno, 60 LEDs piden 3,66 A y 300 LEDs, 18,3 A; un arcoíris usa el 50 % del pleno (9,3 A para 300). Con inyección cada 30, 60, 100 y 150 LEDs la tensión al final del tramo es de 4,86 · 4,45 · 3,49 y 1,60 V. Al atenuar, el brillo del 50 % deja 128 niveles y un error de tono de 0,2°; el del 10 %, 26 niveles y 1,9°; el del 5 %, 13 niveles y 4,0°; el del 2 %, 6 niveles y 11,1°. En serpentina de ancho 16, la fila 1 empieza en el LED 31.
12 · Exploración interactiva
Bits, tramas, corriente y brillo
El primer instrumento dibuja los pulsos de un byte del WS2812 y muestra qué ocurre cuando una interrupción alarga un nivel. El segundo calcula el tiempo de trama y la memoria. El tercero estima corriente y caída de tensión, con el modelo ilustrativo de la sección 5 (60 mA por LED, 5 mΩ de lazo por LED). El cuarto compara las dos formas de atenuar un color.
Instrumento 1: los pulsos de un byte
Instrumento 2: trama, tiempo y memoria
Instrumento 3: corriente y caída de tensión
Instrumento 4: atenuar sin deformar el color
Recorrido guiado
- Con el byte 165 (10100101) y sin retraso: cada bit dura 1,25 µs, el byte 10 µs y el LED recibe el mismo 165. Los bits en 1 tienen el nivel alto largo (0,8 µs) y los 0, corto (0,4 µs).
- Poné un retraso de 1 µs durante el nivel alto del bit 4 (que vale 0): el nivel alto pasa a 1,4 µs, el receptor lo lee como un 1 y el byte recibido es 181, no 165. Esto es lo que ocurre si una interrupción cae en medio de un bit.
- Cambiá a «nivel bajo» con 60 µs: un nivel bajo largo no cambia el bit mientras no llegue al reset. Con el chip de 50 µs, en cambio, 60 µs provocan un latch prematuro: los bits siguientes se pierden. Con el chip de 280 µs, 60 µs son tolerables; probá 300.
- En el instrumento 2, con 300 LEDs WS2812 y 60 cuadros por segundo: 9,3 ms por trama, máximo 108 cuadros y el 56 % del tiempo con interrupciones desactivadas. Pasá a 1000 LEDs: el máximo cae a 33 cuadros por segundo y 3000 bytes no caben en un Uno.
- Elegí APA102 a 8 MHz con 300 LEDs: 1,22 ms por trama y sin bloqueo de interrupciones. Con 1 MHz tarda 9,8 ms, casi lo mismo que el WS2812.
- En el instrumento 3, 60 LEDs a blanco pleno alimentados por un extremo: 3,66 A y la tensión baja a 4,45 V al final. Con una fuente de 2 A, el estado indica fuente insuficiente. Subí a 150 LEDs con una fuente de 10 A: la caída pasa de 3 V (quedan 1,6 V) y los datos del final se perderían.
- Con 150 LEDs, inyectá cada 30: la tensión en el último LED sube a 4,86 V, pero la corriente total sigue siendo de 9 A, y la fuente tiene que dar eso. Bajá el brillo al 40 %: la corriente baja en proporción.
- En el instrumento 4, con tono 4° (un rojo con un poco de naranja) y 5 % escalando los valores: 13 niveles por canal, el verde de 17 se trunca a 0 y el error de tono es de 4,0°, el peor caso de la tabla. Pasá a «campo global»: el tono no se desvía, aunque el brillo queda en 2/31. Bajá el brillo al 1 % y mirá cómo se escalona.
Desafío: un reloj de pared con un anillo de 60 LEDs
Un anillo de 60 WS2812 muestra la hora con tres LEDs (horas, minutos y segundos) y una marca tenue cada 5 posiciones. ¿Qué fuente hace falta y cada cuánto se envía una trama? Solo se encienden 3 LEDs de color más 12 marcas al 10 %: con brillo limitado al 50 %, 3 × 60 mA × 0,5 + 12 × 60 mA × 0,1 × 0,5 + 60 mA de reposo ≈ 0,19 A; un adaptador de 1 A sobra. La imagen solo cambia una vez por segundo, así que basta una trama por segundo (2,1 ms con interrupciones desactivadas), o menos si el segundero se mueve sin barrido. Si se agrega un barrido suave del segundero a 30 cuadros por segundo, el tiempo bloqueado sería 63 ms por segundo, un 6 %: aceptable. El cuidado está en la cola del arcoíris al arrancar: encender los 60 LEDs en blanco de golpe supone 3,7 A.
13 · Método de trabajo
Cómo integrar una tira, para cualquier proyecto
- Elegí la familia: WS2812 si el precio y el tamaño mandan; APA102 si hay cámaras, tiras largas con pocos recursos o un microcontrolador ocupado.
- Calculá el tiempo de trama (30·N + 300 µs para WS2812) y verificá que los cuadros por segundo y el tiempo bloqueado son aceptables.
- Dimensioná la fuente con 60 mA por LED, margen del 20 % y fusible, y limitá el brillo por software.
- Inyectá alimentación en puntos intermedios y a ambos extremos, con masa común.
- Adaptá el nivel lógico (74AHCT125), con resistencia de datos y capacitor de 1000 µF; conectá primero la masa.
- Trabajá en HSV, con tabla gamma, y atenuá con cuidado de la resolución.
- Animá sin bloqueos con
millis()y un arreglo en memoria; ocultá el mapeo de la matriz trasindice(x, y). - Probá el peor caso: todo en blanco y la tira entera, midiendo tensión en el último LED.
Si hay colores al azar, revisá el nivel lógico, la masa y el cable; si el final de la tira vira a rojo, la tensión cae; si la placa se reinicia, la fuente no alcanza; si el tono se desvía al atenuar, faltan niveles.
14 · Comprensión
Confusiones frecuentes
«Un WS2812 es un LED RGB con un cable más»
Es un LED RGB con un chip que guarda el color, mantiene el PWM y regenera la señal para el siguiente. Por eso los datos pasan de un LED al siguiente y se necesitan tiempos precisos.
«Con digitalWrite alcanza para manejar una tira»
Cada bit dura 1,25 µs y un digitalWrite tarda más que eso. Se usan rutinas de ciclos contados (con interrupciones desactivadas) o hardware dedicado: RMT, SPI con DMA o PIO.
«Si el brillo está al 10 %, consume el 10 %»
Aproximadamente sí, pero solo cuenta lo que se muestra: una tira de 300 LEDs a blanco y brillo 10 % pide 1,8 A, y los 300 mA de reposo ya están presentes aunque esté apagada.
«La caída de tensión solo importa en tiras de muchos metros»
Con 60 LEDs a blanco y alimentación por un extremo ya se pierde más de 0,5 V. Cuanto más blanco y más brillo, más corriente en el cobre y más caída.
«Una salida de 3,3 V alcanza para una tira de 5 V»
El WS2812B pide 3,5 V para un nivel alto. A veces funciona, y otras falla con el calor o el largo del cable. Se usa un adaptador de nivel.
«El APA102 es mejor en todo»
Es más rápido, sin tiempos críticos y con mejor PWM, pero necesita un hilo más, cuesta más y consume algo más. Para pocas decenas de LEDs, el WS2812 es suficiente.
15 · Práctica guiada
Predecí antes de comprobar
1. Tiempo de trama
Una tira WS2812 de 120 LEDs: ¿cuánto tarda una trama y cuántos cuadros por segundo admite como máximo?
Ver solución
120 × 30 µs + 300 µs = 3900 µs = 3,9 ms; 1 / 0,0039 = 256 cuadros por segundo.
2. Corriente
Los mismos 120 LEDs en blanco con el brillo limitado al 40 %: ¿qué corriente piden?
Ver solución
120 × 0,060 A × 0,4 = 2,88 A, más el reposo (120 × 1 mA = 0,12 A): 3,0 A. Una fuente de 4 A da el margen del 20 %.
3. APA102
Los 120 LEDs son APA102 con el reloj a 4 MHz. ¿Cuántos bits tiene la trama y cuánto tarda?
Ver solución
32 + 32 × 120 + 8 × ((120 + 15) // 16) = 32 + 3840 + 64 = 3936 bits; 3936 / 4 000 000 = 0,98 ms, cuatro veces menos que el WS2812.
4. Memoria
¿Cabe el arreglo de 800 LEDs en un Arduino Uno, que tiene 2048 bytes de RAM?
Ver solución
800 × 3 = 2400 bytes: no cabe, ni sin el resto del programa. Hay que usar una placa con más RAM (ESP32), dividir la tira en segmentos que se calculan al vuelo, o generar los colores con una función sin guardarlos.
5. Caída de tensión
Con inyección cada 50 LEDs en blanco pleno, R de lazo de 5 mΩ por LED y 60 mA por LED: ¿qué tensión llega al final de cada tramo?
Ver solución
Caída = 0,005 × 0,060 × 50 × 51 / 2 = 0,38 V; llegan 4,62 V: aceptable.
6. Diagnóstico
Una tira de 5 m funciona bien con animaciones de colores, pero al mostrar blanco, el último metro se ve amarillento y, a veces, la placa se reinicia. ¿Qué pasa y qué cambiás?
Ver solución
Dos efectos del mismo origen: el blanco pide la corriente máxima, la tensión cae a lo largo de la tira (los LEDs azules y verdes se apagan primero y el blanco vira a amarillo) y la fuente o el regulador no alcanzan, de ahí el reinicio. Se agregan inyecciones de alimentación cada 1 o 2 m, se usa una fuente propia de mayor corriente y se limita el brillo por software.
16 · Síntesis
Ideas para recordar
- Una tira direccionable pone un controlador en cada LED: se envía el color de todos los píxeles por un solo cable y cada chip regenera la señal para el siguiente.
- El WS2812 codifica el bit en la duración del nivel alto (0,4 µs para 0, 0,8 µs para 1, 1,25 µs por bit); 24 bits por LED en orden GRB; el reset es una pausa en bajo de más de 50 a 280 µs.
- El tiempo de trama es 30·N + 300 µs: 9,3 ms para 300 LEDs; por software se envía con interrupciones desactivadas, o con RMT, SPI y DMA o PIO.
- El APA102 usa reloj y datos, sin tiempos críticos, PWM de ~20 kHz y un campo de brillo global de 5 bits: 300 LEDs en 1,2 ms a 8 MHz.
- Cada píxel pide hasta 60 mA: se dimensiona la fuente con margen del 20 %, se limita el brillo por software y se inyecta alimentación a lo largo de la tira.
- La caída de tensión hace virar el blanco a amarillo y rojo, y por debajo de ~3,5 V los datos se corrompen.
- Con 5 V de alimentación, la señal de 3,3 V necesita adaptador de nivel; además, resistencia de datos, capacitor de 1000 µF y masa común conectada primero.
- Se trabaja en HSV con gamma; atenuar escalando los valores reduce los niveles y desvía el tono; las animaciones no bloqueantes y el mapeo (x, y) esconden el hardware.
¿Listo para el tema 37?
Antes de avanzar, calculá el tiempo de trama y la corriente de una tira WS2812 de 200 LEDs a blanco con el 40 % de brillo, explicá por qué una interrupción en medio de un bit cambia el color y decí qué se hace cuando el blanco del final de la tira se ve amarillento. Si podés justificar las tres respuestas, ya sabés manejar tiras direccionables.
En el próximo tema pasamos de la luz a la información: los displays de 7 segmentos y los LCD de caracteres, con multiplexación, drivers TM1637 y MAX7219 y el LCD 16×2 con I2C.