import board
from kmk.kmk_keyboard import KMKKeyboard as _KMKKeyboard
from kmk.scanners import DiodeOrientation
# print(dir(board))
class KMKKeyboard(_KMKKeyboard):
col_pins = (board.D27, board.D26, board.D22, board.D20, board.D23, board.D21)
row_pins = (board.D5, board.D6, board.D7, board.D8, board.D9)
diode_orientation = DiodeOrientation.COLUMNS
uart_pin = board.RX
rgb_pixel_pin = board.TX
data_pin = board.RX
i2c = board.I2C
SCL=board.SCL
SDA=board.SDA
coord_mapping = [
0, 1, 2, 3, 4, 5, 35, 34, 33, 32, 31, 30,
6, 7, 8, 9, 10, 11, 41, 40, 39, 38, 37, 36,
12, 13, 14, 15, 16, 17, 47, 46, 45, 44, 43, 42,
18, 19, 20, 21, 22, 23, 29, 59, 53, 52, 51, 50, 49, 48,
25, 26, 27, 28, 58, 57, 56, 55,
]
from kb import KMKKeyboard
from kmk.keys import KC
from kmk.modules.layers import Layers
from kmk.modules.modtap import ModTap
from kmk.hid import HIDModes
from kmk.handlers.sequences import send_string
import supervisor
from kmk.modules.split import Split, SplitSide, SplitType
keyboard = KMKKeyboard()
modtap = ModTap()
layers_ext = Layers()
keyboard.modules.append(layers_ext)
keyboard.modules.append(modtap)
from kmk.extensions.media_keys import MediaKeys
keyboard.extensions.append(MediaKeys())
from kmk.modules.mouse_keys import MouseKeys
keyboard.modules.append(MouseKeys())
from kmk.modules.oneshot import OneShot
oneshot = OneShot()
# optional: set a custom tap timeout in ms (default: 1000ms)
# oneshot.tap_time = 1500
keyboard.modules.append(oneshot)
# TODO Comment one of these on each side
split_side = SplitSide.LEFT
#split_side = SplitSide.RIGHT
split = Split(split_side = split_side,use_pio=True)
keyboard.modules.append(split)
# Cleaner key names
_______ = KC.TRNS
XXXXXXX = KC.NO
keyboard.debug_enabled = True
class DV:
# Build DV map for when host OS is in Dvorak mode
# https://kmkfw.zulipchat.com/user_uploads/49575/-m7O9LXFqS9ilkgMYVT5D2Iz/dvorkeys-4110265058.png
QUOT=KC.Q; COMM=KC.W; DOT=KC.E
P=KC.R; Y=KC.T; F=KC.Y; G=KC.U; C=KC.I; R=KC.O; L=KC.P
A=KC.A; O=KC.S; E=KC.D; U=KC.F; I=KC.G; D=KC.H; H=KC.J; T=KC.K; N=KC.L; S=KC.SCLN
SCLN=KC.Z; Q=KC.X; J=KC.C; K=KC.V; X=KC.B; B=KC.N; M=KC.M
W=KC.COMM; V=KC.DOT; Z=KC.SLSH
GRV=KC.GRV
LBRC=KC.MINS; RBRC=KC.EQL
LCBR=KC.UNDS; RCBR=KC.PLUS
SLSH=KC.LBRC; EQL=KC.RBRC
PLUS=KC.LSFT(KC.RBRC); MINS=KC.QUOT
COLN=KC.LSFT(KC.Z)
# class DV:
# # Build DV map for when host OS is in QWERTY mode
# QUOT=KC.QUOT; COMM=KC.COMM; DOT=KC.DOT
# P=KC.P; Y=KC.Y; F=KC.F; G=KC.G; C=KC.C; R=KC.R; L=KC.L
# A=KC.A; O=KC.O; E=KC.E; U=KC.U; I=KC.I; D=KC.D; H=KC.H; T=KC.T; N=KC.N; S=KC.S
# SCLN=KC.SCLN; Q=KC.Q; J=KC.J; K=KC.K; X=KC.X; B=KC.B; M=KC.M
# W=KC.W; V=KC.V; Z=KC.Z
# GRV=KC.GRV
# LBRC=KC.LBRC; RBRC=KC.RBRC
# LCBR=KC.LCBR; RCBR=KC.RCBR
# SLSH=KC.SLSH; EQL=KC.EQL
# PLUS=KC.PLUS; MINS=KC.MINS
# COLN=KC.COLN
class PV:
# Paraview. See Edit (menu) > Settings... > Camera > 3D Interaction Options
ROT = KC.MB_LMB; PAN = KC.MB_MMB; ZOOM = KC.MB_RMB
ROLL = KC.LSFT(KC.MB_LMB); MULTIROT = KC.LSFT(KC.MB_MMB); SKYBOXROT = KC.LCTL(KC.MB_LMB)
ZOOMMOUSE = KC.LECTL(KC.MB_RMB)
# http://kmkfw.io/docs/keycodes
keyboard.keymap = [
[ # 0: Dvorak
DV.GRV, KC.N1, KC.N2, KC.N3, KC.N4, KC.N5, KC.N6, KC.N7, KC.N8, KC.N9, KC.N0, KC.BSPACE, \
KC.TAB, DV.QUOT, DV.COMM, DV.DOT, DV.P, DV.Y, DV.F, DV.G, DV.C, DV.R, DV.L, DV.SLSH, \
KC.LCTL, DV.A, DV.O, DV.E, DV.U, DV.I, DV.D, DV.H, DV.T, DV.N, DV.S, DV.MINS, \
KC.LSFT, DV.SCLN, DV.Q, DV.J, DV.K, DV.X, KC.LT(1,_______), KC.LT(4, KC.ESC), DV.B, DV.M, DV.W, DV.V, DV.Z, XXXXXXX, \
KC.LT(4,_______), KC.LGUI, KC.LALT, KC.ENT, KC.LSFT, KC.LT(2, KC.SPACE), KC.LT(3, KC.BSPACE), KC.DEL,
],
[ # 1: Nav
KC.TO(5), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, KC.MW_UP, _______, KC.UP, _______, _______, _______, \
_______, _______, _______, _______, KC.MW_DN, KC.PGUP, KC.MW_DN, KC.LEFT, KC.DOWN, KC.RGHT, KC.MS_UP, _______, \
_______, _______, KC.PGUP, KC.PGDN, KC.MW_UP, KC.PGDN, _______, KC.TO(0), _______, _______, _______, KC.MS_LT, KC.MS_DN, KC.MS_RT, \
_______, _______, _______, _______, _______, KC.MB_MMB, KC.MB_LMB, KC.MB_RMB,
],
[ # 2: Num
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, DV.COMM, KC.LPRN, KC.RPRN, DV.SLSH, DV.PLUS, KC.N7, KC.N8, KC.N9, KC.N0, DV.PLUS, \
_______, _______, DV.DOT, DV.LBRC, DV.RBRC, KC.ASTR, DV.MINS, KC.N4, KC.N5, KC.N6, KC.N0, DV.MINS, \
DV.COLN, _______, _______, DV.LCBR, DV.RCBR, KC.BSLS, XXXXXXX, XXXXXXX, DV.EQL, KC.N1, KC.N2, KC.N3, KC.N0, DV.COLN, \
XXXXXXX, KC.SPC, KC.BSPC, KC.LALT, _______, _______, _______, XXXXXXX,
],
[ # 3: Sym
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, KC.PERC, _______, _______, KC.CIRC, _______, _______, _______, _______, \
_______, KC.EXLM, KC.AMPR, KC.AT, KC.HASH, _______, _______, KC.TILD, DV.SLSH, KC.PIPE, KC.BSLS, _______, \
_______, _______, _______, _______, KC.DLR, _______, KC.OS(KC.RALT), XXXXXXX, _______, _______, KC.BSLS, _______, _______, _______, \
XXXXXXX, _______, _______, _______, _______, _______, _______, XXXXXXX,
],
[ # 4: Fn
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, KC.VOLU, _______, _______, KC.F12, KC.F7, KC.F8, KC.F9, _______, _______, \
_______, _______, _______, KC.VOLD, _______, _______, KC.F11, KC.F4, KC.F5, KC.F6, _______, _______, \
_______, _______, _______, KC.MUTE, _______, _______,XXXXXXX, XXXXXXX, KC.F10, KC.F1, KC.F2, KC.F3, _______, _______, \
XXXXXXX, _______, _______, _______, _______, _______, _______, XXXXXXX,
],
[ # 5: Paraview
# ROT = KC.MB_LMB; PAN = KC.MB_MMB; ZOOM = KC.MB_RMB
# ROLL = KC.LSFT(KC.MB_LMB); MULTIROT = KC.LSFT(KC.MB_MMB); SKYBOXROT = KC.LCTL(KC.MB_LMB)
# ZOOMMOUSE = KC.LECTL(KC.MB_RMB)
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, PV.ZOOMMOUSE, PV.ZOOM, _______, KC.MW_UP, _______, KC.UP, _______, _______, _______, \
_______, _______, PV.SKYBOXROT, PV.PAN, PV.ROT, _______, KC.MW_DN, KC.LEFT, KC.DOWN, KC.RGHT, KC.MS_UP, _______, \
_______, _______, _______, PV.MULTIROT, PV.ROLL, _______, _______, KC.TO(0), _______, _______, _______, KC.MS_LT, KC.MS_DN, KC.MS_RT, \
_______, _______, _______, _______, _______, KC.MB_MMB, KC.MB_LMB, KC.MB_RMB,
],
# [ # n: desc
# _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
# _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
# _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
# _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
# _______, _______, _______, _______, _______, _______, _______, _______,
# ],
]
if __name__ == '__main__':
keyboard.go(hid_type=HIDModes.USB)
This PNG can be edited on https://drawio.png
# turn on debugging:
# keyboard.debug_enabled = True # in main.py
# capture everything
cat < /dev/ttyACM0 |grep pressed >> logfile
grep -Eo 'pressed={[0-9].*|key_number\ [0-9].*' ~/logfile|cut -d":" -f1|grep -o "[[:digit:]]*"|sort|uniq -c | sort -n > ~/logfile.sort
head ~/logfile.sort
5 35 12 48 14 5 14 55 21 21 28 34 34 4 36 3 37 49 40 59
import numpy as np
import pandas as pd
# coord_mapping = [
# 0, 1, 2, 3, 4, 5, 35, 34, 33, 32, 31, 30,
# 6, 7, 8, 9, 10, 11, 41, 40, 39, 38, 37, 36,
# 12, 13, 14, 15, 16, 17, 47, 46, 45, 44, 43, 42,
# 18, 19, 20, 21, 22, 23, 29, 59, 53, 52, 51, 50, 49, 48,
# 25, 26, 27, 28, 58, 57, 56, 55,
# ]
df = pd.read_csv('~/logfile.sort', sep='\s+', header=None, index_col=1)
# df.head()
left_dict = {0:(0,0),1:(0,1),2:(0,2),3:(0,3),4:(0,4),5:(0,5),
6:(1,0),7:(1,1),8:(1,2),9:(1,3),10:(1,4),11:(1,5),
12:(2,0),13:(2,1),14:(2,2),15:(2,3),16:(2,4),17:(2,5),
18:(3,0),19:(3,1),20:(3,2),21:(3,3),22:(3,4),23:(3,5),29:(3,6),
25:(4,3),26:(4,4),27:(4,5),28:(4,6)}
right_dict = {35:(0,1),34:(0,2),33:(0,3),32:(0,4),31:(0,5),30:(0,6),
41:(1,1),40:(1,2),39:(1,3),38:(1,4),37:(1,5),36:(1,6),
47:(2,1),46:(2,2),45:(2,3),44:(2,4),43:(2,5),42:(2,6),
59:(3,0),53:(3,1),52:(3,2),51:(3,3),50:(3,4),49:(3,5),48:(3,6),
58:(4,0),57:(4,1),56:(4,2),55:(4,3)}
left = np.zeros((7,5)).T
right = np.zeros_like(left)
for key in df.index:
if key <= 29:
x,y = left_dict[key]
left[x,y] = df.loc[key].values[0]
else:
x,y = right_dict[key]
right[x,y] = df.loc[key].values[0]
left[left == 0] = np.nan
right[right == 0] = np.nan
merge = np.hstack((left,right))
import matplotlib.pyplot as plt
plt.imshow(np.log10(merge))
plt.colorbar(fraction=0.017, pad=0.02, label='log$_{10}$ press count [#]')
for y in range(merge.shape[0]):
for x in range(merge.shape[1]):
val = merge[y,x]
if ~np.isnan(val):
plt.text(x-0.33,y,str(int(val)), color='w', horizontalalignment='left')
plt.savefig('/home/kdm/projects/KB/mankoffskey/heatmap.png')
- Adapted from: https://github.com/boardsource/pegBoards/tree/main/keyboards/kata0510-lily58-blok-L
- Hardware: Lily58 from https://shop.beekeeb.com/ using Sea-Picro https://github.com/joshajohnson/sea-picro
ls /media/kdm/
echo ""
ls /media/kdm/CIRCUITPY
CIRCUITPY Kindle boot_out.txt kb.py kmk main.py
cat /etc/fstab
# /etc/fstab: static file system information. # # Use 'blkid' to print the universally unique identifier for a # device; this may be used with UUID= as a more robust way to name devices # that works even if disks are added and removed. See fstab(5). # # <file system> <mount point> <type> <options> <dump> <pass> /dev/mapper/vgkubuntu-root / ext4 errors=remount-ro 0 1 # /boot was on /dev/nvme0n1p2 during installation UUID=3550e9b4-85b0-4996-9ca3-740c0ef22e78 /boot ext4 defaults 0 2 # /boot/efi was on /dev/nvme0n1p1 during installation UUID=B298-D0CC /boot/efi vfat umask=0077 0 1 /dev/mapper/vgkubuntu-swap_1 none swap sw 0 0 /dev/mapper/sda1_crypt /home ext4 defaults 0 2 # sudo blkid UUID=F6AB-6D5A /media/kdm/CIRCUITPY vfat nofail,user 0 0