Módulo LED
El módulo LED maneja tiras y matrices de LEDs de colores WS2812 (también llamados NeoPixel): las que llevan un chip en cada LED y se encadenan por un solo cable de datos. LED.new crea una tira en un pin; con sus métodos pones el color de cada LED y el brillo de toda la tira, y show() lo manda a los LEDs.
use LED
Plataformas
| Windows | ESP32 / ESP32-S3 | ESP32-P4 | ESP32-S31 | |
|---|---|---|---|---|
| Dónde se ve | En la tarjeta WS2812 Strip del simulador GPIO | En la tira conectada al pin | En la tira conectada al pin | En la tira conectada al pin |
| Tiras a la vez | 8, con 2.048 LEDs entre todas | Una por canal RMT de transmisión del chip: 8 en el ESP32 y 4 en el ESP32-S3 | Una por canal RMT libre | Una por canal RMT libre |
| Memoria por LED | 3 bytes | 99 bytes: una tira de 1.024 LEDs gasta unos 100 KB | 6 bytes | 6 bytes |
setOrder | No cambia lo que se ve | Cambia el orden en que se mandan los colores | Igual | Igual |
setBrightness con un decimal | Pone el brillo a 255 | Usa la parte entera | Igual | Igual |
En Windows, el módulo no necesita el simulador abierto: guarda la tira en una memoria que comparte con él, y la tarjeta la pinta en cuanto la ve. En el recorrido del simulador tienes el ejemplo LedStrip paso a paso.
Funciones
| Función | Qué hace | Devuelve |
|---|---|---|
LED.new(pin, n) | Crea una tira de n LEDs en un pin | La tira |
new(pin, n)
Crea una tira de n LEDs conectada al pin pin.
| Parámetro | Tipo | Descripción |
|---|---|---|
pin | entero | El GPIO al que va el cable de datos de la tira. La VM no comprueba que el pin exista ni que esté libre. |
n | entero | Cuántos LEDs tiene la tira, de 1 a 1024. |
Devuelve la tira, con todos los LEDs a negro, el brillo a 255 y el orden de colores LED.GRB. No enciende nada hasta el primer show().
Si algo falla, lanza una excepción, que se captura con try (ver Errores y excepciones):
| Error | Cuándo |
|---|---|
ERR_INVALID_ARG_NUMBER | No le pasas dos argumentos. |
ERR_INVALID_VALUE | n no está entre 1 y 1024. |
ERR_TYPE_MISMATCH | En las placas, pin o n no son enteros. En Windows, un pin que no es entero cuenta como 0, y un n que no es entero da el error de arriba. |
ERR_INVALID_OPERATION | No cabe otra tira: en Windows, ya hay 8 o se pasaría de 2.048 LEDs; en la placa, no queda ningún canal RMT libre. |
ERR_OUT_OF_MEMORY | No hay memoria para la tira. |
use LED
var tira = LED.new(17, 8) // 8 LEDs en el GPIO 17
println(tira.length()) // 8
Métodos de la tira
La tira guarda el color de cada LED en memoria. Los métodos que ponen colores solo cambian esa memoria: los LEDs no cambian hasta que llamas a show().
Los LEDs se cuentan desde 0: en una tira de n, van de 0 a n - 1. Los colores van en tres números de 0 a 255 (rojo, verde y azul) o en HSV: el tono en grados y la saturación y el valor de 0 a 255.
| Método | Qué hace | Devuelve |
|---|---|---|
setPixel(i, r, g, b) | Pone el color de un LED | true |
setHSV(i, h, s, v) | Pone el color de un LED, en HSV | true |
getPixel(i) | Lee el color de un LED | Una lista [r, g, b] |
fill(r, g, b) | Pone todos los LEDs del mismo color | true |
fillHSV(h, s, v) | Lo mismo, en HSV | true |
clear() | Pone todos los LEDs a negro | true |
setBrightness(v) | Fija el brillo de toda la tira, de 0 a 255 | true |
setOrder(orden) | Dice en qué orden espera la tira los colores | true |
show() | Manda los colores a los LEDs | true |
length() | Cuántos LEDs tiene la tira | Un entero |
close() | Apaga los LEDs y libera la tira | true |
Errores comunes a todos ellos (excepciones):
ERR_INVALID_ARG_NUMBERsi el número de argumentos no es el que pide el método.ERR_INDEX_OUT_OF_RANGEsi el LEDino está en la tira.ERR_INVALID_OPERATIONsi la tira está cerrada conclose().
setPixel(i, r, g, b)
Pone el color del LED i. r, g y b son el rojo, el verde y el azul, de 0 a 255: lo que se pase de ese rango se recorta (300 se queda en 255, y -5, en 0).
Los cuatro tienen que ser enteros. Un color decimal cuenta como 0, y un i decimal da ERR_INDEX_OUT_OF_RANGE: pasa antes los decimales a entero con int() o Math.floor.
use LED
var tira = LED.new(17, 8)
tira.setPixel(0, 255, 0, 0) // el primero, rojo
tira.setPixel(7, 0, 0, 255) // el último, azul
tira.setPixel(1, 300, -5, 128) // se recorta
println(tira.getPixel(1)) // [255, 0, 128]
tira.show()
setHSV(i, h, s, v)
Pone el color del LED i en HSV, que es más cómodo para arcoíris y degradados:
h, el tono, en grados: 0 es rojo, 120 verde y 240 azul. Da la vuelta: 480 es 120, y -120 es 240.s, la saturación, de 0 a 255. Con 0, el LED es gris (o blanco), del valor dev.v, el valor (cuánta luz), de 0 a 255.
s y v no se recortan: fuera de 0 a 255 sale otro color. Como en setPixel, los cuatro tienen que ser enteros.
use LED
var tira = LED.new(17, 3)
tira.setHSV(0, 0, 255, 255) // rojo
tira.setHSV(1, 120, 255, 255) // verde
tira.setHSV(2, 240, 255, 255) // azul
println(tira.getPixel(1)) // [0, 255, 0]
tira.show()
getPixel(i)
Devuelve el color del LED i como una lista [r, g, b]. Es el color que guarda la tira, sin el brillo: después de setBrightness(32), un LED rojo sigue siendo [255, 0, 0]. Un color puesto en HSV sale convertido a rojo, verde y azul.
fill(r, g, b)
Pone todos los LEDs del mismo color. Los valores se recortan y tienen que ser enteros, como en setPixel.
fillHSV(h, s, v)
Pone todos los LEDs del mismo color, en HSV, como setHSV.
use LED
var tira = LED.new(17, 8)
tira.fillHSV(30, 255, 255) // naranja
println(tira.getPixel(0)) // [255, 127, 0]
tira.fillHSV(0, 0, 100) // gris
println(tira.getPixel(0)) // [100, 100, 100]
tira.show()
clear()
Pone todos los LEDs a negro. Como los demás, no apaga nada hasta el siguiente show().
setBrightness(v)
Fija el brillo de toda la tira, de 0 (apagada) a 255 (el de serie). Lo que se pase de ese rango se recorta.
El brillo se aplica al mandar los colores con show(): cada color se multiplica por (v + 1) / 256. Los colores que guarda la tira no cambian, así que puedes subir y bajar el brillo sin perderlos, y getPixel los devuelve sin él.
use LED
var tira = LED.new(17, 8)
tira.fill(255, 120, 0) // todos naranja
tira.setBrightness(32) // a un octavo de brillo
tira.show()
println(tira.getPixel(0)) // [255, 120, 0]
En las placas, un decimal vale por su parte entera, y un valor que no es un número da ERR_TYPE_MISMATCH. En Windows, cualquier cosa que no sea un entero pone el brillo a 255. Pasa el brillo como entero.
setOrder(orden)
Dice en qué orden espera la tira los tres colores. La mayoría de las WS2812 los quieren en verde, rojo y azul, que es lo de serie (LED.GRB). Si tu tira enseña el rojo cuando pides verde, prueba con otra de las constantes.
setPixel, fill y getPixel siguen hablando en rojo, verde y azul: el orden solo cambia lo que se manda a la tira. Un valor que no es una de las constantes da ERR_INVALID_VALUE.
use LED
var tira = LED.new(17, 8)
tira.setOrder(LED.RGB) // esta tira espera rojo, verde y azul
En Windows, la tarjeta del simulador enseña los colores tal cual los pone el programa, y setOrder no cambia nada.
show()
Manda a los LEDs los colores de la tira, con el brillo aplicado. En la placa, el programa espera a que acabe de mandarlos. En Windows, la tarjeta WS2812 Strip del simulador se pinta en ese momento.
Devuelve true; en una placa, false si no se ha podido mandar.
length()
Devuelve cuántos LEDs tiene la tira: el n de LED.new. Sigue funcionando después de close().
close()
Apaga los LEDs (manda negro a toda la tira) y libera su memoria y su canal, para que otra tira pueda usarlo. Después, los métodos que tocan colores dan ERR_INVALID_OPERATION. Llamarlo otra vez no hace nada y devuelve true.
use LED
var tira = LED.new(17, 8)
tira.fill(0, 255, 0)
tira.show()
pause(1000)
tira.close() // la tira se apaga
Constantes
El orden de los colores para setOrder:
| Constante | Valor | Orden en que se mandan |
|---|---|---|
LED.GRB | 0 | Verde, rojo, azul. Es el de serie, el de la mayoría de las WS2812. |
LED.RGB | 1 | Rojo, verde, azul. |
LED.BRG | 2 | Azul, rojo, verde. |
LED.RBG | 3 | Rojo, azul, verde. |
LED.GBR | 4 | Verde, azul, rojo. |
LED.BGR | 5 | Azul, verde, rojo. |
Ejemplo completo
Un arcoíris que da vueltas por una tira de 30 LEDs durante 5 segundos. Después, la apaga:
use LED
const NUM_LEDS = 30
var tira = LED.new(17, NUM_LEDS) // 30 LEDs en el GPIO 17
tira.setBrightness(64) // a un cuarto de brillo
var giro = 0
var inicio = clock()
while (clock() - inicio < 5000)
for (var i = 0; i < NUM_LEDS; i++)
var tono = (i * 360) div NUM_LEDS + giro
tira.setHSV(i, tono, 255, 255)
end
tira.show()
giro = (giro + 6) % 360
pause(30)
end
tira.close() // apaga la tira y la libera
El ejemplo LedStrip
JARU IDE trae el proyecto de ejemplo LedStrip: 17 programas para una matriz de 8 × 8 LEDs (una tira de 64) en el GPIO 17, con plasma, fuego, fuegos artificiales, el juego de la vida, una cuenta atrás… Lo creas desde Home › Project › New, en Example Projects. Su programa principal es Code/Matrix8x8Plasma.aru; para probar otro, elígelo en la lista Main File del explorador y pulsa Run (Proyectos).
Los programas cuentan los LEDs fila a fila, con una función como esta:
use LED
const ANCHO = 8
var tira = LED.new(17, 64)
func xy(x, y)
return y * ANCHO + x // fila a fila, de izquierda a derecha
end
tira.setPixel(xy(3, 2), 255, 0, 0) // columna 3, fila 2
tira.show()
Si tu matriz va cableada en zigzag (una fila de cada dos al revés), cambia esa cuenta. En Windows, la forma y el cableado de la matriz se eligen en la tarjeta del simulador, en Layout y Wiring.
Trampas y problemas conocidos
- Nada se ve hasta
show().setPixel,fill,clearysetBrightnesssolo cambian lo que guarda la tira. - Los colores, en enteros. Un color decimal cuenta como 0, sin error:
tira.setPixel(0, 127.5, 0, 0)deja el LED apagado. Usaint(),divoMath.floor. - En HSV, la saturación y el valor no se recortan. Fuera de 0 a 255 salen colores que no esperas.
- El brillo con decimales, en Windows.
setBrightnesscon un decimal pone el brillo a 255 en Windows y usa la parte entera en la placa. Pásalo como entero. - Sin
close(), los LEDs se quedan encendidos. Si el programa acaba sin cerrar la tira, en la placa los LEDs siguen con los últimos colores que les llegaron. - La memoria en ESP32 y ESP32-S3. Cada LED gasta 99 bytes de la memoria de la VM mientras la tira está abierta. En una placa sin PSRAM, una tira larga puede dejar al programa sin memoria.
- El sitio de una tira cerrada, en Windows. Al cerrar una tira, su hueco entre los 2.048 LEDs no se aprovecha mientras siga abierta otra creada después.
Todos los problemas conocidos de JARU, juntos, están en Problemas conocidos.