ZeDMD is a "real" DMD designed for pinball emulations and other use cases. Originally developed by David "Zedrummer" Lafarge, the concept laid the foundation for what ZeDMD has become today. Markus Kalkbrenner, the current maintainer of ZeDMD, was inspired by the original idea and took the initiative to further develop and enhance it into the robust and versatile solution it is now.
ZeDMD is or will be supported by:
- DMDExtensions
- VPX Standalone
- PPUC
- batocera
- libdmdutil
- DOF2DMD
- VPX Mobile iOS
- VPX Mobile Android
- MPF
A full tutorial of its installation is available in English and in French
- ESP32-S3-DevKitC-1-N16R8
- original ESP32 with CP2102 USB-to-serial converter
- original ESP32 with CH340 USB-to-serial converter
For a new build, the ESP32 S3 is recommended. It provides more memory which is used for smoother rendering and higher color depth. And it provides a native USB interface which allows higher data transfer rates.
There are different LED panels on the market. But basically, ZeDMD only supports panels that could be combined to a total resolution of 128x32 (SD) or 256x64 (HD) pixels. This is the typical aspect ratio of a pinball DMD and works well as an arcade marquee. For the special need of small virtual pinball cabs, a single 128x64 panel is also supported but will display content in 128x32.
There're different panels on the market using different driver chips. The supported ones are described at ESP32-HUB75-MatrixPanel-DMA supported panel types.
Here is a short demo of ZeDMD and ZeDMD HD in parallel:
For the special need of ultra small virtual pinball cabs, the LilyGo AMOLED T-Display-S3 V2 is also supported and displays content in 128x32. One use-case is PinPal.
Due to the different supported hardware configurations, there are different "flavours" of the ZeDMD firmware. Because the firmware pushes the cheap ESP32 to its limits, we can not provide a unified firmware, so you have to pick the appropriate one:
- ZeDMD 128x32: using two 64x32 panels driven by an ESP32 connected over USB or WiFi
- ZeDMD HD 256x64: using four 64x64 or two 128x64 panels driven by an ESP32 connected over USB or WiFi
- ZeDMD 128x64: using one 128x64 panel driven by an ESP32 connected over USB or WiFi, showing 128x32 content with an offset, suitable for mini cabinets
- ZeDMD S3 128x32: using two 64x32 panels driven by an ESP32 S3 N16R8 connected over USB CDC or WiFi
- ZeDMD S3 HD 256x64: using four 64x64 or two 128x64 panels driven by an ESP32 S3 N16R8 connected over USB CDC or WiFi
- ZeDMD S3 128x64: using one 128x64 panel driven by an ESP32 S3 N16R8 connected over USB CDC or WiFi, showing 128x32 content with an offset, suitable for mini cabinets
- ZeDMD S3 AMOLED: using a small OLED driven by a LilyGo AMOLED T-Display-S3 V2 connected via USB CDC
- ZeDMD S3 AMOLED WiFi: using a small OLED driven by a LilyGo AMOLED T-Display-S3 V2 connected via WiFi
There are different ways to flash the firmware on the ESP32.
Download the appropriate zip file from the latest release's assets section and extract it.
Install esptool
On Windows you should use esptool.exe
instead of esptool
.
If you have different devices attached via USB or if the ESP32 is not detected you could specifiy the concrete port.
For a Windows machine this could be:
esptool.exe --chip esp32 --port COM3 write_flash 0x0 ZeDMD.bin
On a unix-like system:
esptool --chip esp32 --port /dev/ttyUSB0 write_flash 0x0 ZeDMD.bin
The ESP32-S3 N16R8 is now fully supported too. To flash this device, simply modify the command seen above by appending s3
to esp32
, resulting in esp32s3
.
pio run -t uploadfs -e 128x32
pio run -t upload -e 128x32
Warning
Starting with ZeDMD 5.1.0, we switched from platform-espressif32 to pioarduino.
If you did use pio
with older ZeDMD versions already, you must remove the .pio
folder once or you'll get compile / upload / runtime errors:
rm -rf .pio
Download and install the ZeDMD_Updater2 and follow its instructions.
ZeDMD utilizes HUB75 to display full-color content on your panels. To achieve this, the panels must be connected to specific GPIOs on your ESP32.
ESP32 Dev Board | ESP32-S3-N16R8 | HUB75 pins |
---|---|---|
GPIO 25 | GPIO 4 | R1 |
GPIO 27 | GPIO 6 | B1 |
GPIO 14 | GPIO 7 | R2 |
GPIO 13 | GPIO 16 | B2 |
GPIO 23 | GPIO 18 | A |
GPIO 5 | GPIO 3 | C |
GPIO 16 | GPIO 41 | CLK |
GPIO 15 | GPIO 2 | OE |
GPIO 26 | GPIO 5 | G1 |
GPIO 12 | GPIO 15 | G2 |
GPIO 22 | GPIO 1 | E |
GPIO 19 | GPIO 8 | B |
GPIO 17 | GPIO 42 | D |
GPIO 4 | GPIO 40 | LAT |
To navigate the menu and adjust settings, you'll need to configure a few buttons. However, only two buttons are essential to modify values and exit the menu. These two buttons are Menu Left
and Value +
.
ESP32 Dev Board | ESP32-S3-N16R8 | Menu Button |
---|---|---|
GPIO 33 | GPIO 48 | Menu Left |
NOT USED | GPIO 47 | Menu Right |
GPIO 21 | GPIO 0 | Value + |
NOT USED | GPIO 45 | Value - |
After flashing the ZeDMD a settings menu will appear. Due to the variety of panels available on the market you will need to adjust the RGB values. On ZeDMD versions prior to v5.0.0, this can be done by pressing the RGB button. From v5.0.0 onwards, you can adjust the RGB values by navigating to the
RGB Order:
option at the top of the settings menu.
Then, adjust the RGB order by rotating the colors until the following alignment is achieved:
- The top-left corner displays
red
as red. Green
appears as green.Blue
is shown as blue.
Unique to
128x64
builds: There is an option to adjust theY offset
of the displayed content.
Versions prior to V5.0.0 let you adjust the brightness using the brightness button.
From v5.0.0 onwards, this is done by navigating to the Brightness:
option in the settings menu.
Starting from version 5.1.0, a configurable USB packet size:
option has been introduced. While the default value works for most setups, reducing the packet size may help resolve any issues you encounter.
The option above USB packet size:
allows switching between USB
, SPI
, WiFi UDP
and WiFi TCP
. The USB option for the older ESP32 Dev board is self-explanatory. However, with the ESP32-S3-N16R8 you must use the left USB
port, as shown in the picture.
SPI
is currently non-functional and serves only as a placeholder for future real pinball integration.
To increase the compatibility with some USB ports or hubs, the USB package size became configurable. The default value of 32 bytes for the original ESP32 is very low. If you notice stuttering of the DMD frames, try to increase this value. Good values are 512 bytes for the original EPS32 and 1024 for the ESP32 S3. If ZeDMD doesn't work with these values, try a different USB port of your computer. In most cases not all of them and their driver chips are of the same quality.
When wanting to use WiFi it is recommended to start with WiFi UDP
for seamless frame streaming, provided your WiFi connection is fast. If you encounter crashes or unusual behavior, try adjusting the UDP Delay:
option. For fast connections, a value below UDP Delay: 5
may work well. Values like UDP Delay: 4
have been reported to perform effectively. While lowering the UDP delay may work well for some, values above UDP Delay: 5
should be given a try before making the final decision to switch to WiFi TCP
for slower streaming but improved reliability.
The Debug:
option can be set to Debug: 1
if requested by a ZeDMD developer to enable error tracking during testing. For regular use, this setting should always remain at 0
.
Warning
From version 5.0.0 onwards: once you’ve finished changing values, you must navigate to the 'Exit' button. This step is required to enable the ZeDMD to enter handshake mode.
ZeDMD has more configurations options than these accessible via the setting menu described above.
To set these you need to use the zedmd-client
command line tool, which is part of libzedmd, or the ZeDMD_Updater2.
zedmd-client -i
lists the available settings and their current values:
ZeDMD Info
=============================================================
ID: 799F
firmware version: 5.1.7
CPU: ESP32 S3
libzedmd version: 0.9.6
transport: 1 (UDP)
IP address: 192.168.178.61
USB package size: 512
WiFi SSID: xxxxxxxxxxxxxxx
WiFi port: 3333
WiFi UDP delay: 5
panel width: 256
panel height: 64
panel RGB order: 5
panel brightness: 10
panel clock phase: 0
panel i2s speed: 8
panel latch blanking: 2
panel minimal refresh rate: 30
panel driver: 0
Y-offset: 0
Some of these values could be adjusted, run zedmd-client -h
to see a list of all adjustable settings and how to do it. Here are explanations for some of the advanced options:
Setting | Values | Explanation |
---|---|---|
debug | 0,1 | Display some debug information on the DMD while it is un use. |
panel clock phase | 0,1 | Default is 1 (on), see Clock Phase |
panel drive | 0(SHIFTREG), 1(FM6124), 2(FM6126A), 3(ICN2038S), 4(MBI5124), 5(SM5266P), 6(DP3246_SM5368) | Default is 0(SHIFTREG), see Specific chips found to work |
panel i2s speed | 8, 16, 20 | The frequency used to transfer the data to the panel driver, default is 8Mhz. It might need to be changed in case a "non-standard" driver chip is used in your panels |
panel latch blanking | 0, 1, 2, 3, 4 | Default is 2, see Latch Blanking |
panel min refresh rate | 30..120 | The refresh rate used to update panels. A higher value leads to smoother animations and less lag. But too high values lead to errors, especially if large areas of the DMD change frequently. The default of 30Hz is very low. Try to increase it. 60Hz is a good value for ZeDMD HD, 90Hz for ZeDMD. |
transport | 0(USB), 1(WiFi UDP), 2(WiFi TCP), 3(SPI) | 0(USB) is the default. In WiFi mode you can choose between 1(UDP) and 2(TCP). UDP is a faster and preferable but could lead artifacts or restarts of ZeDMD if the WiFi quality is not good. TCP ensures that everything is displayed, but could lead to stuttering and sometimes frame drops if the WiFi quality is not good. SPI is meant for futitre use in real pinball machines. |
UDP delay | 0..9 | A delay of milliseconds beten UDP packages. A higher value reduces the risk of artifactsor restarts but add a bit of a lag. Default is 5ms. |
USB package size | 32..1920 (step 32) | The amount of bytes sent per data package via USB. A higher value leads to smoother animations and less lag. The default of 32 is very low. Good values are 512 bytes for the original EPS32 and 1024 for the ESP32 S3. But the highest possible value depend on a lot of factors like USB chipset, cable quality, etc. |
WiFi port | The network port to be used to stream frames to ZeDMD via WiFi. The default is 3333. Only change this value in case this port is already in use in your network or blocked by a firewall. |
Warning
The most important values you should adjust even if ZeDMD works are the panel min refresh rate and, in case of USB, the USB package size. Both are also easlilyajustable in the settings menu! Otherwise your ZeDMD will work, but not as good as it could.
After activating either WiFi UDP
or WiFi TCP
in the settings menu, connect your mobile device or laptop to the ZeDMD-WiFi
network using password zedmd1234
.
Then, open your web browser and navigate to http://ZeDMD-WiFi.local (IP: 192.168.4.1) to access the configuration settings.
ZeDMD's firmware is open source and licensed as GPLv2 or later and can be ditributed under these terms.
For manufacturers or resellers of any shield, frame, ready-to-use devices or whatever linked to ZeDMD, our only request is that the device is called as "ZeDMD something" or powered by ZeDMD. "ZeDMD" should be what you see first when you look at the device. Also, a link to this project must be provided with the device.
ZeDMD uses
- ESP32-HUB75-MatrixPanel-DMA
- Bounce2
- miniz
- Tiny 4x6 Pixel Font
- ESPAsyncWebServer
- TFT_eSPI
- RM67162 with fixes from Nikthefix
- pioarduino
Warning
Neither @Zedrummer - David Lfg, nor myself are earning any money from ZeDMD and we don't get money from the sellers listed on https://ppuc.org/ZeDMD I just listed these shops to make it easier for you to get started with ZeDMD. ZeDMD is and will remain a free open source DIY project!
The intention of ZeDMD is to provide a cheap DIY DMD solution. The maintainers of this project don't run any shop to sell ready-to-use hardware!
Nevertheless, there are are some shops we are aware of who designed their own shields to build a ZeDMD. And as this might ease the task to use a ZeDMD for some users, we agreed to add some links here:
- https://janspinballmods.com/mods/zedmd/shield-esp32-s3-not-included/
- https://shop.arnoz.com/en/dmd/87-esp-dmd-shield.html
- https://benfactory.fr/produit/zedmd-shield/
- https://www.smallcab.net/shield-zedmd-p-2697.html
There are also ready-to-use devices:
- https://janspinballmods.com/mods/zedmd/zedmd-s3-128x32-plug-and-play/
- https://benfactory.fr/produit/zedmd/
- https://www.smallcab.net/pack-zedmd-p-2698.html
- https://virtuapin.net/index.php?main_page=product_info&cPath=6&products_id=283
The ZeDMD firmware supports a wide range of LED panels with different driver chips ... in theory.
In general, some driver chips require adjustments in the configuration, timings and the clock phase.
That can be done with ZeDMD_Updater2 for Windows,
or the zedmd-client
which is available for every operating system as part of the libzedmd download:
https://github.com/PPUC/libzedmd/releases
Here is some background information:
- https://github.com/mrcodetastic/ESP32-HUB75-MatrixPanel-DMA?tab=readme-ov-file#supported-panel-can-types
- https://github.com/mrcodetastic/ESP32-HUB75-MatrixPanel-DMA?tab=readme-ov-file#latch-blanking
Thes available config options are decribed above in Advanced Settings.
The pre-built firmware uses the default config which is suitable for the most common LED panels. Obviously we can't provide a menu on the device to adjust these settings as you won't see them ;-)
We would love to list the required settings for specific panels here. But that would require someone to send over their panels to us so we can find out the correct config.
If you find out what config adjustment gets a specific panel to work, you should open an issue here and provide that information so that we could include it in the README.
A few users have reported that VPX and ZeDMD consistently crash if the latest Visual C++ Redistributable Runtime packages are not installed. To resolve this issue, ensure you have the most up-to-date runtime packages installed. If the latest version doesn’t resolve the issue, it may be necessary to install all available versions of the Visual C++ Redistributable Runtime packages.
Another potential issue could be outdated USB drivers. For the original ESP32 Development Board:
For the ESP32-S3-N16R8, we use the USB CDC port, which doesn't require a driver.
If you discover a crash, there's a good chance that a coredump has been written to the internal flash memory.
Especially if ZeDMD actively tells you to do so!
If you install the entire esp-idf, you can extract and interpret the coredump. firmware.elf
is included in the release downloads since v5.1.2.
To get the coredump, the command has to be something like this on Linux or macOS:
python PATH_TO_ESP_IDF/esp-idf/components/espcoredump/espcoredump.py info_corefile PATH_TO_FIRMWARE_ELF/firmware.elf
Or on Windows:
PATH_TO_PYTHON\python.exe PATH_TO_ESP_IDF\esp-idf\components\espcoredump\espcoredump.py info_corefile PATH_TO_FIRMWARE_ELF\firmware.elf
If you used pio to build and flash the firmware, the command line on Linux or macOS could be like this:
python ~/esp/v5.3.2/esp-idf/components/espcoredump/espcoredump.py info_corefile .pio/build/S3-N16R8_128x32/firmware.elf
Yes! A native MPF driver is under development. See libzedmd-python-pybind11-extension.