Skip to content

Instantly share code, notes, and snippets.

@bmander
Last active November 21, 2023 18:34
Show Gist options
  • Save bmander/cd2a5135011048fd1858cac180b636b2 to your computer and use it in GitHub Desktop.
Save bmander/cd2a5135011048fd1858cac180b636b2 to your computer and use it in GitHub Desktop.
CircuitPython code for volume knob
import board
from digitalio import DigitalInOut, Direction, Pull
from adafruit_hid.consumer_control import ConsumerControl
from adafruit_hid.consumer_control_code import ConsumerControlCode
import time
import usb_hid
class Button:
"""Debounced button handler. The user can assign a callback function
to be called when the button is pressed and/or released."""
def __init__(self, pin, on_press, on_release=None, debounce_time=0.01, normally=True):
self.pin = DigitalInOut(pin)
self.pin.direction = Direction.INPUT
self.pin.pull = Pull.UP
self.on_press = on_press
self.on_release = on_release
self.debounce_time = debounce_time
self.normally = normally
self.last_time = time.monotonic()
self.state = normally
def update(self):
if self.pin.value != self.state:
current_time = time.monotonic()
if current_time - self.last_time >= self.debounce_time:
self.state = self.pin.value
self.last_time = current_time
if (self.state != self.normally) and self.on_press:
self.on_press()
elif (self.state == self.normally) and self.on_release:
self.on_release()
class RotaryEncoder:
def __init__(self, clk_pin, dr_pin, on_cw, on_ccw):
self.clk_pin = DigitalInOut(clk_pin)
self.clk_pin.direction = Direction.INPUT
self.clk_pin.pull = Pull.UP
self.dr_pin = DigitalInOut(dr_pin)
self.dr_pin.direction = Direction.INPUT
self.dr_pin.pull = Pull.UP
self.on_cw = on_cw
self.on_ccw = on_ccw
self.turning = False
def update(self):
if not self.turning:
# if one of the rotary pins is high, we're turning
if not self.clk_pin.value and self.dr_pin.value:
self.on_cw()
self.turning = True
elif not self.dr_pin.value and self.clk_pin.value:
self.on_ccw()
self.turning = True
else:
if self.clk_pin.value and self.dr_pin.value:
self.turning = False
cc = ConsumerControl(usb_hid.devices)
def mute():
cc.press(ConsumerControlCode.MUTE)
cc.release()
muteButton = Button(board.D2, mute)
def volume_up():
cc.press(ConsumerControlCode.VOLUME_INCREMENT)
cc.release()
def volume_down():
cc.press(ConsumerControlCode.VOLUME_DECREMENT)
cc.release()
volumeKnob = RotaryEncoder(board.D0, board.D1, volume_up, volume_down)
######################### MAIN LOOP ##############################
while True:
volumeKnob.update()
muteButton.update()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment