Keybow 2040 Sending Special Characters

So I know that it is ill-advised to use sleep functionality when using the Keybow 2040 but I had to build in mechanical latency to send special key presses.

By adding a human delay to the key interaction I was able to have the Keybow 2040 send characters that I could then use to map functions in games.

The delay is necessary as instantaneous sending of a shift and a numerical will only result in the numerical output.

My example simulates the human interaction of pressing shift, then the number necessary to generate a special character.

There may be an easier way to do this, but using this example you can easily bind functions in MMORPG style games to special keys correctly.

Enjoy and happy gaming. If anyone has a way to streamline this please chime in.

import time
from pmk import PMK
from pmk.platform.keybow2040 import Keybow2040 as Hardware          # for Keybow 2040
# from pmk.platform.rgbkeypadbase import RGBKeypadBase as Hardware  # for Pico RGB Keypad Base

import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode

# Set up Keybow
keybow = PMK(Hardware())
keys = keybow.keys

keyboard = Keyboard(usb_hid.devices)
layout = KeyboardLayoutUS(keyboard)

keybow.set_led(0, 0, 255, 0)
keybow.set_led(1, 255, 0, 255)
keybow.set_led(2, 0, 255, 0)
keybow.set_led(3, 255, 0, 255)
keybow.set_led(4, 255, 0, 255)
keybow.set_led(5, 0, 255, 0)
keybow.set_led(6, 255, 0, 255)
keybow.set_led(7, 0, 255, 0)
keybow.set_led(8, 0, 255, 0)
keybow.set_led(9, 255, 0, 255)
keybow.set_led(10, 0, 255, 0)
keybow.set_led(11, 255, 0, 255)
keybow.set_led(12, 255, 0, 255)
keybow.set_led(13, 0, 255, 0)
keybow.set_led(14, 255, 0, 255)
keybow.set_led(15, 0, 255, 0)

key = keys[0]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.ONE)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.ONE)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

key = keys[1]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.TWO)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.TWO)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

key = keys[2]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.THREE)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.THREE)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

key = keys[3]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.FOUR)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.FOUR)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

key = keys[4]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.FIVE)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.FIVE)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)
    
key = keys[5]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.SIX)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.SIX)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

key = keys[6]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.SEVEN)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.SEVEN)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

key = keys[7]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.EIGHT)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.EIGHT)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

key = keys[8]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.NINE)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.NINE)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

key = keys[9]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.LEFT_BRACKET)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.LEFT_BRACKET)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

key = keys[10]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.RIGHT_BRACKET)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.RIGHT_BRACKET)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

key = keys[11]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.SEMICOLON)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.SEMICOLON)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

key = keys[12]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.QUOTE)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.QUOTE)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

key = keys[13]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.COMMA)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.COMMA)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

key = keys[14]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.PERIOD)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.PERIOD)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

key = keys[15]

@keybow.on_press(key)
def press_handler(key):
    keyboard.press(Keycode.SHIFT)
    time.sleep(0.1)
    keyboard.press(Keycode.FORWARD_SLASH)
    time.sleep(0.1)

@keybow.on_release(key)
def release_handler(key):
    keyboard.release(Keycode.FORWARD_SLASH)
    time.sleep(0.1)
    keyboard.release(Keycode.SHIFT)

while True:
    # Always remember to call keybow.update() on every iteration of your loop!
    keybow.update()

1 Like

An interlude on timing (from GitHUB)
Maybe queue the input in your own array, as well as the delay amount.

event_queue = []  # A queue to hold events
time_interval = 0.1  # Set the desired time interval here
time_last_fired = time.monotonic()

@keybow.on_press(key)
def press_handler(key):
    global event_queue
    event_queue.append((time_interval, press_key, Keycode.SHIFT)) # Add SHIFT to queue
    event_queue.append((time_interval, press_key, Keycode.FORWARD_SLASH)) # Add FORWARD_SLASH to queue


while True:
    current_time = time.monotonic()
    if event_queue and (current_time - time_last_fired) >= event_queue[0][0]:
        _, function, keycode = event_queue.pop(0) # Dequeue the event
        function(keycode) # Execute the event
        time_last_fired = current_time
    keybow.update()  # call each time

Ok interesting, I will try that code out and see if it fires off correctly in game as well.
Thanks for the input!