Introducing a New Java DMX512 Library With Demo JavaFX User Interface
In this post, I would like to inform you about a new Java library that is now available on Maven Central, allowing interaction with DMX512 devices using (optionally) the Open Fixture Library (OFL). I also published a video with a code walkthrough of my test setup and demo code.
But first…
A Personal Story
I’ve always been fascinated by sound and light equipment. As a teenager (over 30 years ago…), I built two disco bars and used them as “DJ Franky” to bring ambiance to many weddings and other parties. I loved the DJ-ing, but I loved even more the technique of getting all the devices together and finding the best way to connect them, building custom housing, and creating the best possible connections. But there was one problem with this hobby, it all cost a lot of money…
Fast forward to now. Thanks to modern technology and improved production processes, prices have decreased significantly, allowing you to purchase marvelous pieces of technology at an affordable price. However, most of these can still be controlled by an “ancient” standard: DMX512.
As I wanted to control a few of these from a JavaFX user interface, but couldn’t find a suitable Java library to do so, I created one myself.
About DMX512 and OFL
Let’s start by explaining the standards used in this project.
What is DMX512
DMX512 is a digital communication protocol, based on RS-485, widely used in professional lighting and stage equipment to control dimmers, moving lights, fog machines, and other effects. The protocol transmits data in a serial format over standard XLR cables, with each “universe” capable of controlling up to 512 channels of information. Each channel can carry values from 0 to 255, allowing for precise control of parameters such as brightness, color, position, and speed across multiple fixtures simultaneously. DMX512 has become the industry standard because it’s reliable, relatively simple to implement, and allows complex lighting shows to be programmed and synchronized from a central console.
DMX512 Data Example
In my test setup, I have two RGB LED fixtures who have five values for red, green, blue, dimmer, and effect. If I give them address 1 and 6, and want to first one to be full red, and the second one blue half dimmed (127 = 0x7f
), both without effect, I would need to create this byte array in Java:
// Address 1
// Red Green Blue Dim Effect
var data = new byte[]{0xff, 0x00, 0x00, 0xff, 0x00,
// Address 6
// Red Green Blue Dim Effect
0x00, 0x00, 0xff, 0x7f, 0x00};
DMX512 Control from PC
Not many PCs nowadays have a serial port. Still, luckily, you can control DMX512 devices through several other methods, such as USB-to-DMX and IP-to-DMX interface devices that convert the data into the DMX512 format. These devices use different protocols to handle DMX512 data, for example:
- USB-to-DMX:
- IP-to-DMX:
Software applications like QLC+, ONYX, or MagicQ run on the PC and provide user-friendly interfaces for programming lighting cues, effects, and real-time control. The software sends commands through the USB interface, which then transmits the DMX512 data stream to control brightness, color, movement, and other parameters across hundreds of connected lighting fixtures.
But none of these are based on Java…
What is Open Fixture Library
The Open Fixture Library (OFL) is a collaborative, open-source platform that addresses a persistent issue in lighting control: fixture definitions that are tied to specific software platforms.
The project emerged when lighting professionals wanted to switch between different software controllers, but discovered their fixture definitions couldn’t be easily transferred. This meant recreating all their work from scratch – a time-consuming process the entire lighting community had been dealing with for years.
The OFL Solution
Open Fixture Library creates a centralized, wiki-style repository where fixture definitions are stored in a universal format. The platform automatically generates fixture files compatible with multiple lighting control software packages, eliminating the need to recreate definitions for each program.
Key features include universal compatibility across lighting software formats, collaborative development where anyone can contribute improvements, and a user-friendly online editor for creating new definitions or importing existing ones.
Impact
Since joining the Open Lighting Project in 2018, OFL has become an essential tool for lighting professionals worldwide. By standardizing fixture definitions and making them freely available, setup time has been reduced, reliability improved, and users have been given greater flexibility in software choice. The platform demonstrates how community-driven projects can solve industry-wide challenges more effectively than proprietary solutions.
OFL JSON Files
In my library, you can use OFL exports in the “Open Fixture Library JSON” format. This is the internal data model of OFL and contains all the info in a nice readable way.
The OFL project is well documented on GitHub with more details about the data model of the JSON files here.
DMX512 Java Library
The library I created is open-source with its sources on GitHub and releases on Maven Central.
<dependency>
<groupId>be.codewriter</groupId>
<artifactId>dmx512</artifactId>
<version>${dmx512.version}</version>
</dependency>
My Test Setup
At this moment, the library is only tested with this IP-to-DMX controller: JUNELIONY ArtNet 1024 2-Port Sulite DMX LAN512 2-Port ArtNet Converter. It comes configured with a fixed IP, but I changed it to use DHCP.
I have the following fixtures connected to it:
- Address 1 and 12: PicoSpot 20 LED with 11 channels.
- Address 23 and 28 : LED PARty TCL Spot with 5 channels.
Minimal Code Example
You can send a byte array directly via the controller. Create an array with the expected length by your device and fill in the values.
This is an example for a PicoSpot on channel 1 = the data starts at index 0 of the byte array.
var controller = new DMXIPController(InetAddress.getByName("172.16.1.144"));
// The PicoSpot on DMX channel 1 expects 11 values
/*
"Pan",
"Tilt",
"Pan fine",
"Tilt fine",
"Pan/Tilt Speed",
"Color Wheel",
"Gobo Wheel",
"Dimmer",
"Shutter / Strobe",
"Program",
"Program Speed"
*/
// Set all to 0
controller.render(new byte[]{(byte) 0, (byte) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
sleep(2_000);
// Set pan and tilt to 127
controller.render(new byte[]{(byte) 127, (byte) 127, 0, 0, 0, 0, 0, 0, 0, 0, 0});
sleep(2_000);
// Set color wheel to 44 and dimmer full op
controller.render(new byte[]{0, 0, 0, 0, 0, (byte) 44, 0, (byte) 255, 0, 0, 0});
Using Fixtures and Modes
By using a fixture loaded from an OFL JSON file, it becomes significantly easier to modify the data. You can use the name of the channel (e.g., “red”, “dimmer”, …) and don’t need to know the index of the data in the byte array.
This is a minimal example:
var address = InetAddress.getByName("172.16.1.144");
var controller = new DMXIPController(address);
// Load a fixture
var oflFilePath = "/your/path/to/led-party-tcl-spot.json";
Fixture fixture = OpenFormatLibraryParser
.parseFixture(new File(oflFilePath));
// Create a DMX client based on the fixture, a mode, and DMX channel (23 in this example)
var fixtureMode = fixture.modes().getFirst();
DMXClient client = new DMXClient(fixture, fixtureMode, 23);
// This fixture has only one mode with the following channels:
// "channels": [
// "Red",
// "Green",
// "Blue",
// "Dimmer",
// "Effects"
// ]
// Set to full red
client.setValue("red", (byte) 255);
client.setValue("dimmer", (byte) 255);
// Send the data to the DMX interface
controller.render(client);
// Color change effect
for (int i = 0; i <= 100; i++) {
float ratio = i / 100.0f;
client.setValue("red", (byte) (255 * (1 - ratio)));
client.setValue("blue", (byte) (255 * ratio));
controller.render(client);
sleep(50);
}
controller.close();
Detecting USB-to-DMX and IP-to-DMX interfaces
Two tools in the library can be used to detect these interfaces:
- USB-to-DMX: Returns a list of all serial devices connected to the PC. This list can also contain Bluetooth, test, or other ports that are not related to the DMX interface.
- IP-to-DMX: Returns a list of devices that reply to an ArtNet detect packet. Only DMX interfaces should appear in this list.
List<SerialConnection> serialDevices = DMXSerialDiscoverTool.getAvailablePorts();
List<DMXIPDevice> ipDevices = DMXIPDiscoverTool.discoverDevices();
DMX512 JavaFX Demo Project
To demonstrate how the DMX data can be controlled from a user interface and what gets loaded from the OFL JSON files, a separate project has been created. It’s also available as open-source on GitHub.
Next Steps
At this moment, with V0.0.1 of the library, devices can be successfully controlled with IP-to-DMX with the ArtNet protocol. My first USB experiments didn’t succeed. That’s why I focused on the DMX data handling, IP-to-DMX, and OFL integration to reach a first milestone.
New releases will (soon?) include more support for other protocols. However, I hope that some of you can already use this version and are interested in experimenting with it. Please let me know your ideas and remarks!