Code: Select all
# cardkb_hid.py
#
# (Released under MIT License)
# Allows you to use a CircuitPython board to make the CardKB keyboard from M5Stack
# behave like a regular USB keyboard. This CircuitPython app was originally designed
# to work on an Trinket M0. The default i2c pins are used and are marked on the
# board as SDA and SCL.
#
# Version 1.0 - Initial Release
import time
import board
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
keymap = {
'31': (Keycode.ONE, 0),
'32': (Keycode.TWO, 0),
'33': (Keycode.THREE, 0),
'34': (Keycode.FOUR, 0),
'35': (Keycode.FIVE, 0),
'36': (Keycode.SIX, 0),
'37': (Keycode.SEVEN, 0),
'38': (Keycode.EIGHT, 0),
'39': (Keycode.NINE, 0),
'30': (Keycode.ZERO, 0),
'71': (Keycode.Q, 0),
'77': (Keycode.W, 0),
'65': (Keycode.E, 0),
'72': (Keycode.R, 0),
'74': (Keycode.T, 0),
'79': (Keycode.Y, 0),
'75': (Keycode.U, 0),
'69': (Keycode.I, 0),
'6f': (Keycode.O, 0),
'70': (Keycode.P, 0),
'61': (Keycode.A, 0),
'73': (Keycode.S, 0),
'64': (Keycode.D, 0),
'66': (Keycode.F, 0),
'67': (Keycode.G, 0),
'68': (Keycode.H, 0),
'6a': (Keycode.J, 0),
'6b': (Keycode.K, 0),
'6c': (Keycode.L, 0),
'08': (Keycode.BACKSPACE, 0),
'b5': (Keycode.UP_ARROW, 0),
'b6': (Keycode.DOWN_ARROW, 0),
'b4': (Keycode.LEFT_ARROW, 0),
'b7': (Keycode.RIGHT_ARROW, 0),
'09': (Keycode.TAB, 0),
'0d': (Keycode.ENTER, 0),
'20': (Keycode.SPACEBAR, 0),
'7a': (Keycode.Z, 0),
'78': (Keycode.X, 0),
'63': (Keycode.C, 0),
'76': (Keycode.V, 0),
'62': (Keycode.B, 0),
'6e': (Keycode.N, 0),
'6d': (Keycode.M, 0),
'21': (Keycode.ONE, 1),
'40': (Keycode.TWO, 1),
'23': (Keycode.THREE, 1),
'24': (Keycode.FOUR, 1),
'25': (Keycode.FIVE, 1),
'5e': (Keycode.SIX, 1),
'26': (Keycode.SEVEN, 1),
'2a': (Keycode.EIGHT, 1),
'28': (Keycode.NINE, 1),
'29': (Keycode.ZERO, 1),
'2b': (Keycode.KEYPAD_PLUS, 0),
'3a': (Keycode.SEMICOLON, 1),
'2c': (Keycode.COMMA, 0),
'7f': (Keycode.DELETE, 1),
'5b': (Keycode.LEFT_BRACKET, 0),
'5d': (Keycode.RIGHT_BRACKET, 0),
'2f': (Keycode.FORWARD_SLASH, 0),
'5c': (Keycode.BACKSLASH, 0),
'27': (Keycode.QUOTE, 0),
'7b': (Keycode.LEFT_BRACKET, 1),
'7d': (Keycode.RIGHT_BRACKET, 1),
'5f': (Keycode.MINUS, 0),
'3b': (Keycode.SEMICOLON, 0),
'2e': (Keycode.PERIOD, 0),
'51': (Keycode.Q, 1),
'57': (Keycode.W, 1),
'45': (Keycode.E, 1),
'52': (Keycode.R, 1),
'54': (Keycode.T, 1),
'59': (Keycode.Y, 1),
'55': (Keycode.U, 1),
'49': (Keycode.I, 1),
'4f': (Keycode.O, 1),
'50': (Keycode.P, 1),
'41': (Keycode.A, 1),
'53': (Keycode.S, 1),
'44': (Keycode.D, 1),
'46': (Keycode.F, 1),
'47': (Keycode.G, 1),
'48': (Keycode.H, 1),
'4a': (Keycode.J, 1),
'4b': (Keycode.K, 1),
'4c': (Keycode.L, 1),
'5a': (Keycode.Z, 1),
'58': (Keycode.X, 1),
'43': (Keycode.C, 1),
'56': (Keycode.V, 1),
'42': (Keycode.B, 1),
'4e': (Keycode.N, 1),
'4d': (Keycode.M, 1)
}
# Simple one character buffer
buffer = bytearray(1)
# Initialize the virtual USB keyboard
kbd = Keyboard(usb_hid.devices)
# Use the default i2c pins for the board to talk to the keyboard
i2c = board.I2C()
# Attempt a lock on the bus to talk to the keyboard
while not i2c.try_lock():
pass
# Now do what keyboards do...
while True:
try:
# Get the next key on the keyboard
i2c.readfrom_into(95, buffer)
# If it's anything other than a NUL send it along as a keypress
if buffer != bytearray(b'\x00'):
# Convert char to a hex value formatted as a string
key = '{:02x}'.format(buffer[0])
# Use the key to retrieve the keys attributes
key_info = keymap[key]
if key_info != None:
if (key_info[1] & 1):
kbd.send(Keycode.SHIFT, key_info[0])
elif (key_info[1] & 2):
kbd.send(Keycode.CONTROL, key_info[0])
elif (key_info[1] & 4):
kbd.send(Keycode.FUNCTION, key_info[0])
else:
kbd.send(key_info[0])
# Pause a bit
time.sleep(0.1)
except:
pass
# Done with talking to the keyboard
i2c.unlock()