PIXELIX

Full RGB LED matrix, based on an ESP32 and WS2812B LEDs.


Click on the preview to see the video.


Table of Content
Motivation
My initial goal was to have a remote display that would show multiple kind of information and run reliably 24/7. Can be connected to the local network via WiFi and controlled via REST API or Websocket. PIXELIX was born!
Introduction
PIXELIX firmware runs on ESP32 boards and controls RGB LED matrices or TFT displays. It can display the time, date, weather, text, animations, and more.
It requires no cloud connection or smart home system, but its REST and MQTT APIs integrate with Home Assistant and other smart home systems.
Features
- Supports 32x8, 32x16 and 64x64 LED matrix size out of the box.
- Supports some small TFT displays to simulate a LED matrix in retro style.
- Display static or scrolling text, as well as static or animated icons (BMP, GIF and additional for boards with PSRAM PNG and WEBP).
- Includes a web interface for configuration and control.
- Supports REST and MQTT API for remote control and integration with other systems, like Home Assistant.
- Extendable with custom effects and animations by plugins. See list of plugins.
- Its plugin concept allows to scale for different development boards.
Not every feature is available on every development board. For example, MQTT generally requires a board with at least 8 MB of flash, except for the Ulanzi TC001. See the config<variant>.ini files in the config folder for details.
The native environment runs PIXELIX as an application on Windows and Linux without requiring hardware. It displays a simulated LED grid in a window and serves its web interface on local port 8080. Melodies that would play through a board’s buzzer use the host’s audio device. You can mute them with the Mute entry in the simulator window’s menu bar.

Original Setup
The original setup for development and the first release was:
- ESP32 DevKitV1
- WS2812B 5050 8x32 RGB Flexible LED Matrix Panel
- Power supply 5 V / 4 A
The following diagram shows the minimum wiring setup, for example, for the ESP32 DevKit V1. Wiring may differ depending on your development board.

Attention
:warning: If you power the development board and LED matrix via USB, be careful: excessive LED current can damage the ESP32 board. Avoid increasing the display brightness or filling it completely with white pixels. Use an external power supply rated for at least 5 V / 4 A.
:information_source: To protect your hardware and your eyes, PIXELIX starts at a low brightness. The maximum current is also limited by software.
Supported Development Boards
In the meantime several other boards are supported as well. You can find them in the list of boards.
If your board is not listed in the main branch, please have a look in the Development branch too.
With the Ulanzi TC001 smart pixel clock you even don’t need to assemble the electronic and mechanic together.
Recommendation
If you assemble your own Pixelix hardware, its recommended to use a development board with the following properties:
- 8 MB flash or more. 4 MB flash modules are still supported, but the functionality is limited.
- A esp32 dual core variant, which provides more processing power.
- PSRAM for image formats that require more memory than the available internal RAM, depending on the enabled features.
Special Variants
Additional supported variants, which were original not in focus:
Although PIXELIX was designed to show information, that is pushed or pulled via REST API, the following sensors can be directly connected and evaluated:
- Temperature and humidity sensors DHTx
- Temperature and humidity sensors SHT3x
- Digitial microphone INMP441 for some sound reactive stuff.
Installation
PIXELIX can be installed in two different ways. Decide first which one applies to you, because it determines whether you need a build toolchain at all.
Every release provides ready-to-flash binaries for all supported board and display combinations. They are named after their build environment, e.g. esp32doit-devkit-v1-LED-32x8, which encodes the development board as well as the display type and its resolution.
:warning: A prebuilt binary has the LED matrix width/height, the panel topology and the list of plugins compiled in. None of them can be changed later in the web interface. If one of them does not match your hardware, you have to build the software yourself.
Install A Prebuilt Release With The Web USB Installer
This is the easiest way and the recommended one for everybody who does not want to touch the source code. The installer runs completely in the browser, writes a full flash image (bootloader, partition table, factory image, firmware and filesystem) and can hand over the WiFi credentials over USB afterwards.
- Open the PIXELIX USB installer in a Chromium based desktop browser, like Chrome, Edge, Opera or Brave. It is based on the Web Serial API, which is not available in Firefox, Safari or on mobile devices.
- Choose the version. The latest stable release is preselected. All releases from version 11 on are offered; pre-releases are marked as such and are not recommended for productive use.
- Choose your board and display configuration.
- Connect the development board to your PC with a data capable USB cable and select the serial device once.
- Start Erase and install. Note, that the flash is erased completely, which includes all settings of a previous installation.
- To keep the settings of a previous installation, enable Keep settings before. The flash is then not erased and the device settings stored in NVS survive: WiFi credentials, hostname, web login, brightness, timezone and so on. The slot configuration, MQTT, sensor calibration, timers and the plugin configuration are reset in any case, because they are part of the filesystem which is always written. Don’t use it for the first installation on a board.
- Keep the USB cable connected and continue with the WiFi setup on the same page. If that succeeds, you can skip the Very First Startup.
If the board does not enter the download mode automatically, follow the BOOT/RESET sequence shown on the page. This is typically necessary for the ESP32 DevKit V1.
Install A Prebuilt Release Manually
Use this way if no Chromium based browser is available or if you prefer the classic Espressif tools.
- Download the binaries from the latest release.
- Write them to the flash with the Espressif Flash Download Tool (Windows only) or with esptool (any OS). The detailed steps, the required flash addresses and the flash layout are documented in Upload/Update the software and the filesystem.
- Continue with the Very First Startup.
Build And Install The Software Yourself
:information_source: The order matters. Configure the display before the first build, because the display configuration is compiled into the firmware.
- Setup the toolchain.
- Configure your display in
./config/display.ini:
- Optional: adapt the list of plugins in the corresponding
./config/config*.ini.
- Build the software and check whether the toolchain works.
- Upload the software and the filesystem to the target. Note, that both parts are necessary, the firmware and the filesystem image.
- Continue with the Very First Startup.
Verify The Installation
Independent of the way you installed PIXELIX, verify that the LED panel topology is correct and that you see the “Hello World” on the display. If the text is mirrored, scrambled or spread over the wrong rows, the panel topology does not match and the software has to be built with the right CONFIG_LED_TOPO setting.
Update A Running PIXELIX
Once PIXELIX runs and its web interface is accessible, the firmware and the filesystem can be updated over WiFi with the PIXELIX Updater: https://github.com/BlueAndi/PixelixUpdater. You can access the Updater through the submenu “Update” of PIXELIX’s web interface. Reinstalling via USB is not necessary for an update.
Very First Startup
When the device starts for the very first time, the WiFi station SSID and passphrase settings are empty. They can be configured in two possible ways:
- Using the browser and set them in the captive portal.
- Using a serial terminal connecting via USB.
As long as no WiFi station SSID and passphrase are configured, PIXELIX spawns a WiFi access point automatically on every startup. Just wait until it shows the SSID of the access point, search for it with your mobile device and connect.
Once the WiFi station SSID and passphrase are configured, PIXELIX connects to your WiFi network instead. To get back into the access point mode on purpose - e.g. after you replaced your router - restart the device and keep the button pressed until the access point SSID is shown.
- SSID: pixelix-<DEVICE-ID>
- Passphrase: Luke, I am your father.
Depending on your device, you may see a notification prompting you to open the captive portal. Otherwise, enter http://192.169.4.1 in your browser’s address bar.
Use the following default credentials to get access to the PIXELIX web interface:
- User: luke
- Password: skywalker
Connect PIXELIX to your PC via USB and start a serial terminal. Use the following commands to set the WiFi SSID and passphrase of your home WiFi network:
- Write WiFi passphrase:
write wifi passphrase <your-passphrase>
- Write WiFi SSID:
write wifi ssid <your-ssid>
- Restart PIXELIX:
restart
- Get IP-address:
get ip
- Get hostname:
get hostname
- Get status:
get status
- A status of 0 means everything is ok.
- For any other status, see the low-level error code table. For example, status 1 corresponds to error code E1.
Use help to get a list of all supported commands.
PIXELIX Is Ready
After configuration, restart PIXELIX. It will then be available on your Wi-Fi network.
To change what is displayed, open the web interface and use the same credentials as for the captive portal in Variant 1. On the Display page, configure it to suit your needs.
User Interface
Pixelix can be controlled with buttons. Most of the development boards are supported with just one user button.
- 1 short pulse: Activates the next slot.
- 2 short pulses: Activates the previous slot.
- 3 short pulses: Activates next fade effect.
- 4 short pulses: IP address is shown.
- 5 short pulses: Toggle display power on/off.
- Long pressed: Increases the display brightness until maximum and then decreases until minimum. After that it will again increases it and so on.
- Left button:
- 1 short pulses: Activates the previous slot.
- 2 short pulses: Toggle display power on/off.
- Long pressed: Decreases the display brightness until minimum.
- Right button
- 1 short pulse: Activates the next slot.
- 2 short pulses: Activates next fade effect.
- 3 short pulses: IP address is shown.
- Long pressed: Increases the display brightness until maximum.
- Left button:
- 1 short pulses: Activates the previous slot.
- Long pressed: Decreases the display brightness until minimum.
- Ok button:
- 1 short pulses: Activates next fade effect.
- 2 short pulses: IP address is shown.
- Long pressed: Toggle display power on/off.
- Right button
- 1 short pulse: Activates the next slot.
- Long pressed: Increases the display brightness until maximum.
If the display’s location is hard to reach, the remote user button feature can be used. It is controllable via REST API and perfect for remote buttons like the Shelly Button 1.
Details
FAQ
Where to change panel topology of the LED matrix?
Adapt in ./config/display.ini the CONFIG_LED_MATRIX_WIDTH and CONFIG_LED_MATRIX_HEIGHT according your LED matrix and change CONFIG_LED_TOPO according to your physical panel topology. Take a look how your pixels are wired on the pcb and use the following page to choose the right one: https://github.com/Makuna/NeoPixelBus/wiki/Layout-objects
How to change text properties?
Text properties can be changed using different keywords added to the string to be displayed.
In order to be able to use these keywords, they must be inside curly braces, otherwise they will only be treated as text.
The following keywords are available:
| Keyword |
Description |
{#RRGGBB} |
Set solid text color (RRGGBB in hex) |
{lgv #RRGGBB,#RRGGBB,OFFSET,LENGTH} |
Set linear vertical gradient text color (RRGGBB in hex, OFFSET/LENGTH in pixels) |
{lgh #RRGGBB,#RRGGBB,OFFSET,LENGTH} |
Set linear horizontal gradient text color (RRGGBB in hex, OFFSET/LENGTH in pixels) |
{stc} |
Activate solid text color |
{lgtc} |
Activate linear gradient text color |
{hl} |
Horizontal alignment left |
{hc} |
Horizontal alignment right |
{hr} |
Horizontal alignment center |
{vt} |
Vertical alignment top |
{vc} |
Vertical alignment center |
{vb} |
Vertical alignment bottom |
{0xCC} |
Special character code (CC in hex) |
Notes:
- If these keywords are used via the REST API all unsafe ASCII characters must be replaced by the respective percent encoding (see also ASCII Encoding Reference).
- The keywords can be combined.
- Don’t add additional spaces, e.g. after a comma. Write them exactly as the format is specified.
Examples:
| Sourcecode |
URL |
Result |
{hl}{#ff0000}Hi! |
%7Bcl%7Dff0000Hi! |
Hi! |
{hc}{#ff0000}Hi! |
%7Bhc%7Dff0000Hi! |
Hi! |
{hr}{#ff0000}Hi! |
%7Bhr%7Dff0000Hi! |
Hi! |
The display only shows an error code, like “E4”. What does that mean?
This is a low level error code. Please have a look into the following table.
| Error code |
Description |
| E1 |
Something happened, which can not be further explained, but was fatal. |
| E2 |
There is a problem with the two-wire (i2c) interface. |
| E3 |
There is no user button available. |
| E4 |
Bad filesystem, did you explicit program the filesystem too? If not, please upload it. |
| E5 |
The display manager didn’t start up. |
| E6 |
The system message handler didn’t start up. |
| E7 |
One of the services failed to start. |
Press a button and Pixelix will jump to the Pixelix Updater.
How can I use animated icons?
Use animated GIF images to get animated icons. The sprite sheet support (< v8.0.0) was replaced with the GIF images.
If you like to create animated GIFs by yourself, the Piskel editor is recommended. Piskel is a free online editor for animated sprites & pixel art.
How do I know that my sensor is recognized?
- Check the log output from USB (not via web interface) right after startup (at this point WiFi is not connected yet).
- Install the SensorPlugin and open the SensorPlugin website. There the sensor should be shown in the drop-down.
Why do I see sometimes values from the LDR in the SensorPlugin, although no LDR is installed?
The LDR pin is configured as input (ADC) and it seems that the pin is floating, because there is the ext. pull-down missing.
How can I use alternative icons?
Find details in the icon page.
Is it possible to use a font with 8px height?
There are three font types defined:
- default (6px height)
- normal (6px height)
- large (8px height)
Note, the default font type is “normal”.
The font type can be selected per plugin instance in the display web page.
Not all plugin may support this in case they get conflicts with their layout.
If a plugin don’t support it, it will use the default font type.
The date/time format used by plugins, e.g. the DateTimePlugin or the SunrisePlugin, can be configured in their configuration JSON file. Use the file editor in the web interface to modify it according to your needs. The file can be found in the /configuration folder and the filename is <PLUGIN-UID>.json. The format specifiers following strftime().
Examples:
%I:%M %p: 02:30 PM
%H:%M: 14:30
%m/%d: 11/12
%d.%m.: 11.12.
%d - %b: 11 - Nov
You can colorize it by using the text properties.
The available plugins depend on your development board. Boards with only 4 MB of flash cannot fit every plugin, and single-core boards such as the ESP32-S2 may not have enough processing power for some plugins.
Several .ini files in the ./config folder define plugin sets:
- configSmall.ini: Used for boards with 4 MB flash.
- configNormal.ini: Used for boards with 8 MB flash or more.
- configSmallNoI2s.ini: Used for boards with 4 MB flash and less mcu power.
Edit the file used by your board, commenting plugins in or out as needed.
Is there an easy way to rotate the display by 180° ? I need to turn the display when putting it into a housing
Change option CONFIG_DISPLAY_ROTATE180 in config/display.ini to 1 as shown below and rebuild.
Example:
[display:common]
build_flags =
-D CONFIG_DISPLAY_ROTATE180=1
Used Libraries
| Library |
Description |
License |
| Arduino |
ESP32 Arduino framework v2.x.x |
Apache-2.0 |
| PlatformIO |
PlatformIO is a cross-platform, cross-architecture, multiple framework, professional tool for embedded systems engineers and for software developers who write applications for embedded products. |
Apache-2.0 |
| NeoPixelBus |
Controlling the LED matrix with hardware support (I2S) |
LGPL-3.0 |
| ESPAsyncWebServer |
Webserver |
LGPL-3.0 |
| AsyncTCP |
This is a fully asynchronous TCP library, aimed at enabling trouble-free, multi-connection network environment for Espressif’s ESP32 MCUs. |
LGPL-3.0 |
| ArduinoJson |
JSON handling |
MIT |
| StreamUtils |
Stream utilities |
MIT |
| Bootstrap |
CSS Framework |
MIT |
| POPPER JS |
POPPER JS |
MIT |
| Adafruit Unified Sensor Driver |
A unified sensor abstraction layer. |
Apache License 2.0 |
| Adafruit DHT sensor library |
An Arduino library for the DHT series of low-cost temperature/humidity sensors. |
MIT |
| arduino-sht |
An Arduino library for reading the SHT3x family of temperature and humidity sensors. |
BSD-3-Clause |
| TFT_eSPI |
Arduino and PlatformIO IDE compatible TFT library optimised for the Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different driver chips |
Mixed licenses: MIT, BSD, FreeBSD |
| arduinoFFT |
Fast Fourier Transform for Arduino. |
GPL 3.0 |
| mufonts |
A collection of fonts compatible with Adafruit GFX library. These fonts were developed when creating various samples for mupplet display code. |
MIT |
| JSZip |
A library for creating, reading and editing .zip files with JavaScript, with a lovely and simple API. |
MIT |
| FileSaver.js |
FileSaver.js is the solution to saving files on the client-side. |
MIT |
| Arduino client for MQTT |
This library provides a client for doing simple publish/subscribe messaging with a server that supports MQTT. |
MIT |
| ESP32-PSRamFS |
ESP32-PsRamFS is a pseudo RamDisk library for Arduino-ESP32, with vfs compliance. |
MIT |
| Dear ImGui |
ImGui is a bloat-free graphical user interface library for C++. Is is used by the native Platfrom only to create a simulated LED grid window. |
MIT |
| PNGdec |
PNG image decoding. Only built for boards with PSRAM. |
Apache-2.0 |
| libwebp |
WebP image decoding (static and animated), vendored decoder-only. Only built for boards with PSRAM. |
BSD-3-Clause, plus an additional patent grant |
Issues, Ideas And Bugs
If you have ideas or found a bug, create an issue. If you want to fix it yourself, clone the repository and open a pull request. For questions to the community or showing the own Pixelix, the Discord server can be used.
License
The whole source code is published under the MIT license.
Consider the different licenses of the used third party libraries too!
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, shall be licensed as above, without any
additional terms or conditions.
评论