A palm-sized M5Stack unit with a DMX (or Art-Net) input and a 433 MHz transmitter. It learns the props' remote codes from their own config files, shows them as tap-to-fire tiles, and fires them from DMX so a lighting desk can cue the props like any other fixture.
controller firmware v1.1The props only ever hear remote-button codes over radio. The controller sends those same codes, so to a lantern it is indistinguishable from the hobby remote β nothing on the props changes, show-mode WiFi-off still applies, and the hand remote keeps working alongside. Three things can make it transmit:
| Trigger | How |
|---|---|
| Touch | Tap a cue tile on the screen. Manual firing at rehearsal, or the stage manager's backup during a show. |
| DMX | A channel in the incoming DMX or Art-Net universe moves into a value band mapped to a cue. This is the desk path β see Desk setup. |
| Web | Nothing fires from the web page. The web UI is for configuration only (book, map, discovery, settings, updates). |
Three parts stack together: the M5Stack CoreS3 (the screen), the M5Stack DMX Base underneath it (RS-485 with XLR adapters), and the RF433T transmitter on a Grove lead from Port A with its little antenna.
Where the desk speaks Art-Net rather than XLR, a second build of the same
firmware (controller-artnet.bin) runs on a CoreS3
Lite with three Grove units instead of the DMX Base: the
RF433T on Port A as before, an M5Stack Unit
PoESP32 on Port C (the Ethernet node, running its own small
firmware) and an M5Stack Unit DMX on Port B giving an XLR
OUT. The Lite itself only has Port A, so it sits on a Base DIN or a
Bus Module to get Ports B and C. Two Art-Net universes are subscribed:
the prop universe feeds the same DMX map and fires cues exactly as
XLR does, and the out universe is retransmitted as plain DMX512 on
the Unit DMX — so the controller doubles as a one-universe Art-Net
node for anything else at the desk.
NO NODE (nothing on the Grove
link), NO NET (node up, no Ethernet link), NO IP
(waiting for DHCP; after 10 s the node falls back to a 2.x.y.z
address), then the usual dmx:live / dmx:idle.vivo-ctrl-xxxxxx (ask your production tech for the
password β it's the same one the props use). Join it from a phone or
laptop; the setup page opens by itself.http://vivo-ctrl-xxxxxx.local (or the IP in the screen's
header). Untick Bring WiFi up on boot if you'd
rather it started dark.Whatever the boot setting, the left segment of the on-screen header is a WiFi toggle: tap it to bring WiFi up or take it down without touching a browser. The header shows the IP once it has one.
The touchscreen is the controller's show-time face and works with no network at all.
| Area | What it is |
|---|---|
| Header, left | WiFi state and IP. Tap = toggle WiFi. |
| Header, right | MAP opens the on-screen map stepper; MON opens the DMX monitor. Both below. |
| Cue tiles | Two columns of tiles, grouped under a heading per source (one source per prop config in the book). Tap a tile and the controller transmits that cue's code; the tile highlights for the half-second the send takes. Long books scroll. |
| Status strip | Two lines at the bottom: the last cue
fired from DMX (source and cue name), then steady stats β DMX
live/idle, WiFi, and any map file
error. |
The controller never invents codes. It keeps a book of sources, each one a prop's exported configuration; every scene (slot) in that file becomes a cue with that scene's captured codes. Set the props up first β names, buttons, looks β then fill the book. Three ways, all on the web UI:
| Route | When |
|---|---|
| Book β Upload bookβ¦ | You have a
prop's Export file. The file name becomes the
source name (lantern-config.json reads as
lantern). |
| Discover β Scan β Import | The props are on the venue WiFi with the controller. Scan lists every prop that answers; Import fetches its config directly; Import All does the lot. |
| Discover β Enumerate β Crawl selected | Fresh props still in hotspot mode. Enumerate lists their hotspots by name, type and signal; tick the ones you want and crawl. The controller leaves the venue WiFi, visits each hotspot in turn and fetches its config, then comes back β your browser drops off for the duration and the page picks the result up on its own. The screen shows live progress throughout. |
Twenty identical lanterns would make twenty identical sources, so imports are de-duplicated by content: a config whose scenes and codes match an existing source is reported as identical to "lantern" β skipped, and a config that differs only in name replaces the matching source rather than sitting beside it. A synced fleet therefore converges on one source, which is what you want β one heading of tiles on the screen and one fixture on the desk.
lantern-prototype becomes
lantern-prototyp). If you re-import under a different name
after mapping, the map's rows go unresolved and DMX quietly stops
firing that source. The map page flags it in red; fix by renaming the
source to match, or re-adding the source to the map.Each source card also offers Download (the stored file, byte-identical) and Delete.
The map is the bridge from desk to book: this channel, in this value band, fires this cue. The natural shape is one DMX channel per source, with the source's cues sharing the channel as even value bands. That gives the desk one fixture per prop type with a single "scene" parameter β the Desk setup page covers the desk side of that.
The map holds up to 64 rows in total. A card marked entries span more than one channel was hand-edited or imported that way β Re-band it onto one channel before exporting a fixture for it.
For quick fixes at the desk without a browser, MAP in the header opens a stepper over the same map. Up/Down move a cursor over the rows (source headings and cues); tap a row to jump the cursor there. The bottom row of buttons depends on what's selected:
| Cursor on | Buttons |
|---|---|
| a source heading | β10 / β1 / +1 / +10 on that source's channel (1β512), moving every one of its cues together |
| a cue row | Loβ / Lo+ / Hiβ / Hi+ on that cue's band, Β±5 a tap, kept within 0β255 and lo β€ hi |
Save writes it; Cancel discards. Cue assignment (which cue a row points at) stays web-only. A source showing MIXED spans channels and can't be stepped on screen β re-band it from the web page.
MON shows all 512 incoming channels as a 32Γ16
grid of bars coloured by level β the fastest way to confirm the desk is
actually sending on the channel you think. Cue firing carries on
underneath it; the monitor yields to RF, so a burst is never delayed by
the display. The bottom line reads RF n/n Β· def Β· Hz Β· loop ms
(sends attempted/completed, paints deferred for RF, repaint rate, worst
loop time) and is prefixed NO SIGNAL when no DMX is arriving.
Gridlines and their accent spacing are a Settings option. Tap
X to leave.
controller.bin (CoreS3 SE with
the DMX Base) or controller-artnet.bin (CoreS3 Lite with the
node) from the Firmware
page's controller section β flashing the other variant costs you DMX
until you flash back. The controller verifies the image before switching
to it, then reboots; the book, map and settings all survive. An
interrupted upload is abandoned cleanly β just try again. If a bad flash
ever leaves it unbootable, USB is the recovery path (bench job).node.bin
from the Firmware page's node section; the controller stages it, streams
it to the node over the Grove link and reports progress, and the node
verifies and reboots. Cue firing keeps running meanwhile.map.unresolved greater
than zero is the tell for the source-name problem above.| Symptom | Likely cause and fix |
|---|---|
| Screen taps fire the props but DMX doesn't | Look at the
status strip: dmx:idle means no frames β cable, the
node's output, or DIP switch 2 in bypass. dmx:live but
nothing fires: open MON and check the channel
actually moves; then check the map page for a red unresolved
warning (source renamed on re-import β see the
book). |
| Desk sends, controller shows the fire, prop doesn't change | Radio. Move the antenna away from the DMX Base, get closer, check the prop responds to its hand remote from the same spot. A lantern sitting in a candle/fire scene sometimes needs a second send to leave it β a second cue step or a re-fire. |
| Three changes in quick succession, middle one lost | Sends are sequential (~0.5 s each) with room for one held follow-on; a third trigger inside that window replaces the held one. Keep to two prop channels per cue, and a second between follow-on cues. |
| Fader moves through several scenes on the way up | Each band fires as the value enters it. Give the scene parameter zero time / snap on the desk β firing rules. |
| Web page gone mid-crawl | Expected: the controller leaves the venue WiFi to visit prop hotspots. Watch the screen; the page reconnects when it returns (a few minutes at most). |
| Controller boots without WiFi after an update | Tap the left header segment to bring it up, then tick Bring WiFi up on boot in Settings if it was unticked. |
| Import says "identical β skipped" | Not an error: that prop's config already exists as a source under another name. One source per identical fleet is the intended result. |