Skip to content

Commit 605230f

Browse files
committed
Initial M5Stack Cardputer support
1 parent 0caf3e1 commit 605230f

6 files changed

+417
-0
lines changed
1.98 KB
Binary file not shown.
634 Bytes
Binary file not shown.
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
"""
2+
`M5StackCardputerKbd`
3+
====================================================
4+
5+
CircuitPython M5Stack Cardputer Matrix Keyboard driver.
6+
7+
* Author(s): foamyguy during YouTube livestream
8+
https://www.youtube.com/watch?v=la7g24fP7IQ&t=4s
9+
10+
retiredwizard added modifier keys (shift, alt, ...) and minor performance changes
11+
12+
"""
13+
14+
15+
import board
16+
import digitalio
17+
import keypad
18+
from adafruit_debouncer import Debouncer
19+
#import time
20+
21+
class MultiplexerKeys():
22+
23+
def __init__(self,multiplexed_row_pins, column_pins, value_when_pressed=False):
24+
self.row_pins = multiplexed_row_pins
25+
self.column_pins = column_pins
26+
self.row_dio_objs = []
27+
self.col_dio_objs = []
28+
29+
# Initialize the row pins as outputs
30+
for row_pin in self.row_pins:
31+
_cur_dio = digitalio.DigitalInOut(row_pin)
32+
_cur_dio.direction = digitalio.Direction.OUTPUT
33+
self.row_dio_objs.append(_cur_dio)
34+
35+
# Initialize the colun pins as inputs with pull-ups
36+
for column_pin in self.column_pins:
37+
_cur_dio = digitalio.DigitalInOut(column_pin)
38+
_cur_dio.direction = digitalio.Direction.INPUT
39+
_cur_dio.pull = digitalio.Pull.UP
40+
self.col_dio_objs.append(Debouncer(_cur_dio,.1))
41+
# self.col_dio_objs.append(_cur_dio)
42+
43+
self.value_when_pressed = value_when_pressed
44+
45+
self._events = []
46+
self._last_key = None
47+
48+
@property
49+
def events(self):
50+
self._scan()
51+
return self._events
52+
53+
# Function to scan the key matrix
54+
def _scan(self):
55+
self._events = []
56+
key_num = -1 # Set so held button can be differentiated from no key pressed
57+
for i in range(8):
58+
self.set_multiplexer_state(i)
59+
for col, column_pin in enumerate(self.col_dio_objs):
60+
column_pin.update()
61+
column_pin.update()
62+
while column_pin.state not in [0,3]:
63+
column_pin.update()
64+
if column_pin.value == self.value_when_pressed: # If a key is pressed
65+
key_num = (i * len(self.col_dio_objs)) + col
66+
#print("Key ({}, {:03b}, {}) pressed".format(key_num, i, col))
67+
self._events.append(keypad.Event(key_number=key_num, pressed=True))
68+
self._last_key = key_num
69+
# time.sleep(.1)
70+
if key_num == -1: # No keys pressed
71+
if self._last_key is not None:
72+
self._events.append(keypad.Event(key_number=self._last_key, pressed=False))
73+
self._last_key = None
74+
# time.sleep(.1)
75+
76+
def set_multiplexer_state(self, state_binary):
77+
for idx, compare in enumerate((0b100,0b010,0b001)):
78+
self.row_dio_objs[idx].value = True if state_binary & compare else False
79+
80+
class Cardputer():
81+
def __init__(self):
82+
row_pins = (board.KB_A_0, board.KB_A_1, board.KB_A_2)
83+
column_pins = (
84+
board.KB_COL_0, board.KB_COL_1, board.KB_COL_2, board.KB_COL_3, board.KB_COL_4, board.KB_COL_5, board.KB_COL_6)
85+
86+
self._KEY_MATRIX_LUT = [
87+
# row 4
88+
("OPT","",""), ("z","Z",""), ("c","C",""), ("b","B",""),
89+
("m","M",""), (".",">","DOWN"), (" ","",""), ("CTRL","",""),
90+
("ALT","",""), ("x","X",""), ("v","V",""), ("n","N",""),
91+
(",","<","LEFT"), ("/","?","RIGHT"),
92+
93+
# row 2
94+
("q","Q",""), ("e","E",""), ("t","T",""), ("u","U",""),
95+
("o","O",""), ("[","{",""), ("\\","|",""), ("\t","",""),
96+
("w","W",""), ("r","R",""), ("y","Y",""), ("i","I",""),
97+
("p","P",""), ("]","}",""),
98+
99+
# row 3
100+
("SHIFT","",""), ("s","S",""), ("f","F",""), ("h","H",""),
101+
("k","K",""), (";",":","UP"), ("\n","",""), ("FN","",""),
102+
("a","A",""), ("d","D",""), ("g","G",""), ("j","J",""),
103+
("l","L",""), ("'",'"',""),
104+
105+
# row 1
106+
("1","!",""), ("3","#",""), ("5","%",""), ("7","&",""),
107+
("9","(",""), ("_","-",""), ("\x08","",""), ("`","~","\x1b"),
108+
("2","@",""), ("4","$",""), ("6","^",""), ("8","*",""),
109+
("0",")",""), ("=","+","")
110+
]
111+
112+
self.keyboard = MultiplexerKeys(row_pins, column_pins)
113+
114+
self.shift = False
115+
self.funct = False
116+
self.ctrl = False
117+
self.opt = False
118+
self.alt = False
119+
120+
def check_keyboard(self):
121+
events = self.keyboard.events
122+
new_char_buffer = ""
123+
if events:
124+
for event in events:
125+
if event.pressed:
126+
new_char = self._KEY_MATRIX_LUT[event.key_number][0]
127+
if new_char in ['SHIFT','FN','CTRL','OPT','ALT']:
128+
new_char = ""
129+
else:
130+
if self.shift:
131+
new_char = self._KEY_MATRIX_LUT[event.key_number][1]
132+
self.shift = False
133+
elif self.funct:
134+
new_char = self._KEY_MATRIX_LUT[event.key_number][2]
135+
self.funct = False
136+
#new_char_buffer += new_char # Replaced so only last char if multiple events
137+
new_char_buffer = new_char # (multiple keys simultaneously pressed)
138+
139+
else:
140+
# For modifer keys disable auto-repeat by only responding to "RELEASE" events
141+
new_char = self._KEY_MATRIX_LUT[event.key_number][0]
142+
if new_char == "SHIFT":
143+
self.shift = not self.shift
144+
elif new_char == "FN":
145+
self.funct = not self.funct
146+
elif new_char == "CTRL":
147+
self.ctrl = not self.ctrl
148+
elif new_char == "OPT":
149+
self.opt = not self.opt
150+
elif new_char == "ALT":
151+
self.alt = not self.alt
152+
153+
154+
return new_char_buffer
155+
156+
# Exmple Usage:
157+
#
158+
#cardputer = Cardputer()
159+
160+
#while True:
161+
# print(cardputer.check_keyboard(),end="")
162+

0 commit comments

Comments
 (0)