DIY Video-conferencing MacroBoard
by hansamann in Living > Office Supply Hacks
1742 Views, 18 Favorites, 0 Comments
DIY Video-conferencing MacroBoard
This project is about a DIY MacroBoard / MacroPad that I built to have fun with all these video conferences via Zoom, Slack or Teams. To keep things simple and because I did not want to wait for a shipment from China, I decided to use a Adafruit Circuit Playground Express, which you should be able to get in a few days almost everywhere.
You don't necessarily need to 3D print and lasercut for this project - just be creative. For example, the pins of the Circuit Playground Express are capacitive, they react to touches. You could easily extend them with some wire and aluminium foil, add some printed icon for sound/video etc on top and stick these flat, capacitive buttons to your table insteadd of lasercutting and 3d printing. Let me know what you make!
Let me also give credit to the blog post by Andy that inspired me to create a macroboard. The code I used is very similar, I just made a few changes here and there and my main goal was to make this useful for video-conferences. My main video-conferencing tool these days is Zoom, so support is best here. For Slack and Teams support is just minimal, but of course I'd love to see how you extend my project!
Supplies
- Adafruit Circuit Playground Express or similar CircuitPython board
- Arcade Buttons like these
- Some wire, soldering iron solder...
Lasercutting and 3D Printing
I started by creating the lasercut front plate of the MacroBoard. The holes snuggly fit the arcade push buttons, but they are also not too close together as the 1.5mm Kraftplex wood would break. If you have access to a lasercutter such as Mr Beam, I highly recommend Kraftplex for the material. It is strong and holds the buttons well while also being a bit flexible and easy to spray/color later on.
The SVG files include the front and bottom plate to lasercut. I decided to ground the front plate and sprayed some yellow acrylic color on it, but that's totally up to you of course.
To hold the front and bottom plate in place, I designed some 3d printable stand via OpenSCAD. The stand_side.stl file needs to be mirrored in your slicer such as PrusaSlicer to print the second part.
All the parts are simply glued together which results in a very robust board.
To add some icons to my buttons, I first vectorized some nice icons and then made sure they can be lasercut well - e.g. no completely cutout elements as they don't hold in place. I then lasercut the icons with circles around them and positioned them onto the buttons. Via a somple marker, I then added the icons to the buttons - not always worked perfectly, but way better than me scribbling...
Finally, add all the buttons to the board. Make sure the connectors align nicely on the back.
Wiring
When it comes to wiring, first connect one pin of each button for a common ground wire. The input pins for the Circuit Playground Express will later be bulled high, so 1 / ON will be the normal state when the buttons are not pressed. The buttons go low when you press them, as they then connect to ground.
Next, connect the other pins of the buttons to the pins of the Circuit Playground Express. The pinout is here and you can also see that you have only 8 pins for general purpose in/out - this is also the reason why I limited the board to 8 buttons. Of course you can create a button matrix or use a board with more pins, but for this little DIY project that was all too complex and time consuming for me. So one button = one pin on the Circuit Playground Express. Easy.
Beer and Software
Next, it is recommended to celebrate your physical creation and have a beer. If you are under 16, it might be more appropriate to get a low-sugar lemonade instead, please consult your parents.
You will first need to update the Circuit Playground Express to the latest version and then copy the adafruit_hid (Human Interfacer Device) library to the board. I suggest you familiarize youself a bit with the board, then continue with adding the lib and also the code below. All coding was done in the excellent mu:editor, which detects the board automatically.
Below is the full code and it can probably be optimized in many many ways - again I'd love to hear how you optimize it and what else you add.
The two A/B Button on the Playground Express itself are used to toggle between the mode - Zoom/Slack/Teams for now/. If you press a button in Slack mode and it has not been implemented, e.g. the codes Array/Dict has no KeyCodes for this button, then it will quickly flash the NeoPixel LEDs of the board. Otherwise it simply sends the KeyCodes. You need to make sure that controls in Zoom are always visible (search Zoom In-Meeting Controls), the shortcut to toggle this once should be CTRL-\ on Mac. Also, as we're sending simple keystrokes, make sure the Zoom/Slack/Teams window is active and focused.
Have fun!
import time import board from digitalio import DigitalInOut, Direction, Pull from adafruit_hid.keyboard import Keyboard from adafruit_hid.keycode import Keycode from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS import usb_hid from adafruit_circuitplayground import cp cp.pixels.brightness = 0.1 # configure device as keyboard kbd = Keyboard(usb_hid.devices) layout = KeyboardLayoutUS(kbd) modes = ["zoom", "slack", "teams"] mode = 0 # zoom desc = { "d3": "audio", "d2": "video", "d0": "share", "d1": "raise hand", "d6": "fullscreen", "d12": "gallery", "d10": "chat", "d9": "participants", } codes = [ { "d3": [Keycode.COMMAND, Keycode.SHIFT, Keycode.A], "d2": [Keycode.COMMAND, Keycode.SHIFT, Keycode.V], "d0": [Keycode.COMMAND, Keycode.SHIFT, Keycode.S], "d1": [Keycode.OPTION, Keycode.Y], "d6": [Keycode.COMMAND, Keycode.SHIFT, Keycode.F], "d12": [Keycode.COMMAND, Keycode.SHIFT, Keycode.W], "d10": [Keycode.COMMAND, Keycode.SHIFT, Keycode.H], "d9": [Keycode.COMMAND, Keycode.U], }, {"d3": [Keycode.M], "d2": [Keycode.V], "d9": [Keycode.A]}, { "d3": [Keycode.COMMAND, Keycode.SHIFT, Keycode.M], "d0": [Keycode.COMMAND, Keycode.SHIFT, Keycode.SPACE], "d2": [Keycode.COMMAND, Keycode.SHIFT, Keycode.O], "d6": [Keycode.COMMAND, Keycode.SHIFT, Keycode.F], }, ] colors = [[0, 0, 255], [255, 0, 150], [100, 50, 255]] # little function to open apps via spotlight def open_app(app): kbd.send(Keycode.COMMAND, Keycode.SPACE) time.sleep(0.2) layout.write(app) time.sleep(0.2) kbd.send(Keycode.ENTER) def send(btn): if codes[mode] and btn in codes[mode]: kbd.send(*codes[mode][btn]) print(modes[mode], desc[btn]) else: print("Not implemented!") blink() time.sleep(0.5) def blink(): for i in range(4): cp.pixels.fill(colors[mode]) time.sleep(0.2) cp.pixels.fill([0, 0, 0]) time.sleep(0.1) d0 = DigitalInOut(board.D0) d0.direction = Direction.INPUT d0.pull = Pull.UP d1 = DigitalInOut(board.D1) d1.direction = Direction.INPUT d1.pull = Pull.UP d3 = DigitalInOut(board.D3) d3.direction = Direction.INPUT d3.pull = Pull.UP d2 = DigitalInOut(board.D2) d2.direction = Direction.INPUT d2.pull = Pull.UP d6 = DigitalInOut(board.D6) d6.direction = Direction.INPUT d6.pull = Pull.UP d12 = DigitalInOut(board.D12) d12.direction = Direction.INPUT d12.pull = Pull.UP d10 = DigitalInOut(board.D10) d10.direction = Direction.INPUT d10.pull = Pull.UP d9 = DigitalInOut(board.D9) d9.direction = Direction.INPUT d9.pull = Pull.UP # loop forever while True: cp.pixels.fill(colors[mode]) if cp.button_a: print("Button A pressed!") mode += 1 if mode > 2: mode = 0 print("mode is", modes[mode]) time.sleep(0.5) if cp.button_b: print("Button B pressed!") mode -= 1 if mode < 0: mode = 2 print("mode is", modes[mode]) time.sleep(0.5) if not d3.value: send("d3") if not d2.value: send("d2") if not d0.value: send("d0") if not d1.value: send("d1") if not d6.value: send("d6") if not d12.value: send("d12") if not d10.value: send("d10") if not d9.value: send("d9")