{"id":15142103,"url":"https://github.com/todbot/qtpy-knob","last_synced_at":"2025-10-23T19:31:14.103Z","repository":{"id":49353517,"uuid":"341803641","full_name":"todbot/qtpy-knob","owner":"todbot","description":"QT Py Media Knob using rotary encoder \u0026 neopixel ring","archived":false,"fork":false,"pushed_at":"2023-10-15T00:10:32.000Z","size":23027,"stargazers_count":74,"open_issues_count":2,"forks_count":11,"subscribers_count":7,"default_branch":"main","last_synced_at":"2024-09-27T09:22:39.914Z","etag":null,"topics":["circuitpython","knob","mousewheel","usb","usb-hid"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/todbot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-02-24T06:35:45.000Z","updated_at":"2024-09-10T01:28:35.000Z","dependencies_parsed_at":"2023-10-15T18:47:21.875Z","dependency_job_id":null,"html_url":"https://github.com/todbot/qtpy-knob","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/todbot%2Fqtpy-knob","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/todbot%2Fqtpy-knob/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/todbot%2Fqtpy-knob/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/todbot%2Fqtpy-knob/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/todbot","download_url":"https://codeload.github.com/todbot/qtpy-knob/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219867955,"owners_count":16555810,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["circuitpython","knob","mousewheel","usb","usb-hid"],"created_at":"2024-09-26T09:22:48.749Z","updated_at":"2025-10-23T19:31:10.106Z","avatar_url":"https://github.com/todbot.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# QTPy-Knob\n\nQT Py USB Media Knob using rotary encoder \u0026amp; neopixel ring\n\n\u003cimg width=400 src=\"./docs/qtpyknob-pic1.jpg\" /\u003e\n\n\nThe QTPy-Knob features:\n- Media knob for volume up/down/mute with \"qtpy-knob.py\" CircuitPython program\n- Stylish design reminiscent of Griffin Powermate\n- Recessed USB-C connector to for safety\n- No screws needed for assembly\n- Only 3 wires needed to solder (none if you want to forgo LED lighting)\n- Reprogrammable for any USB macro key action via CircuitPython\n\nA small video about it: https://www.youtube.com/watch?v=pt7JgoSlgOg\n\nThis is an attempt to make a minimal and easy-to-build version of similar, previous projects like:\n- https://learn.adafruit.com/trinket-usb-volume-knob\n- https://learn.adafruit.com/media-dial\n\n## Components\n\nParts needed:\n\n- Adafruit QT Py (Originally for [QTPy M0](https://www.adafruit.com/product/4600) or [XIAO SAMD21](https://www.seeedstudio.com/Seeeduino-XIAO-Arduino-Microcontroller-SAMD21-Cortex-M0+-p-4426.html), but [QTPy RP2040](https://www.adafruit.com/product/4900) does work via a `fakerotaryio` hack)\n- Adafruit Neopixel Ring (https://www.adafruit.com/product/1463 or equiv)\n- Rotary encoder (PEC11-4120F-S0018 or equiv. The 3D printed case expects encoder w/ 20mm shaft \u0026 7mm threaded barrel, see [here for mods if using a 15mm encoder](https://github.com/todbot/qtpy-knob/issues/2))\n- 3D printed enclosure (see \"cad\" folder)\n\n## Software\n\nFor some of the scripts and for some QT Py variants,\nthere are [prebuilt UF2 firmware images in Releases](https://github.com/todbot/qtpy-knob/releases).\n\nOtherwise, software installation consists of:\n- Install CircuitPython on the QT Py\n- Install required CircuitPython libraries to QT Py\n- Copy qtpy_knob.py to QT Py\n\nThe CircuitPython installation step is described here: https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython\n\nThe last two steps can be accomplished with the below\n\n```\ngit clone https://github.com/todbot/qtpy-knob\ncd qtpy-knob\npip3 install circup\ncircup install -r requirements.txt\ncp qtpy_knob.py /Volumes/CIRCUITPY/code.py\n```\n\n**RP2040 NOTE:** And if you have a QTPy RP2040, be sure to copy the \"fakerotaryio.py\" file to CIRCUITPY as well.\n\n### Variations\n\nThere are a few variations of the code provided:\n- [`qtpy_knob.py`](./qtpy_knob.py)  -- volume up / down and mute\n- [`qtpy_knob_scroller.py`](./qtpy_knob_scroller.py) -- performs vertical \u0026 horizontal scrolling\n- [`qtpy_knob_midi_cc.py`](./qtpy_knob_midi_cc.py) -- sends MIDI CC instead of keyboard/mouse\n- [`qtpy_knob_simple.py`](./qtpy_knob_simple.py) -- no neopixel stuff, just encoder and USB vol up/down sending\n\n## Assembly\n\nSteps:\n\n1. Plug rotary encoder to bottom of QT Py. If your encoder has metal on the bottom,\nadd a bit of tape (Kapton, Scotch, electrical) in between the QT Py and the encoder.  If your encoder has mounting tabs, cut them off.  Solder the five pins.\n\n  \u003cimg width=325 src=\"./docs/qtpyknob-tape.jpg\"/\u003e\u003cimg width=325 src=\"./docs/qtpyknob-solder.jpg\"/\u003e\n\n\n2. Print out the enclosure on your 3d printer. Standard 0.2mm at 20% infill is fine.  The STL files are:\n\n- `qtpyknob-base.stl` -- Base that houses the QT Py \u0026 rotary encoder\n- `qtpyknob-basecap.stl` -- Cap that goes on the bottom of the base\n- `qtpyknob-knob.stl` -- Knob that you turn\n- `qtpyknob-diffuser.stl` -- Light diffuser that goes between base \u0026 knob, should be printed with translucent or clear plastic. Or you can leave it out. Or you can approxiate it with a disk cut out clear plastic like a CD case\n\nUse the rotary encoder's washer \u0026 screw to hold QTPy+encoder assembly\n\n  \u003cimg width=325 src=\"./docs/qtpyknob-case.jpg\"/\u003e\n\n\n3. Solder three wires to the Neopixel ring, insert the ring into the enclosure and solder the wires to the 3V, Gnd, and MI pins of the QT Py.  Use a bit of hot glue to secure the Neopixel ring if it doesn't snap in.\n\n  \u003cimg width=325 src=\"./docs/qtpyknob-wiring1.jpg\"/\u003e\n\n4. Snap the bottom cap on and the knob top on and you're done with physical assembly!\n\n  \u003cimg width=400 src=\"./docs/qtpyknob-pic1.jpg\" /\u003e\n\n\n### Wiring diagram\n\n\u003cimg width=500 src=\"./docs/qtpyknob-wiring-diag.jpg\" /\u003e\n\n\n### Assembly animation\n\n\u003cimg width=500 src=\"./docs/qtpyknob-cad-animation.gif\" /\u003e\n\n\n\n## Useful links\n\nResources that helped me out on this:\n\n- https://learn.adafruit.com/media-dial\n- https://learn.adafruit.com/make-it-a-keyboard/circuitpython\n- https://github.com/adafruit/Adafruit_CircuitPython_HID/tree/master/examples\n- https://circuitpython.readthedocs.io/projects/hid/en/latest/api.html#adafruit-hid-consumer-control-consumercontrol\n- https://learn.adafruit.com/trinket-usb-volume-knob\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftodbot%2Fqtpy-knob","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftodbot%2Fqtpy-knob","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftodbot%2Fqtpy-knob/lists"}