lrg + ledchainarrangement - graphics subsystem for SmartLED chains and matrices.
What is lrg?
lrg is short for "low resolution graphics", and within p44script is the name of the global object used to access the p44lrgrpahics graphics subsystem. p44lrgrpahics provides a graphics environment with which complex effects on LED chains and matrices can be created and also animated. For this purpose it provides a hierarchy of Views, which can be arranged and moved side by side or also on top of each other (with variable transparency).
A chaser effect for example would be realized in p44lrgrpahics with a background view over which the actual chaser is moved as a second view.
What is a ledchainarrangement?
SmartLED chains consisting of individually addressable LEDs (WS281x, SK681x etc.) can be combined in various ways to form bands or areas. For example, LED strips can be wound on a cylinder, or in a zigzag arrangement on a surface.
A ledchainarrangement comprises one or more sections of LED chains, and arranges them logically within a rectangle of pixels (possibly with gaps). This logical rectangle then forms the rootview for the lrg graphics system. Each connected LED thus receives a unique coordinate (x and y). The rootview (usually a stack) can then place, move, show and hide other views as desired in this rectangle.
The ledchainarrangement of a P44-xx device is either specified on the command line with the
--ledchain option, or defined via p44script with
addledchain() (see below for details), usually from within the mainscript.
There are several types of views:
- All other types are built on this simplest view. A plain view includes a rectangle with a background color and a foreground color.
- On this view single pixels can be set (drawn) programmatically.
- Simulates a light "spot", a round or oval area with different possibilities of color and brightness distribution around the center. This makes color gradients, soft edges, etc. feasible. The lightspot is the basis of the "Moving feature light with effects" which is available in P44-DSB/LC devices with SmartLED connector.
- Displays a text in 5*7 matrix font.
- Displays an image (which must be in PNG format).
- Displays animations created in the Expressive pixels IoT animation format JSON format.
- Can move (scroll) another View with adjustable speed. The movement steps can be smaller than one LED, then the intermediate steps are simulated by distributing brightness over several pixels (anti-aliasing). With the scroller and a text-View e.g. tickers can be realized.
- Serves to arrange several other views in layers on top of each other (layers)
- Serves to display several other Views (e.g. pictures) in a temporal sequence (Steps), once or repeatedly. The individual steps can have different display durations as well as fade-in and fade-out times.
- Represents Conway's "Game of Life". The age of the cells can be represented by color.
- A simple torch/fire simulation that looks good on round wound LED chains. This view evolved from the MessageTorch project from 2014.
Setting up the SmartLED chains in LEDChainArrangements.
Depending on the hardware, a device has one or more outputs to each of which an LED chain with single addressable LEDs, such as WS28xx and similar, can be connected. How the LEDs in a chain are mapped to the coordinates of the rootview (rectangle encompassing all LEDs) is determined by the initialization string:
If the initialization string for the
--ledchain command line option is simply
none, then only an empty ledchainarrangement is created at startup; the LED chains can be added later with the addledchain() function.
The individual elements are
Specifies the type and other parameters for controlling the LEDs. Normally in the form
chip.layout, for more precise control of the parameters it can also be
- Type of the LED chip. Currently supported: WS2811, WS2812, WS2813, WS2815, P9823, SK6812.
- Channel assignment. Currently supported: RGB, GRB, RGBW, GRBW. The most common layout on WS28xx chips is GRB.
- maximum pause time between two bits in µS. If the value is not specified or set to 0, the default value of the respective chip is used (10..80µS). In case of unmediated flickering, especially with old WS2812 chips, it may help to shorten the pause.
- Maximum number of attempts to send the data for an update. Depending on the driver and the interrupt situation on the target system an update must be aborted and before all LEDs of the chain have been updated. In this case the update is repeated, but not more often than maxretries (default value: 3).
For backward compatibility reasons, the following ledtype values (without separate chip/layout specification) are also still supported: SK6812, P9823, WS2812, WS2813, WS2815_RGB.
- The name of the LED device/channel to which the LED chain is connected. On MT7688 OpenWrt platforms with p44-ledchain kernel driver, the devices for the maximum 4 PWM outputs are named /dev/ledchain0 to /dev/ledchain3. On ESP32 the name of the GPIO (up to 8 channels possible) must be specified: e.g. gpio22. On RaspberryPi the leddevicename is currently not relevant and can be omitted, because only one output (always: GPIO18) is supported.
- The number of LEDs in the chain to be controlled. The chain can be shorter or longer, but if power consumption calculation/limitation is used, the actual number of LEDs must match.
- x, dx, y, dy
- (optional) These values define the coordinate range in rootview that this LED chain covers. The X direction is the running direction of the chain, Y comes into play when a chain is arranged to a surface, e.g. rolled up on a cylinder, or zigzagged on a surface (see XYSA flags). If these flags are missing, the whole chain is mapped in X-direction from x=0 and y=0.
- (optional) Specifies the number of non-driven LEDs at the beginning of the chain. This can be used if, for example, the first LEDs of a chain are not visible at all for installation reasons, and if different sections of the same LED chain are to be placed at different coordinates.
- (optional) In case of flat matrix arrangements, where the LED chain is led in a zig-zag way, usually one or more LEDs are not visible between the rows. This parameter can be used to exclude them from the matrix.
(optional) flags for the arrangement:
- X inverts the X coordinate
- Y inverts the Y coordinate
- S swaps X and Y coordinate ( Swap )
- A changes X running direction for each Y row ("Alternate") for zigzag arrangements.
- (optional) For chains with a white fourth LED, the color and brightness produced by the white channel can be specified here (in webcolor format, e.g. 'W#AA8' or 'W#A5A582'). This way correct color reproduction can be achieved for different RGBW chains. Without specification, the white channel is assumed to be pure white with double brightness compared to the R,G,B channels.
A common WS2813 LED chain with 200 LEDs can be easily integrated with name and number of LEDs in x-direction from coordinate x=0, y=0:
On the RaspberryPi (only one output, leddevicename irrelevant) is even enough:
To reverse the running direction (x=0 for last LED in the chain, not for the first LED):
However, if the chain is rolled up on a cylinder so that there are 20 turns of 10 LEDs each, and this is to be driven as a 10x20 matrix, e.g. for using a torch view (see tutorial here):
But now a more sophisticated arrangement:
Here we see a chain of 106 LEDs, which has 3 inactive LEDs at the beginning, forms a 14x6 area afterwards (with two inactive LEDs in each kink), and at the end puts 9 more LEDs in Y-direction like a candle on the cake.
The 6x14 area can be described like this:
The X flag is necessary because the first line on the X axis goes backwards, the A flag because the line direction changes every line.
Now to put the 9 "candle" LEDs on the coordinates x=6, y=6..14, it needs another initialization string, which refers to another section of the same LED chain (same leddevicename):
Here the first 97 LEDs are inactive (these are covered by the first definition with the 6*14 matrix). Because the LEDs in this section run in Y direction (instead of X), it needs the S flag.
Work in Progress
This text is work in progress and therefore incomplete at the moment.