Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mankoff/mankoffskey
Custom mankoff keyboard
https://github.com/mankoff/mankoffskey
Last synced: 11 days ago
JSON representation
Custom mankoff keyboard
- Host: GitHub
- URL: https://github.com/mankoff/mankoffskey
- Owner: mankoff
- Created: 2023-03-29T19:47:46.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-04-20T22:25:22.000Z (7 months ago)
- Last Synced: 2024-06-11T17:34:08.918Z (5 months ago)
- Size: 51.8 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.org
Awesome Lists containing this project
README
* Table of contents :toc_2:noexport:
- [[#layout][Layout]]
- [[#kbpy][kb.py]]
- [[#mainpy][main.py]]
- [[#graphical-layout][Graphical layout]]
- [[#heatmap][Heatmap]]
- [[#capture][Capture]]
- [[#process][Process]]
- [[#background][Background]]
- [[#is-it-attached][Is it attached?]]
- [[#auto-mount-when-plugged-in][Auto-mount when plugged in]]* Layout
** kb.py
#+BEGIN_SRC python :tangle /media/kdm/CIRCUITPY/kb.py
import boardfrom 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.SDAcoord_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,
]
#+END_SRC#+RESULTS:
** main.py
#+BEGIN_SRC python :tangle /media/kdm/CIRCUITPY/main.py
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.NOkeyboard.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.GRVLBRC=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.COLNclass 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)#+END_SRC
* Graphical layout
This PNG can be edited on https://drawio.png
[[./lily58.drawio.png]]
* Heatmap
** Capture
#+BEGIN_SRC bash :exports both :results verbatim# turn on debugging:
# keyboard.debug_enabled = True # in main.py# capture everything
cat < /dev/ttyACM0 |grep pressed >> logfile
#+END_SRC** Process
#+BEGIN_SRC bash :exports both :results verbatim
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
#+END_SRC#+RESULTS:
#+begin_example
5 35
12 48
14 5
14 55
21 21
28 34
34 4
36 3
37 49
40 59
#+end_example#+BEGIN_SRC jupyter-python :exports both
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.nanmerge = 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')
#+END_SRC#+RESULTS:
[[file:./figs_tmp/ca93a925160bc526a351365f460c5306df2479d6.png]]* Background
+ 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* Is it attached?
#+BEGIN_SRC bash :exports both :results verbatim
ls /media/kdm/
echo ""
ls /media/kdm/CIRCUITPY
#+END_SRC#+RESULTS:
: CIRCUITPY
: Kindle
:
: boot_out.txt
: kb.py
: kmk
: main.py* Auto-mount when plugged in
#+BEGIN_SRC bash :exports both :results verbatim
cat /etc/fstab
#+END_SRC#+RESULTS:
#+begin_example
# /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).
#
#
/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
#+end_example