Setup Adafruit Feather M0 Express for CircuitPython
We'll need to get our Feather board setup so we can run CircuitPython code. First thing we'll need to do is connect the board to your computer with a microUSB cable. Then double-click on the reset button to put it in "UF2" boot-loader mode. The NeoPixel will turn green. The board will then show up as a USB storage device on your computer named "FEATHERBOOT".
Install CircuitPython UF2
After you've dragged the UF2 onto the FEATHERBOOT drive, wait for a few moments, and a CIRCUITPY drive will appear letting you know that circuit python has been loaded correctly. You may need to unplug-replug the Feather to reset it.
Download Adafruit CircuitPython HID Library
Now we need to get the HID library from github. This allows us to have the Feather act like a keyboard
Visit our library installation page to learn how to download and install the latest driver bundle!
You can install the whole bundle if you have an Express board, or just the adafruit_hid folder. If you're just installing the individual driver, stick the adafruit_hid folder into the CIRCUITPY/lib folder or just into CIRCUITPY
Upload The Code
Copy and paste the code below into a new text document (we recommend using Mu as your editor, which is designed for CircuitPython.). Save the file and name it as main.py
Once the files has been uploaded to the drive, the Feather will automatically reboot and run the code. No upload button (say whaaat?!).
Text Document Formatting
We recommend using Mu as your editor, which is designed for CircuitPython.
If you're using something else, watch out for formatting! When making your text document, you need to ensure the file is set as Plain Text. Most common text editing applications, like TextEdit for MacOS will save text documents as .RTF (rich text format) by default. You can quickly change an RTF text document to plain text by using selecting "Make Plain Text" under the Format menu. You can also change the format in the applications "Preferences" menu.
Line Spaces and Invisible Characters
If you are still finding your code isn't quite working and running. You can try copying the code into a different code or text editing software, save it out as a .txt format with line spacing and then convert it to the .py file extension. Sometimes text editors will add invisible characters like line breaks and tabbed spaces.
# SPDX-FileCopyrightText: 2017 Limor Fried for Adafruit Industries # # SPDX-License-Identifier: MIT import time import digitalio from adafruit_hid.keyboard import Keyboard from adafruit_hid.keycode import Keycode import board import usb_hid # A simple neat keyboard demo in circuitpython # The button pins we'll use, each will have an internal pullup buttonpins = [board.D12, board.D11, board.D10, board.D9, board.D6, board.D5] ledpins = [board.A0, board.A1, board.A2, board.A3, board.A4, board.A5] # The keycode sent for each button, will be paired with a control key buttonkeys = [Keycode.A, Keycode.B, Keycode.C, Keycode.D, Keycode.E, Keycode.F] controlkey = Keycode.LEFT_CONTROL # the keyboard object! kbd = Keyboard(usb_hid.devices) # our array of button objects buttons = [] leds = [] # make all pin objects, make them inputs w/pullups for pin in buttonpins: button = digitalio.DigitalInOut(pin) button.direction = digitalio.Direction.INPUT button.pull = digitalio.Pull.UP buttons.append(button) for pin in ledpins: led = digitalio.DigitalInOut(pin) led.direction = digitalio.Direction.OUTPUT leds.append(led) led = digitalio.DigitalInOut(board.D13) led.switch_to_output() print("Waiting for button presses") while True: # check each button for button in buttons: if not button.value: # pressed? i = buttons.index(button) leds[i].value = True print("Button #%d Pressed" % i) # turn on the LED led.value = True while not button.value: pass # wait for it to be released! # type the keycode! k = buttonkeys[i] # get the corresp. keycode kbd.press(controlkey, k) kbd.release_all() # turn off the LED led.value = False leds[i].value = False time.sleep(0.01)
Modify the Code
Now that the code lives on the Adafruit Feather board, it's super easy to change or update it. We can change the number of pins, their wiring, and what key-codes they send.
Open up the main.py file in your favorite text editor and take a look at the code.
If you want to change the pins for the buttons, look for the buttonpins
list variable:
# The button pins we'll use, each will have an internal pullup
buttonpins = [D12, D11, D10, D9, D6, D5]
The "ledpins" variable lists which analog pins we're using, they correspond with the button pins one-to-one
ledpins = [A0, A1, A2, A3, A4, A5]
So here, the first pin name is the LED connected to pin A0, which matches up with the first button input pin D12. They match up A1+D11, A2+D10, A3+D9, A4+D6, and A5+D5. To change the connections, simply change the pin names in the list and save
Changing Key Presses
The buttonkeys
and controlkey
variables list which characters we want the buttons to output.
# The keycode sent for each button, will be paired with a control key
buttonkeys = [Keycode.A, Keycode.B, Keycode.C, Keycode.D, Keycode.E, Keycode.F]
For example, when the D12 button is pressed, it will emit a Keycode.A
. and when D11's button is pressed, you'll see a Keycode.B
. You can pick a wide variety of keycodes, see the full list here.
Note that keycodes aren't the same as ASCII codes. So for example if you want to send a upper case A you need to send both a control key that is 'shift' and then the keycode Keycode.A
. Together, they will make your computer recognize it's an A you want. You can set the control keycode that goes with each key on the next line:
controlkey = Keycode.LEFT_CONTROL
In this case, we want to send a Left "Control" keypress at the same time. Try changing this to
controlkey = Keycode.SHIFT
and save main.py to see how it now sends uppercase letters.
If you want to get really creative with what keypresses to send, see this line:
kbd.press(controlkey, k)
You can have up to 6 keycodes sent at once - so if you need control-shift-A, turn it into:
kbd.press(Keycode.SHIFT,Keycode.LEFT_CONTROL, k)
Coding Video
You have the option to add up to 6 buttons. You can watch Limor walkthrough the development of the software and explain how everything works. The CircuitPython HID Keyboard library is by Dan Halbert and Scott Shawcroft.
Prototyping Circuit
Once the code has been uploaded to the board, you can quickly test to ensure everything is working as expected. Using a jumper cable, you can testing the keystrokes by tying D12-D5 and ground together. You should see key presses happen on your computer with accompanying red LED on the feather board.
Page last edited January 22, 2025
Text editor powered by tinymce.