This is a Python-based lighting control application that allows you to program and trigger lighting scenes on an ADJ Scene Setter 24 or 48 channel DMX controller using your laptop. Instead of manually moving physical faders every time, you can save scenes as files on your laptop and send them to the controller at the press of a button.
Signal chain:
Laptop (this app) → USB → MIDI Interface Cable → MIDI IN on Scene Setter → DMX OUT → Dimmers/Lights
- ADJ Scene Setter 48 or Scene Setter 24 controller
- A USB-to-MIDI interface cable (the kind with a small black box in the middle, with a USB-A end and two 5-pin DIN MIDI ends labelled IN and OUT)
- A laptop running Windows 10/11 (also works on Mac and Linux with minor visual differences)
- Python 3.6 or higher — download from python.org
- The app automatically installs its own dependencies (
mido,python-rtmidi) on first run
- Plug the USB end of the cable into your laptop
- Plug the MIDI OUT end of the cable (labelled "OUT") into the MIDI IN port on the back of the Scene Setter
- The MIDI IN end of the cable can be left unplugged — you only need one direction (laptop → controller)
Important: The ports on the cable are from the cable's perspective. The OUT on the cable sends data out of the laptop, which goes into the IN on the controller. This is correct.
Most USB-MIDI cables use a standard chip (CH345 or CP2102) that Windows installs automatically. To verify:
- Open Device Manager (right click Start → Device Manager)
- Look under Sound, video and game controllers
- You should see something like "USB Audio Device" or "USB MIDI Interface"
- If you see a yellow warning icon instead, search for "USB MIDI cable driver Windows" and download from the manufacturer's website
You need to tell the controller which MIDI channel to listen on (use channel 1):
- Power on the Scene Setter
- Hold the Record button and tap Flash button 1 three times → the display shows "CHI"
- Tap Flash button 1 once to set MIDI channel 1
- Hold Record and press Rec Exit to save and exit
Note: This MIDI channel setting has nothing to do with your DMX channels or physical faders. It just tells the controller which MIDI lane to listen on. Your physical faders continue to work exactly as normal at all times.
Download and install Python from python.org. During installation, make sure to check "Add Python to PATH".
Open a Command Prompt (search "cmd" in Start menu) and run:
python lighting_control.py
On first run, the app will automatically install the required packages (mido and python-rtmidi). This may take a minute. After that it will launch immediately on every subsequent run.
When you launch the app, a dialog appears asking you to select your controller model:
- Scene Setter 48 (48 channels) — shows a 4×12 grid of sliders
- Scene Setter 24 (24 channels) — shows a 2×12 grid of sliders
Select the correct one and click Continue.
- Make sure the MIDI cable is plugged in and the Scene Setter is powered on
- Click Connect MIDI in the left sidebar
- A list of available MIDI ports appears — select MIDIOUT2 (USB2.0-MIDI) 2 or whichever entry contains "MIDI" and "USB" (not "Microsoft GS Wavetable Synth" which is Windows' built-in synthesizer)
- Click Connect — the status indicator turns green if successful
| Element | Description |
|---|---|
| Scene list | All your scenes listed — click any to jump to it |
| + Add | Add a new blank scene |
| ✕ Delete | Delete the currently selected scene |
| Scene name field | Click and type to rename the current scene, press Enter to confirm |
| New | Start a fresh program (clears all scenes) |
| Load | Load a previously saved .json program file |
| Save | Save current program (overwrites existing file) |
| Save As | Save current program to a new file |
| Connect MIDI | Select your USB-MIDI interface port |
| Controller info | Shows which controller model is selected |
| Button | Description |
|---|---|
| ◀ PREV / NEXT ▶ | Navigate between scenes |
| ⚡ LIVE | When checked, automatically sends the scene to the board whenever you change scenes |
| BLACKOUT | Sets all sliders to 0 instantly |
| FULL ON | Sets all sliders to 255 (100%) instantly |
| COPY | Copies the current scene's slider values |
| PASTE | Pastes copied values into the current scene |
| 💾 SAVE | Saves the current program |
| ▶ SEND TO BOARD | Sends the current scene via MIDI to the controller |
| 0-100% | Toggle display between 0–255 (DMX values) and 0–100 (percentage) |
| ? | Opens this help reference |
Each numbered cell corresponds to a DMX channel (which matches the slider number on the physical controller):
- Channel number shown at the top of each cell
- White slider — drag to set intensity, or tap anywhere on the trough to jump to that value
- Value box — click and type a number directly, press Enter or click away to confirm. Values snap to the nearest common level (0, 10, 20, 25, 30, 40, 50, 60, 70, 75, 80, 90, 100%)
A scene is a snapshot of all 48 (or 24) channel values at a given moment — like one "slide" in a slideshow.
To create a scene:
- Set your sliders to the desired levels
- The scene is automatically saved as you adjust — no extra step needed
- Click + Add to create the next scene and start setting new values
To navigate between scenes:
- Click any scene in the sidebar list
- Use the ◀ PREV and NEXT ▶ buttons
- Use the ← → arrow keys on your keyboard
To send a scene to the board:
- Press Enter on your keyboard
- Or click ▶ SEND TO BOARD
- Or enable ⚡ LIVE mode so it sends automatically whenever you change scenes
A program is a collection of scenes saved as a .json file on your laptop. You can have multiple programs for different events (e.g. graduation.json, concert.json, drama_show.json).
- New — clears everything and starts fresh (will ask for confirmation)
- Save / Save As — saves all scenes to a file. The filename appears in the title bar
- Load — opens a file browser to load a previously saved program. If the file was saved for a different controller model, you'll get a warning
The current filename is always shown in the window title bar so you always know which program is loaded.
| Shortcut | Action |
|---|---|
| ← → | Previous / Next scene |
| Enter | Send current scene to board |
| Ctrl+C | Copy current scene |
| Ctrl+V | Paste to current scene |
| Ctrl+S | Save program |
| Ctrl+O | Load program |
| Ctrl+N | New program |
The app communicates with the Scene Setter using MIDI Note On messages:
| Controller Model | Channels | MIDI Notes Used |
|---|---|---|
| Scene Setter 48 | 1–48 | Notes 70–117 |
| Scene Setter 24 | 1–24 | Notes 70–93 |
For each channel, the note number encodes which DMX channel to update, and the velocity (0–127) encodes the intensity. The app scales your 0–255 slider values down to 0–127 for MIDI, and the controller scales them back up internally to 0–255 for DMX output.
The physical faders on the controller are not affected by incoming MIDI. If you move a physical fader after sending a MIDI scene, the physical fader immediately takes back control of that channel.
| Problem | Solution |
|---|---|
| App doesn't launch | Make sure Python is installed and added to PATH |
| No MIDI ports listed | Check cable is plugged in, try a different USB port, check Device Manager for driver issues |
| Green OUT light flashes but lights don't respond | Check cable is in MIDI IN on the controller (not OUT or THRU), verify MIDI channel is set to 1 on the controller |
| Lights respond to test script but not the app | Make sure you selected MIDIOUT2 and not USB2.0-MIDI 1 in the Connect MIDI dialog |
| Sliders look cramped | Resize the window — the app is fully resizable |
| Saved file won't load | Make sure it's a .json file saved by this app, not a different program |
| Controller mismatch warning on load | The file was saved for a different controller model — you can still load it but channel counts may differ |
Programs are saved as standard .json files and can be opened in any text editor. Each file contains:
- The controller model it was created for
- A list of scenes, each with a name and an array of 48 (or 24) channel values (0–255)
This means your lighting programs are human-readable and can be backed up, shared, or version controlled like any other file.
| Platform | Status |
|---|---|
| Windows 10/11 | Fully working |
| macOS | Slightly Broken, need to check |
| Linux | Not tested yet |
Requires Python 3.6 or higher.