layers and layer colors
This commit is contained in:
4
code.py
4
code.py
@@ -1,6 +1,6 @@
|
||||
from keyboard import Keyboard
|
||||
from config import io_extenders_pinout, pinout, keymap, rgb_pins
|
||||
from config import io_extenders_pinout, pinout, keymap, rgb_pins, layer_colors
|
||||
|
||||
keyboard_state_manager = Keyboard(io_extenders_pinout, pinout, keymap, rgb_pins)
|
||||
keyboard_state_manager = Keyboard(io_extenders_pinout, pinout, keymap, rgb_pins, layer_colors)
|
||||
|
||||
keyboard_state_manager.start()
|
||||
4
config.py
Executable file → Normal file
4
config.py
Executable file → Normal file
@@ -1,6 +1,7 @@
|
||||
|
||||
# pimodori tiny 2040 8MB
|
||||
import board
|
||||
from keyboard import Hold, Toggle
|
||||
from keycodes import SE
|
||||
|
||||
io_extenders_pinout = [(0x20, board.GP1, board.GP0)]
|
||||
@@ -13,11 +14,12 @@ pinout: tuple[int,int] = [
|
||||
]
|
||||
|
||||
keymap: list[int] = [
|
||||
121, SE.TWO, SE.THREE, SE.FOUR,
|
||||
Hold(1), Toggle(2), Toggle(3), Toggle(4),
|
||||
SE.A, SE.B, SE.C, SE.D,
|
||||
SE.E, SE.F, SE.G, SE.H,
|
||||
SE.I, SE.J, SE.K, SE.L
|
||||
]
|
||||
|
||||
layer_colors = [(255,255,255),(0,255,0),(0,0,255), (255,0,255), (255, 255, 0)]
|
||||
|
||||
rgb_pins: tuple[int,int,int] = (board.LED_R, board.LED_G, board.LED_B)
|
||||
98
keyboard.py
Executable file → Normal file
98
keyboard.py
Executable file → Normal file
@@ -7,6 +7,17 @@ import pwmio
|
||||
import time
|
||||
from micropython import const
|
||||
|
||||
class LayerKey:
|
||||
layer: int
|
||||
def __init__(self, layer:int):
|
||||
self.layer = layer
|
||||
class Toggle(LayerKey):
|
||||
def __init__(self, layer:int):
|
||||
super().__init__(layer)
|
||||
class Hold(LayerKey):
|
||||
def __init__(self, layer:int):
|
||||
super().__init__(layer)
|
||||
|
||||
__RED = (255,0,0)
|
||||
__BLUE = (0,0,255)
|
||||
__GREEN = (0,255,0)
|
||||
@@ -28,6 +39,8 @@ class RGBLED:
|
||||
|
||||
def set(self, rgb_values: tuple[int, int, int]):
|
||||
for i in range(3):
|
||||
input = rgb_values[i]
|
||||
assert 0 <= input <=255
|
||||
value = self.__to_inverse_8_bit_value(rgb_values[i])
|
||||
self.leds[i].duty_cycle = value
|
||||
|
||||
@@ -65,9 +78,16 @@ class RGBLED:
|
||||
else:
|
||||
time.sleep(color_sleep_cycles[i][0])
|
||||
|
||||
__PRESSED = False
|
||||
__UNPRESSED = True
|
||||
__PRESSED = const(0)
|
||||
__UNPRESSED = const(1)
|
||||
__TOGGLED_PRESSED = const(2)
|
||||
__TOGGLED_RELEASED = const(3)
|
||||
__UNTOGGLED_PRESSED = const(4)
|
||||
class Keyboard:
|
||||
active_layer: int
|
||||
previous_layers: list[int]
|
||||
layer_colors: list[tuple[int,int,int]]
|
||||
|
||||
pressed_keys_last_cycle: set[int]
|
||||
pressed_keys: set[int]
|
||||
|
||||
@@ -79,7 +99,7 @@ class Keyboard:
|
||||
keyboard_device: usb_hid.Device
|
||||
led: RGBLED
|
||||
|
||||
def __init__(self, io_extenders_pinout: list[tuple[int, int, int]], pinout: list[tuple[int,int]], keymap: list[int], rgb_pins: tuple[int, int, int]):
|
||||
def __init__(self, io_extenders_pinout: list[tuple[int, int, int]], pinout: list[tuple[int,int]], keymap: list[int], rgb_pins: tuple[int, int, int], layer_colors: list[tuple[int, int, int]]):
|
||||
"""Initialize new keyboard
|
||||
|
||||
'io_extenders_pinout': list of tuple containing the i2c address, clock pin and data pin of the device. The order of the extenders are decided by the order in the list.
|
||||
@@ -92,6 +112,7 @@ class Keyboard:
|
||||
self.pins = self.initialize_pins(io_extenders, pinout)
|
||||
|
||||
self.keymap = keymap
|
||||
self.layer_colors = layer_colors
|
||||
|
||||
self.led = RGBLED(rgb_pins)
|
||||
self.led.indicate_boot()
|
||||
@@ -135,6 +156,8 @@ class Keyboard:
|
||||
|
||||
def start(self):
|
||||
try:
|
||||
self.active_layer = 0
|
||||
self.previous_layers = []
|
||||
self.pressed_keys = set()
|
||||
self.pressed_keys_last_cycle = set()
|
||||
self.pin_states_last_cycle = []
|
||||
@@ -145,20 +168,61 @@ class Keyboard:
|
||||
keycode = self.keymap[pin_index]
|
||||
previously = self.pin_states_last_cycle[pin_index]
|
||||
value = pin.value
|
||||
currentlyPressed = value is __PRESSED
|
||||
previouslyPressed = previously is __PRESSED
|
||||
if currentlyPressed:
|
||||
if not previouslyPressed:
|
||||
self.pressed_keys.add(keycode)
|
||||
else:
|
||||
if previouslyPressed:
|
||||
try:
|
||||
self.pressed_keys.remove(keycode)
|
||||
# Catch silenly if same keycode is pressed twice then released
|
||||
except KeyError:
|
||||
pass
|
||||
self.pin_states_last_cycle[pin_index] = value
|
||||
|
||||
currentlyPressed = value == __PRESSED
|
||||
previouslyPressed = previously == __PRESSED
|
||||
previouslyToggled = previously == __TOGGLED_PRESSED
|
||||
previouslyToggledReleased = previously == __TOGGLED_RELEASED
|
||||
previouslyUntoggledPressed = previously == __UNTOGGLED_PRESSED
|
||||
if not isinstance(keycode, LayerKey):
|
||||
if currentlyPressed:
|
||||
if not previouslyPressed:
|
||||
self.pressed_keys.add(keycode)
|
||||
else:
|
||||
if previouslyPressed:
|
||||
try:
|
||||
self.pressed_keys.remove(keycode)
|
||||
# Catch silenly if same keycode is pressed twice then released
|
||||
except KeyError:
|
||||
pass
|
||||
self.pin_states_last_cycle[pin_index] = value
|
||||
continue
|
||||
# TODO: Always release old key when entering new layer
|
||||
if type(keycode) is Hold:
|
||||
if currentlyPressed and not previouslyPressed:
|
||||
self.previous_layers.append(self.active_layer)
|
||||
self.active_layer = keycode.layer
|
||||
print(f"hold: {self.previous_layers}")
|
||||
self.pin_states_last_cycle[pin_index] = value
|
||||
continue
|
||||
if previouslyPressed and not currentlyPressed:
|
||||
self.active_layer = self.previous_layers.pop()
|
||||
self.pin_states_last_cycle[pin_index] = value
|
||||
print(f"release: {self.previous_layers}")
|
||||
continue
|
||||
if type(keycode) is Toggle:
|
||||
if currentlyPressed and not previouslyToggled and not previouslyToggledReleased and not previouslyUntoggledPressed:
|
||||
self.previous_layers.append(self.active_layer)
|
||||
self.active_layer = keycode.layer
|
||||
print(f"Toggled: {self.previous_layers}")
|
||||
self.pin_states_last_cycle[pin_index] = __TOGGLED_PRESSED
|
||||
continue
|
||||
if not currentlyPressed and previouslyToggled:
|
||||
print(f"Toggled Released: {self.previous_layers}")
|
||||
self.pin_states_last_cycle[pin_index] = __TOGGLED_RELEASED
|
||||
continue
|
||||
if currentlyPressed and previouslyToggledReleased:
|
||||
print(f"Untoggled: {self.previous_layers}")
|
||||
self.active_layer = self.previous_layers.pop()
|
||||
self.pin_states_last_cycle[pin_index] = __UNTOGGLED_PRESSED
|
||||
continue
|
||||
if not currentlyPressed and previouslyUntoggledPressed:
|
||||
print(f"Untoggled unpressed: {self.previous_layers}")
|
||||
self.pin_states_last_cycle[pin_index] = __UNPRESSED
|
||||
continue
|
||||
if len(self.layer_colors) >= (self.active_layer + 1):
|
||||
self.led.set(self.layer_colors[self.active_layer])
|
||||
else:
|
||||
self.led.off()
|
||||
if self.pressed_keys != self.pressed_keys_last_cycle:
|
||||
self.send_nkro_report()
|
||||
self.pressed_keys_last_cycle = set(self.pressed_keys)
|
||||
|
||||
0
keycodes.py
Executable file → Normal file
0
keycodes.py
Executable file → Normal file
0
lib/adafruit_mcp230xx/__init__.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/__init__.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/digital_inout.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/digital_inout.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/mcp23008.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/mcp23008.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/mcp23016.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/mcp23016.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/mcp23017.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/mcp23017.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/mcp230xx.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/mcp230xx.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/mcp23s17.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/mcp23s17.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/mcp23sxx.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/mcp23sxx.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/mcp23xxx.mpy
Normal file → Executable file
0
lib/adafruit_mcp230xx/mcp23xxx.mpy
Normal file → Executable file
0
lib/simpleio.mpy
Normal file → Executable file
0
lib/simpleio.mpy
Normal file → Executable file
Reference in New Issue
Block a user