The Adafruit CircuitPython HID library makes it simple to use CircuitPython to make your NeoKey Trinkey into a tiny macropad. This means you can use your NeoKey Trinkey to send a single key press, combination of key presses, or strings to your computer when you press the key!

CircuitPython's touchio module makes it easy to use the capacitive touch pad on the NeoKey Trinkey. You can use it to treat the touch pad as an input, which allows you to do all kinds of fun things with it!

All the necessary modules and libraries for this example are included with CircuitPython for the NeoKey Trinkey, so you do not need to load any separate files onto your board.

You'll want to connect to the serial console.

Save the following as code.py on your CIRCUITPY drive.

You can download the Project Bundle, but you only need to copy code.py to your NeoKey Trinkey. All the necessary libraries are included in CircuitPython for the NeoKey Trinkey!
"""NeoKey Trinkey Capacitive Touch and HID Keyboard example"""
import time
import board
import neopixel
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode  # pylint: disable=unused-import
from digitalio import DigitalInOut, Pull
import touchio

print("NeoKey Trinkey HID")

# create the pixel and turn it off
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.1)
pixel.fill(0x0)

time.sleep(1)  # Sleep for a bit to avoid a race condition on some systems
keyboard = Keyboard(usb_hid.devices)
keyboard_layout = KeyboardLayoutUS(keyboard)  # We're in the US :)

# create the switch, add a pullup, start it with not being pressed
button = DigitalInOut(board.SWITCH)
button.switch_to_input(pull=Pull.DOWN)
button_state = False

# create the captouch element and start it with not touched
touch = touchio.TouchIn(board.TOUCH)
touch_state = False

# print a string on keypress
key_output = "Hello World!\n"

# one character on keypress
# key_output = Keycode.A

# multiple simultaneous keypresses
# key_output = (Keycode.SHIFT, Keycode.A)  # capital A
# key_output = (Keycode.CONTROL, Keycode.ALT, Keycode.DELETE) # three finger salute!

# complex commands! we make a list of dictionary entries for each command
# each line has 'keys' which is either a single key, a list of keys, or a string
# then the 'delay' is in seconds, since we often need to give the computer a minute
# before doing something!

# this will open up a notepad in windows, and ducky the user
"""
key_output = (
   {'keys': Keycode.GUI, 'delay': 0.1},
   {'keys': "notepad\n", 'delay': 1},  # give it a moment to launch!
   {'keys': "YOU HAVE BEEN DUCKIED!", 'delay': 0.1},
   {'keys': (Keycode.ALT, Keycode.O), 'delay': 0.1}, # open format menu
   {'keys': Keycode.F, 'delay': 0.1}, # open font submenu
   {'keys': "\t\t100\n", 'delay': 0.1}, # tab over to font size, enter 100
)
"""


# our helper function will press the keys themselves
def make_keystrokes(keys, delay):
    if isinstance(keys, str):  # If it's a string...
        keyboard_layout.write(keys)  # ...Print the string
    elif isinstance(keys, int):  # If its a single key
        keyboard.press(keys)  # "Press"...
        keyboard.release_all()  # ..."Release"!
    elif isinstance(keys, (list, tuple)):  # If its multiple keys
        keyboard.press(*keys)  # "Press"...
        keyboard.release_all()  # ..."Release"!
    time.sleep(delay)


while True:
    if button.value and not button_state:
        pixel.fill((255, 0, 255))
        print("Button pressed.")
        button_state = True

    if not button.value and button_state:
        pixel.fill(0x0)
        print("Button released.")
        if isinstance(key_output, (list, tuple)) and isinstance(key_output[0], dict):
            for k in key_output:
                make_keystrokes(k['keys'], k['delay'])
        else:
            make_keystrokes(key_output, delay=0)
        button_state = False

    if touch.value and not touch_state:
        print("Touched!")
        pixel.fill((0, 255, 0))
        touch_state = True
    if not touch.value and touch_state:
        print("Untouched!")
        pixel.fill(0x0)
        touch_state = False

Now, open a text editor of your choice. Press the key. Note that nothing happens as long as it's pressed. Now let go of it. "Hello World!" appears followed by a newline! You can check the serial console as well, while pushing and releasing the key, to see Button pressed. and Button released. printed to the console.

Check the serial console and try touching the capacitive touch pad. When you touch the pad, you'll see Touched! printed to the console. When you let go of it, you'll see Untouched! printed.

First you import all the necessary modules and libraries to make them available for use in your code. You print NeoKey Trinkey HID to the serial console.

Then you setup the NeoPixel, the keyboard, the button, and the touch pad.

Next, there are four options for the key_output. There is a default, and the rest are commented out. You can only use one option at a time. To use one of the others, comment out the first one, and uncomment a different one.

  1. The first and default option, is the string "Hello World!" with a newline at the end.
  2. The second option is to send a single character, a lowercase a.
  3. The third has two options for demonstrating multiple simultaneous key presses:
    • The first is shift+a to generate a capital A.
    • The second is control+alt+delete.
  4. The fourth is a complex command that is designed for Windows machines. It opens notepad, types out "YOU HAVE BEEN DUCKIED!" and then sets the font size to 100.

Next is a helper that function that handles the "actual" key presses. It checks to see what type of commands you're using for key_output and handles each one appropriately.

Inside the loop, you check to see if the key switch is pressed, print to the serial console, and turn the NeoPixel purple for the duration of the press. Once released, turns off the NeoPixel, prints to the serial console, and checks what type of setup you did for key_output, and then uses the helper function to execute the key presses.

Finally, it checks to see if the touch pad is touched, prints to the serial console, and turns the NeoPixel green for the duration of the touch. On release, it prints to the serial console and turns off the NeoPixel.

That's all there is to using HID and capacitive touch with the NeoKey Trinkey!

This guide was first published on May 26, 2021. It was last updated on 2021-05-27 13:09:21 -0400.

This page (HID and Cap Touch Example) was last updated on Sep 16, 2021.

Text editor powered by tinymce.