A stream deck is a row of buttons that press keys for you. That is all it is. Once I saw it that way, the rest followed: a small touchscreen, a way to send keystrokes, and a layout that is mine.
This is how I built one for OBS Studio. It has five scene keys that light up when they are chosen, mute keys, push-to-talk, record and pause with a timer, and a GO LIVE key that will not fire if a sleeve brushes it.
I should say up front that I make LCD Wizard, the designer I built it in. This is a build log, not a review: every step below is one you can check for yourself, the finished design is public to open, and the full step-by-step tutorial is linked at the end.
The idea: it is only a keyboardThe usual way to build a stream deck is to write a program for the PC that listens to the device. I did not want a program on the PC. So the deck pairs as a Bluetooth keyboard, which every computer already understands, and it sends ordinary shortcuts that I then give to OBS in its own Settings.
The shortcuts are F13 to F24. Those are real keys, but no keyboard has them, so nothing else on the PC will ever send one and no program has claimed them. Each key on the deck takes exactly one modifier, and the rule is short enough to remember:
- Ctrl means "on"
- Alt means "off"
- Shift means a single press
One board: an LCDWIKI 3.5-inch ESP32-S3 (the ES3C35P), a 320 x 480 touchscreen with the processor on the back and a USB-C socket. I turned it on its side, so the deck is 480 x 320. There is nothing to solder and nothing to wire.
Starting the projectThe designer asks four things before it opens: what the project is for (Arduino), which board, which way up the panel is, and which version of the graphics library. Choosing the board fills in every pin, so that was the whole of the hardware setup.
Then one tab makes the board a Bluetooth keyboard: tick a box, pick "A keyboard (HID)", and give it the name the PC will see.
I made one key completely before making any others, because the other fourteen are copies of it.
A key is a button with an icon above its caption. I styled it four times, once for each state it can be in: resting, pressed, lit, and greyed out. The backdrop behind the keys is a single picture, with a dark well for each key and a strip of coloured light under it. The keys themselves are ordinary buttons sitting in the wells, so every colour and caption is a setting, not something I would have to redraw.
What it does is one event: when it is clicked, send Ctrl + F13.
The designer has a preview that behaves like the panel, so I could press the key in the browser and read what the board would have sent, before there was any firmware at all.
A scene key should light when I choose it and go out when I choose another. If each key lit itself, I would end up with five lit keys.
So the keys do not light themselves. A variable called scene remembers which one was chosen. Each key sets it to its own number when clicked, and each key is lit while the variable holds that number. That last part is one line: a binding that says "Checked follows scene == 1".
With that done, I duplicated the key four times and changed four things on each copy: its caption, its icon, its shortcut, and its number.
This is the decision I would make the same way again.
A keyboard only talks one way. The deck cannot ask OBS whether the microphone is muted. If MUTE sent one shortcut that toggles, then a single click of the mouse in OBS would leave the two disagreeing for the rest of the evening: the key lit, the microphone live.
So a key that stays on sends Ctrl + F18 when it turns on and Alt + F18 when it turns off, and OBS gets two hotkeys, Mute and Unmute. The lit key then means "the last thing I sent was Mute", and the next press always sends Unmute. If they ever disagree, one press puts it right.
Push-to-talk is the same idea with different triggers. The shortcut is held down when the finger lands and let go when it lifts.
Going live is the one key that costs something if it is pressed by accident. Mine takes a long press, both to start and to stop.
That made it the odd one out. A button that toggles does so on any release, so GO LIVE is not that kind of button. A long press flips a variable called live, the key is lit while live is on, and two small automations send the shortcuts when the variable changes: Ctrl + F24 when it becomes 1, Alt + F24 when it becomes 0.
The bar across the top shows how long I have been recording and how long I have been live. Each is a timer widget with two settings that matter: run while rec is on, and hold still while paused is on. There is nothing else behind it. It keeps time by the board's own clock, so three hours of stream read as three hours.
Behind each timer is a second label that says 888:88 in a faint colour. Those are the unlit segments of a real display, and they are what makes the numbers look like an instrument and not like text.
One more thing turned out to matter more than I expected. If the PC is asleep or the Bluetooth link has dropped, a key that still lights up is lying to me. So every key is disabled while no host is connected. That is a second variable, read from Bluetooth, and one more binding on the first key before I copied it.
I ran the whole deck in the preview before any of it touched hardware: chose a scene, started a recording, paused it, stopped it and watched PAUSE put itself out, then held GO LIVE.
The designer generated the project: 31 files, including the screen as C, the sketch, the Bluetooth module, the fonts and the backdrop. I did not edit any of them.
Building it with PlatformIO is one command in the unzipped folder:
pio run -t uploadThe firmware came to 1.32 MB. The board started with its keys greyed and NO HOST in the bar. I added a Bluetooth device on the PC, picked "OBS Deck", and the bar changed to LINKED.
Telling OBS which key is whichThis was the part I had expected to be tedious. It is not, because OBS listens for the key: under Settings > Hotkeys I clicked the box beside an action and tapped its key on the deck, and OBS wrote the shortcut in for me. For a key with two shortcuts, the second tap sends the second one.
The whole list:
- INTRO, CAMERA, SCREEN, BRB, OUTRO send Ctrl + F13 to F17. In OBS: Switch to scene, on each of five scenes.
- MUTE MIC sends Ctrl + F18 for on and Alt + F18 for off. In OBS: Mic/Aux, Mute and Unmute.
- TALK sends Shift + F18, held. In OBS: Mic/Aux, Push-to-talk.
- MUTE PC sends Ctrl + F19 and Alt + F19. In OBS: Desktop Audio, Mute and Unmute.
- HIDE CAM sends Ctrl + F20 and Alt + F20. In OBS: Hide and Show, on the camera source.
- SNAP sends Shift + F21. In OBS: Screenshot Output.
- REC sends Ctrl + F23 and Alt + F23. In OBS: Start Recording and Stop Recording.
- PAUSE sends Ctrl + F22 and Alt + F22. In OBS: Pause Recording and Unpause Recording.
- REPLAY sends Shift + F22. In OBS: Save Replay.
- V-CAM sends Ctrl + F21 and Alt + F21. In OBS: Start and Stop Virtual Camera.
- GO LIVE sends Ctrl + F24 to start and Alt + F24 to stop, on a hold. In OBS: Start Streaming and Stop Streaming.
- Decide the shortcut scheme first. One modifier for on, one for off, one for a single press, and never two at once. Some programs match loosely and will take Ctrl + Shift + F23 for Ctrl + F23.
- Start and Stop are two hotkeys. It is the difference between a deck you trust and one you keep glancing at OBS to check.
- Make one key completely, then copy it. Its look, its event, when it lights and when it greys out. Everything you get right on the first key you get right fourteen more times for free.
- Guard the key that matters. A long press costs a second and saves an accidental stream.
- It is not only for OBS. It is a keyboard. The same fifteen keys will run a video mixer, mute a call or fire editor macros. Only the list you give the program changes.
- The step-by-step tutorial, fifty steps with a picture of each: https://lcdwizard.com/docs/tutorial-obs-stream-deck
- The finished design, to open, press Play on and take apart: https://lcdwizard.com/p/obs-deck
- The board: https://lcdwizard.com/boards/lcdwiki-es3c35p
Designing the deck and trying it in the preview are free and need no account. Generating the code for this design is part of LCD Wizard's paid tier, because it uses two of its paid parts, the Bluetooth keyboard and the timer widget. I would rather say that here than have you find it at the last step.
If you build one, I would like to see it.




Comments