QLAB Buddy
Connects to QLab 5 on a Mac — or directly to Go Button on iPhone/iPad — and shows the live cue name, timer, and status. Pair wireless Card Fountain props and fire them from QLab or Go Button.
QLAB Buddy BETA
A wireless touchscreen that shows your show live — cue name, timer, and connection status on a bright 3.5″ display. Put it anywhere: the tech table, the wings, your hand. Works with QLab 5 on a Mac, or Go Button on an iPhone with no Mac at all. Pair wireless Card Fountain props and fire them straight from your cues.
#timer/ directives baked into QLab notes.Try it
Reading the status dot
Blue — connected to a show
- QLAB + gold pip — QLab connected, internet reachable. Healthy showtime state.
- QLAB — QLab connected, no internet. Cues still work fine.
- Go Button + gold pip — Go Button connected, internet reachable.
- Go Button — Go Button connected, no internet. The show still runs fine.
Gold — on a network, no show yet
- WiFi — on WiFi with internet, but no QLab or Go Button found yet.
- LAN — USB-C to a Mac with internet, no QLab or Go Button yet.
- Hotspot — the buddy’s own hotspot is on and a device has joined it.
- Pairing — Pair Devices is running and a prop has joined the hotspot.
White — on a network, not ready yet
- WiFi — on WiFi but no internet yet, and no QLab or Go Button.
- LAN — USB-C cable plugged in, still getting an address or no internet yet.
- Hotspot — hotspot on, nothing connected to it yet.
- Pairing — Pair Devices running, waiting for a prop to join.
Red — no network
- No WiFi — no network path at all. Plug in USB-C or enter WiFi credentials.
Hardware
Hold BOOT on the board, plug in USB-C, release BOOT, then click Connect and Install (~60 s). After flashing, follow Get Started.
Desktop Chrome, Edge, or Opera — flashing isn’t supported in Firefox or Safari.
Get Started
Four steps from unboxed hardware to a working buddy.
-
Buy the hardware The Waveshare ESP32-S3 Touch LCD 3.5” — links above in The Buddy. Nothing else to buy.
-
Flash the firmware In Chrome (or Edge / Opera) on a desktop: hold BOOT, plug in USB-C, release BOOT, then click Connect and Install in the install button above. Takes about 60 seconds. Web Serial isn’t available in Firefox or Safari.
-
Enter your WiFi credentials On the buddy, tap Devices (top center tab) → SETTINGS → WiFi row. Type your network SSID and password. The buddy will connect immediately — no reboot needed. The status dot turns gold when it has a network path.
-
Choose your mode
- QLab 5 — plug into your Mac via USB-C or join the same WiFi network. The buddy finds QLab automatically within a few seconds. Status dot turns blue labeled QLAB. See Using with QLab 5 for the full setup.
- Go Button — make sure your iPhone/iPad is on the same WiFi network and Go Button’s UDP Reply Port is set to 53001. The buddy discovers the show automatically. Status dot turns blue labeled Go Button. See Using with Go Button for the full setup.
Using with QLab 5
#timer/ directives. QLab 4 gives you GO/PANIC/STOP and a blue dot, but Stage view stays blank. Get QLab 5 → (free, opens .qlab4 files via File → Import).
OSC setup in QLab
Two settings in every workspace. Do this once per show file and it sticks in the .qlab5 file.
-
Enable OSC input on port 53000 Workspace Settings → Network → OSC Controls (or OSC Receiver).
Tick Enable Network OSC. Set the listen / input port to 53000. -
Allow control Workspace Settings → Network → OSC Access.
Check Allow OSC connections. In the No Passcode row, tick Control. Save.
Three ways to connect
- USB-C — sub-millisecond latency, completely RF-immune. Best choice for showtime. The buddy presents as a USB-NCM Ethernet device at
192.168.7.1— your Mac’s WiFi stays the default route, so QLab and internet work normally alongside it. - WiFi — join the same network as your QLab Mac. Discovery is automatic, typically connects within 2–3 seconds.
- Hotspot — the buddy hosts its own AP if you have no router. Used for prop pairing too. Credentials below.
QLAB Buddy
Passwordqlabbuddy
Cue-note timer directives
Drop directives into a cue’s Notes field — the buddy reads them and strips them from the visible text, so the operator never sees them on the QLab screen. Both : and . work as separators.
| Directive | What it does |
|---|---|
#timer/HH:MM.SS |
Countdown from the specified time (amber). Goes negative and turns red after expiry. Hours are optional — #timer/05.00 and #timer/00:05.00 both mean five minutes. |
#timer/start |
Count-up stopwatch from 0:00.00 (green). Drop on the first cue of the show; pair with #timer/end on the last. |
#timer/pause |
Freeze the timer in its current color. Amber if time remains, red if over, green if counting up. Tap the timer area on the buddy to clear manually. |
#timer/resume |
Un-pause exactly where it stopped — no gap, no double-counting. |
#timer/end |
Show over. Freezes the display with the final run time. Green if you came in at or under the duration; red if you ran over. Count-up timers (no original duration set) always freeze green. |
#timer/clear |
Resets all timers and clears any pause-freeze. Drop this on a pre-show reset cue. |
Workspace Lock
The buddy auto-selects the first workspace it finds on the network — whether that’s a QLab workspace or a Go Button show. In a more complex rig you can lock it to exactly the right one.
Workspace picker
Go to Settings → Workspace to open the picker. Every workspace the buddy has discovered on the current network appears as a row. Short-tap a workspace to select it as the active workspace — the buddy stays on that selection through WiFi drops, reboots, and restarts.
To hard-lock onto a specific host device, hold a workspace row for 2.5 seconds. The row fills as you hold. When it completes, the buddy locks to that workspace and that device IP — it won’t wander to another host on the network even if something else responds first. The locked row turns blue and pins to the top of the list with a LOCKED badge. Hold the same row again to unlock.
If the locked host goes offline, a grey ghost row stays at the top so you can see and unlock it without losing the lock inadvertently. The buddy waits quietly for that host to reappear and ignores everything else on the network.
The picker stays open after a tap or lock so you can review the state. Tap the ‹ Back pill (top-right) to return to Settings.
OSC Access
Tap Settings → OSC Access to open the OSC Access page. This is where all OSC permission and passcode settings live.
- Mode (VIEW / CTRL) — CTRL (default) lets the buddy send GO, PANIC, STOP, and cue-navigation commands. Switch to VIEW to make the buddy read-only: it monitors the show live but all control buttons and chevron navigation are silenced. Useful at the tech table or for a second monitor display you don’t want to accidentally trigger.
- QLab passcode — if your QLab workspace has an OSC passcode set under Workspace Settings → Network → OSC Access, enter the same numeric code here. The buddy sends it automatically on every connect. Leave blank if no passcode is set.
- Go Button passcode — if your Go Button show has an OSC passcode set, enter the matching numeric code here. This is the only place you enter it: the buddy shares it with every paired Card Fountain automatically (see Passcode auto-sync to props below). Leave blank if no passcode is set.
Passcode auto-sync to props NEW in 0.9.5
When OSC is passcode-locked, a Card Fountain only fires from a matching passcode — so a prop on a shared network won’t fire from an unauthorized sender. You never type that passcode into the prop. Enter the Go Button passcode once on the buddy (Settings → OSC Access → Go Button passcode) and the buddy pushes it to every paired prop for you.
- Set once, shared everywhere — the buddy sends the stored Go Button passcode to each paired Card Fountain in the background. Newly discovered props, props that reconnect, and props pairing via SYNC all receive it — no per-prop entry and no re-pairing.
- Changes re-push automatically — whenever you change the passcode on the buddy — from the numeric pad or by tapping x to clear it — the new value is pushed to every paired prop right away. Clearing it propagates too, so props stop expecting a passcode and keep firing.
- Self-healing on reconnect — if a prop was offline when you changed the passcode, or a push was missed, it re-syncs silently the next time it reports in. Each prop advertises a fingerprint of its stored passcode; when the buddy sees a mismatch it re-pushes the current code on its own. Cue triggering just keeps working — no manual action needed.
RF Relay BETA
A networked sub-GHz capture and replay node. Point a 315, 433, 868, or 915 MHz fixed-code remote at it, learn the code via OSC or the onboard encoder, then replay it from QLab or Go Button on every subsequent show. Once provisioned the RF Relay fires independently — the buddy is only needed for initial WiFi SYNC and monitoring.
Designed for battery-powered remotes that control props or practical effects that can’t be wired: wireless LED controllers, RF dimmers, ceiling fans, and any fixed-code PT2262/EV1527 remote.
#timer/ directives in cue notes. Activates after 45 s idle.Pairing with the buddy
- Start pairing mode. On the buddy, tap Devices → Pair Devices. This turns on the hotspot and begins scanning.
- Power on the RF Relay. It scans for the “QLAB Buddy” hotspot on every boot and joins automatically.
- Tap SYNC on the buddy when the device appears. Pushes your main WiFi credentials and a static IP.
Hardware
Amazon →
Display UI
| Screen | Description |
|---|---|
| Home | 25-slot list — slot number, name, frequency, captured code. Short press fires. Long press opens Setup. |
| Setup | Per-slot menu: LEARN / FIRE / RENAME / DELETE. Long press back. |
| Listening | 30 s capture window. Auto-scans 315 / 390 / 418 / 433 / 868 / 915 MHz. Short press cancels. |
| CAPTURED | Code, frequency, and protocol confirmed. Auto-returns to Home. |
| NO SIGNAL | Nothing received in 30 s. Auto-returns to Setup. |
| Rename | Character picker (A–Z, 0–9). Short press places, long press saves. |
| Screensaver | QLab elapsed timer or #timer/ countdown. Activates after 45 s idle. Any input exits. |
OSC reference
| Address | What it does |
|---|---|
/rf/N | Fire stored slot N (1–25) for the default 1 s hold. Optional float or int argument overrides the hold duration in seconds — e.g. /rf/1 with arg 0.5 fires for 0.5 s. |
/rf/N/TIME | Fire slot N for a hold time encoded in the path — e.g. /rf/1/3 (3 s), /rf/1/00:00.03 (3 s), /rf/1/00:01.30 (90 s). Lets a QLab Network cue set duration without an OSC argument. |
/rf/learn/N | Arm capture for slot N at its stored frequency. 30 s window — hold the remote button to capture. Auto-scans all bands when no frequency is stored yet. |
/rf/learn/N/MHZ | Arm capture for slot N at an explicit frequency — e.g. /rf/learn/1/433. Accepts any numeric MHz value (315, 433.92, 868.35, 915, etc.). |
/rf/freq/MHZ | Set the active band and re-drive the antenna switch — e.g. /rf/freq/315, /rf/freq/433, /rf/freq/868, /rf/freq/915. |
/rf/stop | Cancel an armed learn without saving. |
/ping | Connectivity check — board replies /pong (and sends /hello). |
/identify | 3× white LED flash — confirms which board you’re targeting. Sent by the buddy’s TEST button. |
T-Embed uses native USB: plug in USB-C, click Connect — the tool sends a 1200-baud touch to enter download mode automatically. No BOOT button needed. Subsequent updates are wireless OTA from the buddy.
Universal Controller BETA
A wireless OSC prop controller for live shows. Pair it with the buddy, give it a static IP, and drive motors and servos directly from QLab cues or Go Button. Two board options: the NULLLAB Maker-ESP32 gives you four DC motor channels and four servo channels; the Romeo Mini ESP32-C3 is a smaller form factor with two motor channels and four servo channels.
Build anything that moves: turntables, lifts, reveals, automated set pieces, puppet rigs. If it takes a motor or a servo, the Universal Controller drives it from your cue stack.
Pairing with the buddy
- Start pairing mode On the buddy, tap Devices → Pair Devices. This turns on the hotspot and begins scanning.
- Power on the Universal Controller. It scans for the “QLAB Buddy” hotspot on every boot and joins automatically. The buddy’s hotspot just needs to be active — there is no fixed time window.
- Tap SYNC on the buddy when the device appears. Pushes your main WiFi credentials + static IP assignment.
Hardware
DFRobot →
Amazon →
Amazon →
LED status
Idle
- Blue — QLab show file open and ready.
- Green — WiFi connected, no QLab file open.
Boot
- White pulse ×3 — Boot animation, board is starting up.
- Yellow — Connecting to WiFi.
- Magenta blink — On buddy hotspot, waiting for SYNC or receiving credentials.
Pairing
- 3× green flash — Credentials saved, board rebooting onto your WiFi.
Active
- White breathing — Motor running.
- 3× white flash —
/identifyreceived, confirms which board you’re targeting.
Error
- Red blink — WiFi dropped, waiting to reconnect.
- Yellow — Actively reconnecting to WiFi.
OSC reference
Motors (M1–M4)
| Custom Message | What it does |
|---|---|
/m1/start/80/00:00.03 | Run M1 forward at 80 % for 3 s |
/m1/start/80 | Run M1 forward at 80 % for default duration (5 s) |
/m1/start | Run M1 forward at default (75 % / 5 s) |
/m1/reverse/80/00:00.03 | Run M1 in reverse at 80 % for 3 s |
/m1/stop | Halt M1 immediately |
/m1/test | Quick test fire — 75 % / 5 s |
/stop | Emergency stop — halts all four motors immediately |
/ping | Connectivity check — board replies /pong |
/identify | Flash LED 3× white — confirms which board you’re talking to. Sent automatically by the buddy’s TEST button. |
Servos (S1–S4)
| Custom Message | What it does |
|---|---|
/s1/90 | Move servo 1 to 90° instantly |
/s1/90/00:00.03 | Move servo 1 to 90° over 3 s |
/s1/angle/90 | Move servo 1 to 90° instantly (explicit keyword form) |
/s1/angle/90/00:00.03 | Move servo 1 to 90° over 3 s (explicit keyword form) |
/s1/velocity/30 | Sweep servo 1 continuously at 30°/s (stops at 0° or 180°) |
/s1/velocity/0 | Stop continuous sweep, hold at current position |
/s1/bounce | Bounce servo 1 back and forth at 30°/s until stopped |
/s1/bounce/60 | Bounce servo 1 back and forth at 60°/s until stopped |
/s1/center | Move servo 1 to 90° (center) |
/s1/stop | Halt servo 1 at current position |
/s1/pulse/1500 | Set servo 1 to raw pulse width 1500 µs (advanced) |
Duration formats
| Format | Example | Result |
|---|---|---|
| HH:MM:SS | 00:00:03 | 3 s |
| Seconds suffix | 3s | 3 s |
| Milliseconds suffix | 500ms | 0.5 s |
| Bare decimal | 1.5 | 1.5 s |
Hold BOOT on the board, plug in USB-C, release BOOT, then click Connect and Install.
Desktop Chrome, Edge, or Opera only — Web Serial is not supported in Firefox or Safari.
Hold BOOT on the board, plug in USB-C, release BOOT, then click Connect and Install.
Desktop Chrome, Edge, or Opera only — Web Serial is not supported in Firefox or Safari.
Card Fountain — Handheld ALPHA
Pocket-sized Card Fountain. Fires on the same OSC interface as the Dekolta. Pairs over the buddy’s hotspot, gets a static IP, and takes /start from QLab network cues or Go Button cue tags.
Pairing with the buddy
- Start pairing mode On the buddy, tap Devices → Pair Devices. This turns on the hotspot and begins scanning.
- Power on the Handheld within ~5 seconds. It scans for the “QLAB Buddy” hotspot on every boot and joins automatically.
- Tap SYNC on the buddy when the Handheld appears in the list. This pushes your main WiFi credentials to the prop, gives it a static IP, and completes the pairing.
Hardware
DFRobot →
Amazon →
Amazon →
Amazon →
C3 boards auto-enter bootloader — no button hold needed. Just plug in USB-C and click Connect and Install.
Desktop Chrome, Edge, or Opera — flashing isn’t supported in Firefox or Safari.
Card Fountain — Dekolta ALPHA
Stage Card Fountain. Pairs over the buddy’s hotspot; QLab drives it over OSC. Cosine ramp for smooth motor acceleration. Static IP survives reboots and router restarts.
Pairing with the buddy
- Start pairing mode On the buddy, tap Devices → Pair Devices.
- Power on the Dekolta. It joins the “QLAB Buddy” hotspot automatically on first boot or after a factory reset.
- Tap SYNC on the buddy row. Pushes WiFi credentials + static IP assignment.
Hardware
DFRobot →
Amazon →
Amazon →
Amazon →
Hold BOOT on the board, plug in USB-C, release BOOT, then click Connect and Install.
Desktop Chrome, Edge, or Opera — flashing isn’t supported in Firefox or Safari.
Device Triggering from QLab
Both Card Fountain models use the same OSC interface. Set each one up as a Network Patch in QLab and fire it with Network cues.
-
Find the prop’s IP on the buddy Go to the Devices view. The IP appears under each paired prop’s name (e.g.
192.168.1.62). This address is permanent across reboots, router restarts, and DHCP churn — QLab patches stay valid forever. -
Add a Network Patch in QLab Workspace Settings → Network → OSC Controls → + (add).
Name: anything you want (e.g.Handheld Fountain).
Network Patch: tap + Add Network Patch if needed. Type:UDP, Host:<prop IP>, Port:8000. -
Add a Network cue Toolbar → + → Network. Set the destination to your prop patch. In the Custom Message field, type the OSC address + arguments separated by spaces.
OSC commands
| Custom Message | What it does |
|---|---|
/start/80/00:00.03 |
Run motor forward at 80 % for 3 s. Cosine ramp in/out. |
/start |
Run forward at default velocity and duration (75 %, 5 s). |
/reverse/80/00:00.03 |
Run motor in reverse at 80 % for 3 s. |
/stop |
Stop immediately. Safe to fire even if nothing is running. |
/test |
Quick test fire — 75 % for 5 s. Handy for a soundcheck cue. |
/ping |
Connectivity check. Prop replies /pong. Use as a pre-show health check. |
Device Triggering from Go Button NEW in 0.9.5
How it works: Go Button can’t send OSC out to a device on its own, so the buddy does it for you. Put a short trigger tag in a cue’s name. The buddy watches Go Button’s live cue display — the moment the playhead leaves the tagged cue and advances to the next one, the buddy fires the matching prop. In practice this happens right as GO is pressed, since pressing GO is what advances the playhead. The buddy is the bridge between Go Button and the prop — it must be powered on and connected to the show (it only needs USB power, not a computer). The tag uses the prop’s IP address directly, so it always targets the right device regardless of device type or how many props are on the network.
192.168.86.62). This address is permanent — it never changes after pairing, so paste it once and it works forever.
-
Add the tag to a Go Button cue name In Go Button, rename the cue so its name contains the trigger tag. The tag can sit anywhere — the cue name can still read naturally:
Big Reveal #192.168.86.62/80%/3s -
Press GO When GO is pressed, Go Button advances the playhead to the next cue. The buddy sees the displayed cue name leave the tagged cue and immediately fires the prop — never when you merely open, reopen, or scrub to the cue. Pressing GO on the same tagged cue again re-triggers the prop, so a repeated reveal works every time.
Tag syntax
| Tag in the cue name | What it does |
|---|---|
#192.168.86.62/start |
Fire the prop at that IP at default velocity and duration (75 %, 5 s). |
#192.168.86.62/80%/3s |
Fire at 80 % for 3 s. (Velocity first, then duration — implicit start.) |
#192.168.86.62/reverse/80%/3s |
Run motor in reverse at 80 % for 3 s. |
#192.168.86.62/stop |
Stop the prop immediately. |
#192.168.86.62/test |
Quick test fire — 75 % for 5 s. Handy for a soundcheck cue. |
Big Reveal #192.168.1.2/80%/3s #192.168.1.3/80%/3s |
Two tags in one cue name — fires both props simultaneously. |
The pieces
- IP address — the prop’s static IP from the buddy’s Devices view. Works with any device type (Handheld, Dekolta, or future props) and with multiple props of the same type — each has a unique IP.
- Velocity —
0to100. The%sign is optional (75and75%are identical). - Duration —
3s(seconds),500ms, a plain number of milliseconds (3000), or decimal seconds (2.5s).
Don’t tag the last cue
- Fix — keep at least one cue after the tagged cue: a 1-second blackout, a silent memo, or an
ENDmarker. Trailing / cleanup cues are normal show-building practice and this is the only reliable solution.
#IP/ tag syntax works in QLab too — put it in the cue’s Notes field (Go Button has no notes field, so it reads the cue name instead). Same syntax, different field.
Magic API
The Magic API page turns the Buddy into a live data monitor. Point it at up to three HTTP endpoints — a wiki, a bridge relay, or a lyric/word service — and the Buddy polls them every 10 seconds and shows the results on screen. No QLab required, no cues involved: it’s always-on ambient data for the stage.
Setting URLs
Each section is configured with its own URL. URLs are stored on the Buddy and survive reboots.
- Open the API page on the Buddy and navigate to the section you want to configure (WIKITEST, BRIDGE, or ELIPS).
- Double-tap the section header (e.g. tap “WIKITEST” twice quickly). The on-screen keyboard appears.
- Type or paste your endpoint URL and confirm. Both
http://andhttps://are supported. URLs can be up to 128 characters. Certificate errors on HTTPS are bypassed — self-signed certs work fine. - The Buddy polls immediately and then every 10 seconds while the API tab is open. Tap the blue SYNC button in the header to force a manual refresh at any time — it flashes green to confirm the request was sent.
Endpoint types
The three slots each speak a slightly different protocol, designed to match common data services used in theatrical production.
WIKITEST — plain text
The simplest format. The Buddy makes a GET request and displays the raw response body as the Value field. No JSON parsing — whatever the server returns is shown verbatim.
Use this for any lightweight endpoint that returns a single string: a custom show-state server, a script cue counter, a simple webhook that writes a word to a text endpoint, etc.
| Request | Expected response |
|---|---|
GET <your-url> | Plain text string — displayed as Value |
BRIDGE — JSON value relay
Designed for wkt.pw-compatible bridge services and any JSON endpoint that wraps a value in a standard envelope. The Buddy reads the value or rawValue field from the JSON response body and shows it as Value.
| Request | JSON field read | Displayed as |
|---|---|---|
GET <your-url> | value or rawValue | Value |
Either field name is accepted — if both are present, value takes priority. Any other keys in the response are ignored.
ELIPS — artist / song / word
A richer format for live lyric feeds, prompter services, or any endpoint that streams the current word or line being spoken/sung on stage. The Buddy reads three fields and shows them as separate labeled rows.
| Request | JSON field read | Displayed as |
|---|---|---|
GET <your-url> | artist | Artist |
song | Song | |
word or lyric or selected or title | Word |
For the Word field the Buddy tries each key in order until it finds one that exists in the response — so the same endpoint works whether it calls the current word word, lyric, selected, or title. Fields that are absent or empty are left blank on screen.
Status & errors
Each section independently shows its connection state. Values appear white when data is live, red on an error, and grey when no URL has been set yet. If the Buddy has no internet at all, the entire page displays “No Internet” in red.
| Message shown | What it means |
|---|---|
Set URL — double-tap header | No URL configured for this slot yet. |
Can't connect | Network error reaching the server (DNS failure, refused connection, timeout). |
No response | Server accepted the connection but returned no data. |
Wrong URL or code | Server returned 401 or 403 — check the URL or any access token. |
Link not found | Server returned 404 — the path doesn’t exist. |
Server busy | Server returned 5xx — try again or check the service. |
Check the link | Response arrived but JSON parsing failed — confirm the endpoint returns valid JSON in the expected format. |
No Internet (full page) | The Buddy’s WiFi is connected but has no internet route. |
Troubleshooting
Flashing issues
- “Browser not supported” — switch to Chrome, Edge, or Opera on desktop. Web Serial doesn’t work in Firefox or Safari.
- Port doesn’t appear in the list — try a different cable (many are charge-only). Quit any app holding the port (Arduino IDE,
screen, etc.). On Mac, checkls /dev/cu.usbmodem*. - Flash fails partway — unplug, hold BOOT, plug back in, release BOOT, retry.
- Flashed successfully but buddy doesn’t show anything — power-cycle the board. On first boot after a clean flash, the buddy goes straight to the Devices view and waits for WiFi credentials.
QLab not connecting (dot stays white or gold)
- Confirm the buddy and QLab Mac are on the same network, or connected via USB-C.
- Workspace Settings → Network → OSC Controls: enable Network OSC input, port 53000. Save.
- Tap GO on the buddy — status dot should turn blue within seconds.
- If you’re on a different subnet or the venue has AP isolation, try Settings → QLab IP to enter the Mac’s IP directly.
Stage view blank with dot blue (QLab 4)
The buddy needs QLab 5’s push-update OSC API. QLab 4 doesn’t have it. Upgrade free at qlab.app — QLab 5 imports .qlab4 files via File → Import.
Buddy connects but GO / PANIC / STOP do nothing
First check the buddy’s own mode: Settings → OSC Access → VIEW / CTRL. If it’s set to VIEW, all control buttons and chevron nav are intentionally silenced — tap CTRL to restore full control.
If the toggle is already on CTRL, check QLab’s OSC permissions: Workspace Settings → Network → OSC Access → No Passcode row → tick Control. Save. Also make sure no QLab passcode is set, or enter the matching code under Settings → OSC Access → QLab passcode.
Go Button show not appearing in the workspace picker
- Confirm both the buddy and the iPhone/iPad are on the same WiFi network. Go Button discovery uses UDP broadcast — it doesn’t cross subnets or VLANs.
- In Go Button: Settings → Connections → UDP Reply Port = 53001. This is the single most common miss. Go Button hears the buddy’s query but replies to the wrong port and the buddy sees nothing.
- If OSC Access in Go Button has a passcode, enter the same numeric code on the buddy under Settings → OSC Access → Go Button passcode. A mismatched or missing passcode makes Go Button silently reject the buddy’s queries.
- Confirm Go Button has a show loaded and the session is active. The buddy only discovers active shows.
- On the buddy, tap the workspace name in the status bar to force a fresh scan.
Go Button timer stuck at 00:00:00
- Double-check UDP Reply Port = 53001 in Go Button (above).
- Fire a cue in Go Button. The timer starts after Go Button reports elapsed time advancing — takes one poll cycle (~0.5 s).
- If the show was reset, the timer resets to 00:00 automatically and resumes when the show advances.
Card Fountain not appearing in Devices
- Tap Pair Devices on the buddy to enable the hotspot, then power-cycle the prop. It scans for “QLAB Buddy” on every boot and joins within ~10 s.
- Tap the prop’s row SYNC button to push WiFi credentials and complete pairing.
- If the row shows WAIT for more than 30 s, power-cycle the prop closer to the buddy and try again.
- Paired devices vanished after a reboot? FIXED in 0.9.5 — on buddy firmware before 0.9.5, a quirk in flash storage could let a stale “deleted” list survive a power-cycle and prune a freshly-paired prop on the next boot. This is fixed: paired devices now reappear automatically on reboot, and re-pairing a device you previously deleted now sticks across reboots too. Update the buddy to 0.9.5+ if a prop keeps disappearing after power-cycling.
Card Fountain doesn’t fire from QLab
- Verify the Network Patch is set to UDP, the prop’s IP (found on the Devices view), port 8000.
- Tap TEST on the Devices row — if the prop fires, the issue is in the QLab Network cue patch, not the prop or buddy.
- Use
/pingfrom a QLab Network cue to confirm you can reach the prop before relying on/start.
Card Fountain doesn’t fire from a Go Button cue name
- Is the tagged cue the last cue in the list? This is the most common cause. The buddy detects a GO by the playhead advancing to the next cue, so GO’ing a tagged last cue moves the playhead to nothing and the prop won’t fire. Reliable fix: keep at least one cue after the tagged cue — a 1-second blackout, a silent memo, or an “END” marker. Note: giving the tagged cue a longer duration does not help if the cue contains an internal GoTo or other action that completes the group immediately — the trailing-cue approach is the only reliable fix in that case.
- Check the tag uses the prop’s IP address (shown in the buddy’s Devices view), not a name. Format:
#192.168.86.62/80%/3s. The IP is permanent after pairing. - Confirm the verb is valid:
/start,/80%/3s(implicit start),/reverse/80%/3s,/stop, or/test. - The prop must be paired with the buddy, and the buddy must be powered on and connected to the show — it’s the bridge between Go Button and the prop (USB power is enough, no computer needed). The trigger fires the moment Go Button advances the playhead past the tagged cue, even right after a buddy reboot before the prop has reported in.
- Tap TEST on the prop’s Devices row to confirm the prop itself works — if TEST fires but the cue tag doesn’t, the issue is the tag text or the last-cue gotcha above.
- OSC passcode is handled for you. NEW in 0.9.5 If the Go Button workspace has an OSC passcode, the buddy shares it with each paired prop automatically — no per-prop setup or re-pairing needed. Change the passcode once on the buddy and every prop re-syncs on its own, even one that was offline when you changed it.
Card Fountain fires when you open the Go Button show FIXED in 0.9.5
On buddy firmware before 0.9.5, simply opening or reopening a Go Button show file could fire a tagged cue that the buddy saw as already “running.” This is fixed: a prop now fires only when the playhead actually advances past the tagged cue (i.e. when GO is pressed and Go Button moves on), never on file open, reopen, or while you scrub through cues with the on-screen arrows. Update the buddy to 0.9.5+ if a prop triggers unexpectedly on show open.
Release History
Highlights from earlier versions
- Touch + reliability fixes (0.9.8–0.9.9) — Touch unresponsiveness fixed: AP-subnet probe packets were firing on every draw cycle, blocking touch reads for ~30 ms; removed. Pulsing-dot redraws rate-limited to 12 fps to stop unnecessary screen contention. Tab bar dead zone between LIVE / DEVICES / API tabs eliminated (8 px gap now split 4 px each side). Prop LED broadcast: the buddy now sends
/qlab/connectedand/qlab/disconnectedto all paired props the instant a QLab workspace opens or closes — props update their LED immediately without waiting for the next poll cycle. UC TEST button now sends/identify(3× white LED flash) instead of/start, so you can confirm which board you’re targeting without triggering a motor. Auto-timezone fix:autoTimezone()was blocking the main loop for up to 1.5 s every 60 s in venues without internet; moved to a background core. Go Button: fix session no longer triggers discovery backoff. - Go Button cue triggering + passcode auto-sync (0.9.5) — Tag a Go Button cue name with a device tag (e.g.
#192.168.86.62/start) and the matching Card Fountain fires the moment Go Button advances the playhead past that cue. Go Button can’t send OSC to a device itself, so the buddy bridges it — the buddy watches Go Button’s live cue display and fires the prop the instant the playhead leaves the tagged cue, even right after a buddy reboot before the device has reported in. The buddy’s stored Go Button OSC passcode auto-syncs to every paired prop — set it once and each Card Fountain receives it; if a prop was offline when you changed it, it self-heals on its next reconnect via a passcode fingerprint check, so cue triggering just keeps working. Cue-name display strips the#IP/verbtag when a readable note precedes it, and long names no longer overrun the navigation arrows. Fixes: props now fire only when a cue is actually GO’d — never when you merely open or reopen the show, and using the on-screen chevrons to scrub no longer mis-fires a tagged prop. Closing a picked Go Button file blanks the cue / stage / timer almost instantly instead of holding the stale display ~1.5 s. Paired devices now survive a buddy reboot (and a deleted-then-re-paired device stays paired). The Devices-view UPDATE button is refused with a clear HOTSPOT hint while the hotspot is on, since a prop on the hotspot has no internet route to pull the firmware. Time-picker and OSC PIN-pad keys no longer stay visually stuck in the pressed state. Note: don’t make a tagged cue the last cue — the trigger fires when the playhead advances past the tagged cue to the next one, so there must be a next cue; keep at least one trailing cue (a blackout, memo, or “END” marker) after it. - OSC Access page + workspace picker redesign (0.9.3) — Settings → OSC Access replaces the old Workspace IP row and moves VIEW / CTRL out of the settings sub-header into its own dedicated page. The OSC Access page adds on-device numeric passcode entry for both QLab and Go Button — no more compile-time constant. Workspace picker now stays open after a tap or lock instead of jumping to the live view; locked rows pin to the top in blue with a LOCKED badge; a ghost row keeps the locked entry visible when the host is offline. Manual IP entry moved into the picker empty state as an “Enter IP Manually” escape hatch.
- VIEW / CTRL + workspace picker (0.9.2) — VIEW / CTRL segmented control added to Settings sub-header. Go Button show timer, workspace picker initial implementation, chevron cue navigation.
- Go Button connectivity fixes (0.9.1) — Two bugs fixed: (1) iPhones and iPads running Go Button couldn’t connect to the buddy’s hotspot. Root cause: in WIFI_AP_STA mode the AP auto-syncs its channel to the router channel; if the router uses 40 MHz (HT40), the AP beacons at 40 MHz too — iOS 14+ associates then immediately drops. Fixed by forcing the AP interface to HT20 (20 MHz) after softAP starts. Macs and Card Fountain props are unaffected. (2) When Go Button disconnected with QLab open but no file loaded, the buddy would auto-connect to QLab, immediately get a “no file” thump, disconnect, and repeat every 4 s — producing a visible QLAB↔WiFi status flicker. Fixed by arming the closed-file guard defensively in
gbGoIdle(). A genuine QLab file open still disarms the guard within one poll cycle via the existing fast-path. - UI polish + bug fixes (0.8.33) — IP Pool arrows register correctly. OTA dot + version centered on splash. Connection dot restored to all views. OTA dot colors: grey = up to date, green = update available, red = update available but no WiFi.
- IP Pool, status indicators, WiFi (0.8.32) — IP Pool selector (AUTO or four isolated 40-address slices). OTA update dot on splash persisted in NVS. Pairing label replaces HOTSPOT when pairing is active. Hotspot toggle shows “OFF — hold to enable.” WiFi auto-connects after save. WiFi indicator stuck-white fix.
- Device flicker fix + API URL pre-fill (0.8.31) — stale timeout restored to 6 s (main WiFi) / 8 s (hotspot). WIKITEST and BRIDGE URL keyboards pre-fill the constant prefix.
- Single-tap navigation + faster device presence (0.8.29) — Fixed double-tap regression. Prop
/helloreduced to 400 ms; buddy probe at 1.2 s of silence; stale/offline threshold 3.5 s. - OSC commands, IP stability, keyboard (0.8.28) — Props respond to
/start,/reverse,/stop, and/test. Connect time ~1 s; disconnect ~4 s. Same prop always gets same static IP on re-pair. Pool raised to 32 devices (160 addresses). - Ghost arrow fix on USB power banks (0.8.24) — Touch threshold dichotomy: real-host (0x55) vs floating-power (0x70). Detector is
usbNcmIsConnected() && usbNcmLeaseGiven()so power banks, wall chargers, and OSes without USB-NCM always get the ghost-resistant threshold. - QLab host lock (0.8.22) — Once the buddy talks to a QLab, that’s THE QLab for the session. Survives heartbeat blips, foreign-Mac overtakes, file switches, 5-min socket stalls, DHCP renumbering, and WiFi flaps.
- Wireless OTA end-to-end — SHA-256 verify + 60 s health-gate rollback. Direct Connect IP, press-and-hold prev/next, 5 s connection recovery.
What’s next
Multi-performer / multi-tenancy
- Team key — short shared secret so multiple performers on one venue WiFi don’t cross-adopt props or API URLs.
- Per-buddy hotspot SSID — suffix with MAC so two buddies in the same room don’t both broadcast plain “QLAB Buddy.”
Pairing & IP coordination
- ARP pre-check — ping a candidate IP before handing it to a prop to avoid collisions with non-paired LAN devices.
- Multi-prop pairing — pool DHCP so more than one prop can pair in a single SYNC window.
Integration & polish
- Custom theme — built-in presets (Classic Amber, High-Contrast, Cool Blue…).
- Larger paired-device list — raise MAX_FOUND / MAX_KNOWN for venues running 8+ props.
Known limitations
- One prop pairs at a time — the buddy’s hotspot has a single DHCP slot. Pair them one-by-one.
- USB-only buddy can’t reach WiFi-side props — enter WiFi creds on the buddy so it can see the prop’s static IP.
- Static-IP pool can collide with non-paired LAN devices — reserve .50–.209 on your router, or move DHCP to .210+.
- Two buddies in the same room both broadcast “QLAB Buddy” — pair one at a time, or keep the other’s hotspot off.
- Go Button mode: GO / PANIC / STOP unavailable — cue advancement is controlled by Go Button on the iOS device.
- Go Button: don’t tag the last cue — the trigger fires when the playhead advances to the next cue, so a device tag on the final cue fires nothing. Keep a trailing cue (a blackout, memo, or “END” marker) after it. See Device Triggering from Go Button.
- Environmental (out of scope): router AP-isolation, captive portals, 5 GHz-only WiFi, mesh band-steering.