Skip to content

Instantly share code, notes, and snippets.

@b2ox
Last active April 7, 2023 00:01
Show Gist options
  • Save b2ox/91ca055f2e90972bf535a8a5df8fae60 to your computer and use it in GitHub Desktop.
Save b2ox/91ca055f2e90972bf535a8a5df8fae60 to your computer and use it in GitHub Desktop.
Neopixel indicator module for kmk firmware
import time
#import neopixel
from pioasm_neopixel_bg import NeoPixelBackground
# https://learn.adafruit.com/intro-to-rp2040-pio-with-circuitpython/advanced-using-pio-to-drive-neopixels-in-the-background
from kmk.modules import Module, InvalidExtensionEnvironment
from kmk.keys import ModifierKey
class NPXStatus(Module):
def __init__(
self,
neopixel_pin,
led_num,
colors = [(0, 0, 5), (0, 5, 0), (5, 0, 0), (5, 5, 5)],
):
if led_num < 4:
raise InvalidExtensionEnvironment('Need at least 4 LEDs')
if len(colors) < led_num:
n = len(colors)
c = colors[-1]
for i in range(led_num - n):
colors.append(c)
self._neopixel_pin = neopixel_pin
self._layerbits = led_num - 3
self._colors = colors
def __repr__(self):
return 'NPXStatus()'
def on_runtime_enable(self, keyboard):
return
def on_runtime_disable(self, keyboard):
return
def during_bootup(self, keyboard):
'''Light up every single led once'''
#self._neopixel = neopixel.NeoPixel(self._neopixel_pin, self._layerbits + 3, auto_write = False)
self._neopixel = NeoPixelBackground(self._neopixel_pin, self._layerbits + 3, auto_write = False)
for i in range(self._layerbits + 3):
self._neopixel[i] = (0, 5, 0)
self._neopixel.show()
time.sleep(0.1)
for i in range(self._layerbits + 3):
self._neopixel[i] = (0, 0, 0)
self._neopixel.show()
return
def before_matrix_scan(self, keyboard):
return
def after_matrix_scan(self, keyboard):
return
def before_hid_send(self, keyboard):
'''
Indicates modifier keys and layer with NeoPixel
It show binary number as active layer number
'''
modSCA = [False, False, False]
for key in keyboard.keys_pressed:
if type(key) == ModifierKey:
if key.code == 0x2 or key.code == 0x20:
modSCA[0] = True
if key.code == 0x1 or key.code == 0x10:
modSCA[1] = True
if key.code == 0x4 or key.code == 0x40:
modSCA[2] = True
if key.code < 0:
for mo in key.has_modifiers:
if mo == 0x2 or mo == 0x20:
modSCA[0] = True
if mo == 0x1 or mo == 0x10:
modSCA[1] = True
if mo == 0x4 or mo == 0x40:
modSCA[2] = True
bitOFF = (0, 0, 0)
for i in range(3):
self._neopixel[i] = self._colors[i] if modSCA[i] else bitOFF
tmp = keyboard.active_layers[0]
for i in range(self._layerbits):
self._neopixel[3 + i] = self._colors[3 + i] if 0 < (tmp & 1) else bitOFF
tmp = tmp >> 1
self._neopixel.show()
return
def after_hid_send(self, keyboard):
return
def on_powersave_enable(self, keyboard):
return
def on_powersave_disable(self, keyboard):
return
@b2ox
Copy link
Author

b2ox commented Sep 5, 2022

Usage:

from NPXStatus import NPXStatus

npxStatus = NPXStatus(board.GP16, 6, [(0, 0, 15), (0, 15, 0), (15, 0, 0), (14, 5, 5), (5, 5, 14), (5, 14, 5)])
# 引数: 信号ピン, 個数, [shift色, ctrl色, alt色, レイヤー番号1ビット目の色, 2ビット目の色, ...]

modules.append(npxStatus)

@b2ox
Copy link
Author

b2ox commented Sep 5, 2022

動作にはCircuitPythonのadafruit_pixelbuf.pyとneopixel.pyが必要。

@b2ox
Copy link
Author

b2ox commented Mar 30, 2023

neopixel.pyだと別の場所がちらついたりするので、PIO版を使った方が良い。
入手先はソース中のurl
adafruit_pioasm.pyも必要。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment