This project doesn't require much (any) knowledge of CircuitPython to get up and running, but if you're new to it, and would like to know more, there is a full getting started guide here. There's also a great introduction to the PyRuler here.
If you'd like to edit the code, Adafruit suggests using the Mu editor to edit your code and have an interactive REPL in CircuitPython. You can learn about Mu and installation in this tutorial.
If you haven't already reprogrammed your PyRuler, it should come pre-programmed as a USB HID keyboard that you can try out. Plug the PyRuler into your computer USB port via an A to microB cable. A drive named CIRCUITPY should appear. Open the code.py file on that drive in Mu and change this line:ENABLE_KEYBOARD = False
to:ENABLE_KEYBOARD = True
Then when you hit one of the four buttons, it will type Ω, µ, π, or https://www.digikey.com/python (I totally just typed those on my PyRuler!)
Quick Install
Because we already have everything we need to use the PyRuler as an HID keyboard, getting up and running is very simple:
- Download the code as a code.py file
- Plug the PyRuler into the computer with a microUSB power/data cable
- Once the CIRCUITPY drive appears, just drag the code.py file you downloaded into the CIRCUITPY folder and replace the code.py file that's there
- The PyRuler should immediately reboot, and start working as a panic button for your video conferences!
# SPDX-FileCopyrightText: 2020 John Thurmond for Adafruit Industries # # SPDX-License-Identifier: MIT import os import board from digitalio import DigitalInOut, Direction import time import touchio # Set this to True to turn the touchpads into a keyboard ENABLE_KEYBOARD = True # Used if we do HID output, see below if ENABLE_KEYBOARD: from adafruit_hid.keyboard import Keyboard from adafruit_hid.keycode import Keycode from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS import usb_hid kbd = Keyboard(usb_hid.devices) layout = KeyboardLayoutUS(kbd) #print(dir(board), os.uname()) # Print a little about ourselves led = DigitalInOut(board.D13) led.direction = Direction.OUTPUT touches = [DigitalInOut(board.CAP0)] for p in (board.CAP1, board.CAP2, board.CAP3): touches.append(touchio.TouchIn(p)) leds = [] for p in (board.LED4, board.LED5, board.LED6, board.LED7): led = DigitalInOut(p) led.direction = Direction.OUTPUT led.value = True time.sleep(0.25) leds.append(led) for led in leds: led.value = False cap_touches = [False, False, False, False] def read_caps(): t0_count = 0 t0 = touches[0] t0.direction = Direction.OUTPUT t0.value = True t0.direction = Direction.INPUT # funky idea but we can 'diy' the one non-hardware captouch device by hand # by reading the drooping voltage on a tri-state pin. t0_count = t0.value + t0.value + t0.value + t0.value + t0.value + \ t0.value + t0.value + t0.value + t0.value + t0.value + \ t0.value + t0.value + t0.value + t0.value + t0.value cap_touches[0] = t0_count > 2 cap_touches[1] = touches[1].raw_value > 3000 cap_touches[2] = touches[2].raw_value > 3000 cap_touches[3] = touches[3].raw_value > 3000 return cap_touches while True: caps = read_caps() print(caps) # light up the matching LED for i,c in enumerate(caps): leds[i].value = c if caps[0]: if ENABLE_KEYBOARD: # Zoom kbd.press(Keycode.ALT, Keycode.V) kbd.release(Keycode.V) time.sleep(0.25) kbd.press(Keycode.A) kbd.release_all() if caps[1]: if ENABLE_KEYBOARD: # Teams # Note that video toggle doesn't work in the web app kbd.press(Keycode.CONTROL, Keycode.SHIFT, Keycode.M) kbd.release(Keycode.M) time.sleep(0.5) kbd.press(Keycode.O) kbd.release_all() if caps[2]: if ENABLE_KEYBOARD: # Skype kbd.press(Keycode.CONTROL, Keycode.M) kbd.release(Keycode.M) time.sleep(0.5) kbd.press(Keycode.SHIFT, Keycode.K) kbd.release_all() if caps[3]: if ENABLE_KEYBOARD: # Jitsi kbd.press(Keycode.M) kbd.release(Keycode.M) time.sleep(0.5) kbd.press(Keycode.V) kbd.release_all() time.sleep(.2)
More Details
The code is a lightly-modified version of the code that comes on the PyRuler. However, rather than typing the keys for Ω or µ, it presses the combination of hotkeys needed to toggle the camera and microphone in that specific application.
For example, the first button (the Ω) looks like this:# Zoom
kbd.press(Keycode.ALT, Keycode.V)
kbd.release(Keycode.V)
time.sleep(0.25)
kbd.press(Keycode.A)
kbd.release_all()
In Zoom, the hotkey for for starting/stopping video is Alt-V, and the hotkey for mute/unmute is Alt-A.
In the code, we're just asking it to press the Alt key, press the V key, release the V key, wait a quarter of a second, press the A key, then release all keys.
"But wait!", you ask, "You didn't hit Alt before the A!"
True, but for modifier keys like Alt, they affect all keys pressed while holding them down. They act just like the Shift key, which is just another modifier key. If you hold the Shift key down and START TYPING, all of your letters become capitals - you don't have to press Shift for each one.
The code for Teams looks slightly different: kbd.press(Keycode.CONTROL, Keycode.SHIFT, Keycode.M)
kbd.release(Keycode.M)
time.sleep(0.5)
kbd.press(Keycode.O)
kbd.release_all()
Here, we have TWO control keys, both Control and Shift before the M and O keys are pressed. (Ctrl-M is for mute/unmute, and Ctrl-O is for starting/stopping video. You can see why these are difficult to remember in all the apps!
The other thing that's different here is the time between the M and O keys being pressed is increased to half a second. While testing the program, I found that some applications didn't respond very well when the keys were pressed too quickly. Sometimes, this would result in just the microphone being muted, but the video remaining on.
Even worse, as these hotkeys are toggles (they turn things both off and on), if you'd press the button on the PyRuler again, you could unmute the microphone and turn off the video!
Real-world testing is important, and sometimes small tweaks are needed in the code!
Page last edited January 18, 2025
Text editor powered by tinymce.