Repository navigation
LEDPixelsJSONConfig
This page describes the JSON used to configure LEDPixels. The configuration is normally an entry in the Devices array of a SysType (see SysTypes), where the class is the name the application registered its LEDPixelsDevice (or subclass) under, normally LEDPixels.
The same JSON can also be passed directly to LEDPixels::setup(const RaftJsonIF&) when LEDPixels is used without the device wrapper.
{
"class": "LEDPixels",
"name": "LEDs",
"brightnessPC": 100,
"strips": [
{ LEDStripConfig },
{ LEDStripConfig }
],
"segments": [
{ LEDSegmentConfig },
{ LEDSegmentConfig }
]
}| Setting | Description | Type | Default |
|---|---|---|---|
class |
Device class name used to find the device in the device factory. Standard device setting, not read by LEDPixels. | string | required |
name |
Device name. Standard device setting. | string | |
brightnessPC |
Global brightness as a percentage. Used as the brightness of any segment that doesn't set its own brightnessPC. |
number | 100 |
strips |
Array of LED strip (hardware) configurations. At least one is required, otherwise setup fails. | array | required |
segments |
Array of logical segments. Optional: if omitted, a single segment called All covering every pixel is created. |
array | [] |
Applications that subclass LEDPixelsDevice may read their own extra settings from the same object.
All strips are joined into a single pixel buffer in the order they appear in strips. A segment is a range of that buffer given by start and num.
strips: [ strip 0: pin 18, num 6 ][ strip 1: pin 40, num 20 ]
buffer: 0 1 2 3 4 5 6 7 8 ... 25
segments: [st][ slots ] [ ring ]
0 1..5 6..25
- A segment's
startis an offset into the whole buffer, not into a strip. - A segment should sit within one strip. One that spans strips logs a warning (
segment X spans strips a..b); it still works, but it uses the colour order of the strip its first pixel is in. - Segments may overlap, but each segment's pattern writes its pixels independently, so overlapping segments overwrite each other.
Each strip is driven by its own ESP32 RMT TX channel. The number of strips is limited by the number of RMT TX channels on the chip (for example 8 on ESP32, 4 on ESP32-S3, 2 on ESP32-C3).
| Setting | Description | Type | Default | Example |
|---|---|---|---|---|
pin |
GPIO pin for the strip's data line. Required: a missing or negative value makes the strip, and so the whole setup, invalid. | integer | required | 18 |
num |
Number of pixels in the strip. Values above 2000 are clamped to 2000. | integer | 60 |
120 |
colorOrder (or colourOrder) |
Order of the colour bytes on the wire. Also sets the bytes per pixel. See Colour orders. | string | GRB |
RGB, GRBWC
|
bpp |
Bytes per pixel. Only used when colorOrder is not set. If both are set, bpp is ignored and a warning is logged. |
integer | 3 |
5 |
colorOrder |
Bytes per pixel | Wire order | Typical parts |
|---|---|---|---|
RGB |
3 | R, G, B | Some WS2811-based strips |
GRB |
3 | G, R, B | WS2812B, SK6812 (RGB) |
BGR |
3 | B, G, R | |
RGBWW |
5 | R, G, B, cold white, warm white | WS2805 |
GRBWW |
5 | G, R, B, cold white, warm white | |
GRBWC |
5 | G, R, B, warm white, cold white |
Names are case-insensitive, and an unrecognised name is treated as RGB. With a 3-byte order, the white values in RRGGBBCCWW colours and setRGBWW() calls are dropped. With a 5-byte order, plain RGB colours set both white channels to 0.
The defaults suit WS2812B. Times are in microseconds and are converted to RMT ticks using rmtHz, so at the default 10 MHz the resolution is 0.1 µs.
| Setting | Description | Type | Default |
|---|---|---|---|
rmtHz |
RMT channel resolution in Hz. | integer | 10000000 |
T0H |
High time for a 0 bit (µs). Legacy name bit0_0Us. |
number | 0.4 |
T0L |
Low time for a 0 bit (µs). Legacy name bit0_1Us. |
number | 0.85 |
T1H |
High time for a 1 bit (µs). Legacy name bit1_0Us. |
number | 0.8 |
T1L |
Low time for a 1 bit (µs). Legacy name bit1_1Us. |
number | 0.45 |
resetUs |
Reset (latch) low time after each frame (µs). | number | 100 |
msbFirst |
Send the most significant bit of each byte first. | boolean | true |
| Setting | Description | Type | Default |
|---|---|---|---|
memBlockSymbols |
RMT memory block size in symbols. RMT memory is allocated in chip-specific blocks (64 symbols on ESP32, 48 on S3/C3/C6/H2). Increasing it can reduce flicker on long strips. | integer | 64 |
transQueueDepth |
RMT transaction queue depth. Keep at 1: the transmit buffer is reused, so queued transactions could send corrupted data. | integer | 1 |
minChunkSize |
Reserved for the encoder. Read but not currently used. | integer | 64 |
blockingShow |
When true, show() waits for the transmission to finish before returning. |
boolean | false |
beforeDeinitMs |
Extra delay in ms after a blocking show completes, before power-off or peripheral stop. Only used when blockingShow is true. |
integer | 0 |
stopAfterTx |
Release the RMT channel when idle (about 100 ms after the last transmission, or straight after a blocking show). It is set up again on the next show. Useful to save power, or to share the channel. | boolean | false |
allowPowerDown |
Let the RMT channel be powered down in light sleep (its context is saved to RAM). Passed to the ESP-IDF channel config as allow_pd. |
boolean | false |
These settings let a GPIO switch power to the strip, for example through a MOSFET or a regulator enable pin. They only take effect when pwrPin is set.
| Setting | Description | Type | Default |
|---|---|---|---|
pwrPin |
GPIO that controls power to the strip. -1 means no power control. |
integer | -1 |
pwrOnLvl |
Level written to pwrPin to turn power on (1 = high, 0 = low). |
integer | 1 |
offIfBlank |
Turn power off after a frame in which every pixel (apart from the first offBlankExcl1stN) is off. Any non-zero value enables it. If the key is omitted it is enabled. Set 0 to disable it. |
integer | enabled |
offBlankExcl1stN |
Number of pixels at the start of the strip that the offIfBlank check ignores, for pixels that are always powered. |
integer | 0 |
offAfterMs |
Turn power off this many ms after the last transmission, whatever the pixel values. 0 disables it. Unchanged frames are not retransmitted, so a strip showing a steady colour is also turned off after this time. |
integer | 0 |
pwrPinGpioHold |
Use gpio_hold_en() on the power pin so its level holds through light sleep. |
boolean | false |
pwrHoldIfInactive |
With pwrPinGpioHold, also hold the pin while power is off. Otherwise it is only held while power is on. |
boolean | false |
Power is turned on just before the first transmission that needs it, and pixel data is sent straight after. The power pin is set as an input when the driver is destroyed.
| Setting | Description | Type | Default | Example |
|---|---|---|---|---|
name |
Segment name. Used (case-insensitively) to address the segment in the led API and in LEDPixels::getSegmentIdx(). |
string | "" |
"ring" |
start |
Index of the segment's first pixel in the combined pixel buffer. | integer | 0 |
6 |
num |
Number of pixels in the segment. If there is exactly one segment and num is 0 or missing, it covers all pixels. |
integer | 0 |
20 |
brightnessPC |
Brightness scale for this segment (percent). Applied to every RGB, RGBWW and HSV value written through the segment, including by patterns. | number | top-level brightnessPC
|
25 |
pattern |
Name of a registered pattern to start when the device is set up. The pattern must be registered before setup() is called. |
string | none | "Status" |
patternParams |
Parameters for the initial pattern as a query string (name=value&name=value, without a leading ?). They are converted to JSON and passed to the pattern's setup(). Include forMs=<ms> to stop the pattern after that time. |
string | none | "rateMs=1500&rgb=002040" |
colorOrder (or colourOrder) |
Colour order for the segment. It is replaced by the colour order of the strip that contains the segment whenever the strip sets one (a warning is logged if they differ), so it rarely needs to be set. | string | GRB |
"GRB" |
patternMs |
Read but not currently applied. To time-limit the initial pattern, use forMs in patternParams. |
integer | 0 |
|
startupFirstPixel |
Read but not currently applied. | string (hex) | "000000" |
Segments with no pattern are cleared at setup. LEDPixelsDevice also sends an all-off frame after setup, so the strip doesn't keep its power-on state.
{
"class": "LEDPixels",
"name": "LEDs",
"strips": [
{ "pin": 18, "num": 30 }
]
}This creates a single segment called All covering all 30 pixels, so led/All/setall/FF0000 and led/0/setall/FF0000 both work.
The first pixel shows system status using the built-in Status pattern, and the next twelve form a ring that runs a Chase pattern registered by the application (see the example application). indicatorSeg is an extra setting that the example application reads itself.
{
"enable": 1,
"class": "LEDPixels",
"name": "LEDs",
"indicatorSeg": "status",
"strips": [
{ "pin": 18, "num": 13 }
],
"segments": [
{
"name": "status",
"start": 0,
"num": 1,
"brightnessPC": 25,
"pattern": "Status"
},
{
"name": "ring",
"start": 1,
"num": 12,
"brightnessPC": 25,
"pattern": "Chase",
"patternParams": "rateMs=60&tail=4&rgb=0040FF"
}
]
}An RGB status LED on one pin and a 20-pixel RGBWW (WS2805-style, warm/cold white swapped) ring on another:
{
"class": "LEDPixels",
"name": "LEDs",
"strips": [
{ "pin": 13, "num": 1, "colorOrder": "RGB" },
{ "pin": 40, "num": 20, "colorOrder": "GRBWC" }
],
"segments": [
{ "name": "status", "start": 0, "num": 1, "brightnessPC": 50, "pattern": "Status" },
{ "name": "ring", "start": 1, "num": 20, "brightnessPC": 80 }
]
}Each segment takes its colour order from its strip, so led/ring/setall/0000000080 drives only the warm white channel of the ring.
The strip's supply is switched by GPIO 5 (active low). Power is cut whenever all pixels are off, and the pin level is held through light sleep:
{
"class": "LEDPixels",
"name": "LEDs",
"brightnessPC": 40,
"strips": [
{
"pin": 18,
"num": 12,
"pwrPin": 5,
"pwrOnLvl": 0,
"offIfBlank": 1,
"pwrPinGpioHold": true,
"stopAfterTx": true,
"allowPowerDown": true
}
],
"segments": [
{ "name": "ring", "start": 0, "num": 12 }
]
}Breathe blue for 10 seconds at startup, then turn off. This needs an application that registers a Breathe pattern, such as the example application:
"segments": [
{
"name": "ring",
"start": 0,
"num": 12,
"pattern": "Breathe",
"patternParams": "rateMs=2000&rgb1=000000&rgb2=0000FF&forMs=10000"
}
]Example timing for an SK6812-style part, using the canonical key names:
"strips": [
{
"pin": 18,
"num": 60,
"rmtHz": 10000000,
"T0H": 0.3, "T0L": 0.9,
"T1H": 0.6, "T1L": 0.6,
"resetUs": 80
}
]LEDPixelConfig, LEDStripConfig and LEDSegmentConfig are plain classes with public members, so the configuration can be built without JSON and passed to LEDPixels::setup(LEDPixelConfig&):
LEDPixelConfig cfg;
LEDStripConfig strip;
strip.ledDataPin = 18;
strip.numPixels = 12;
strip.colourOrder = LEDPixel::GRB;
strip.colourOrderSpecified = true;
strip.bytesPerPixel = LEDPixel::getBytesPerPixel(strip.colourOrder);
cfg.stripConfigs.push_back(strip);
cfg.totalPixels = strip.numPixels;
LEDSegmentConfig seg;
seg.name = "ring";
seg.startOffset = 0;
seg.numPixels = 12;
seg.pixelBrightnessFactor = 0.5f;
cfg.segmentConfigs.push_back(seg);
_ledPixels.setup(cfg);When building LEDStripConfig in code, the timing members are in RMT ticks (T0H_ticks and so on), not microseconds. totalPixels must equal the sum of the strips' numPixels.
Getting Started
- Quick Start
- Architecture at a Glance
- Writing Your First SysMod
- Adding a Comms Channel
- Adding an I2C Device Type
Scaffolding & Building
- Raft CLI
- Web Apps (Device Types, Flasher)
- SysTypes
- Top-Level SysType
- Build Process
- WebUI Build Pipeline
- File System
- Partitions & Flash
- Local Dev Libraries
- Library Developer Guide
Architecture
Built-in SysMods
- NetworkManager
- WiFi Troubleshooting
- BLEManager
- WebServer
- MQTTManager
- SerialConsole
- CommandSerial
- CommandSocket
- CommandFile
- FileManager
- LogManager
- ESPOTAUpdate
- StatePublisher
- Remote Logging
- Data Source Registration
Comms & Protocols
- Stack Overview
- Comms Channels
- ProtocolExchange
- RICREST Protocol
- Real-Time Streams
- Adding REST Endpoints
- Built-in REST Endpoints
- File Download (OKTO)
- OTA Update Flow
Devices & Buses
- DeviceManager
- Device Manager REST API
- Device Factory & Classes
- Device Type Records
- Adding an I2C Device Type
- Device Data Publishing
- Data Logger
- I2C Bus
- I2C Device Scanning
- I2C ID & Polling
- MotorControl Overview
- MotorControl Config
- MotorControl Commands
- Camera
ROS 2
Helpers
Reference