====== Micro Keypad Software ====== ===== Inhalt ===== Dieses Video ist der zweite Part zu meinem Micro Keypad Projekt. Hier geht es um die Firmware kmk, welche Möglichkeiten sie bietet und wie man damit am Ende eine eigene Tastatur erstellen kann. Als Entwicklungsumgebung für Python kommt Thonny zum Einsatz. Und nein, man muss dafür kein Entwicklerprofi sein :-) ===== YouTube Video #12 ===== {{youtube>XwqdD4puiWo?half}} ===== Spenden ===== Wer meinen Kanal und meine Arbeit unterstützen möchte, kann das über folgenden Paypal Link: \\ https://www.paypal.com/donate/?hosted_button_id=68UZ68DMENVP6 ===== Github ===== https://github.com/DrKlipper/MikroKeypad/ ====== Anleitung ====== ===== Entwicklung / Debugging ===== * Thonny * Notepad++ * Serial Monitor (z.B. YAT -> https://sourceforge.net/projects/y-a-terminal/) \\ Port Einstellungen: 115200 8n1 mit DTR \\ ===== boot.py konfigurieren ===== import supervisor import board import storage import usb_cdc from digitalio import DigitalInOut, Direction, Pull supervisor.set_next_stack_limit(4096 + 4096) row = DigitalInOut(board.GP3) col = DigitalInOut(board.GP4) row.direction = Direction.INPUT col.direction = Direction.OUTPUT row.pull = Pull.DOWN col.value = True # Wenn die Taste NICHT gedrückt ist wird alles abgeschaltet # Nur wenn die Taste (#) gedrückt wird erscheint der serielle Port & das Laufwerk if not row.value: # USB Laufwerk einblenden auf Knopfdruck (#) #storage.disable_usb_drive() # Seriellen Port einblenden auf Knopfdruck (#) #usb_cdc.disable() ===== Programmierung ===== ==== Single Key ==== http://kmkfw.io/docs/keycodes Beispiele * ''KC.A'' * ''KC.N1'' * ''KC.ENTER'' * ''KC.F13'' * ''KC.LEFT'' * ''KC.LCTRL'' ==== Sondertasten + Key ==== Beispiele \\ * ''KC.LCTRL(KC.LALT(KC.DOT))'', * ''KC.LCTRL(KC.C)'' ==== Sondertasten + Key mit Verzögerung ==== simple_key_sequence([ KC.LALT(no_release=True), KC.MACRO_SLEEP_MS(30), KC.LEFT, KC.MACRO_SLEEP_MS(30), KC.LALT(no_press=True),]), ==== String Kette ==== Beispiele * ''send_string('open https://github.com')'' -> Achtung Sonderzeichen ! Siehe Fix folgend ... * ''send_string('Dies ist nur ein Text !')'' ==== Problemfix send_string ==== * für Umlaute und Sonderzeichen in deutschem Format ... * US Tastatur installieren * Text in ENG Layout schreiben * Wenn Windows auf Deu steht hat man die Umlaute und Sonderzeichen in Deutsch * Bsp: send_string("http>&&www.heise.de;'[:\"{"), ergibt -> http://www.heise.deöäüÖÄÜ ===== Beispiel simple Keypad ===== Dieses Beispiel nutzt nur die Tasten mit einem Layer. import board from kmk.kmk_keyboard import KMKKeyboard from kmk.keys import KC from kmk.scanners import DiodeOrientation from kmk.extensions.media_keys import MediaKeys from kmk.handlers.sequences import send_string, simple_key_sequence # Keyboard Instanz erzeugen keyboard = KMKKeyboard() # Debugging keyboard.debug_enabled = True # Setup media_keys = MediaKeys() keyboard.extensions.append(media_keys) # Tastatur Matrix keyboard.col_pins = (board.GP2, board.GP0, board.GP4) keyboard.row_pins = (board.GP1, board.GP6, board.GP5, board.GP3) keyboard.diode_orientation = DiodeOrientation.COL2ROW # Keymaps keyboard.keymap = [ # Windows [ #KC.MEDIA_PREV_TRACK, send_string("http>&&www.heise.de;'[:\"{"), KC.MEDIA_PLAY_PAUSE, KC.MEDIA_NEXT_TRACK, KC.LGUI(KC.LSHIFT(KC.C)), KC.LALT(KC.SPACE), KC.LCTRL(KC.LSHIFT(KC.ESCAPE)), KC.LGUI(KC.LCTRL(KC.LEFT)), KC.LGUI(KC.LCTRL(KC.D)), KC.LGUI(KC.LCTRL(KC.RIGHT)), KC.LGUI(KC.L), KC.LCTRL(KC.LALT(KC.LSHIFT(KC.C))), KC.NO ] ] if __name__ == '__main__': keyboard.go() ===== Rotary Beispiel ===== import board from kmk.kmk_keyboard import KMKKeyboard from kmk.keys import KC from kmk.scanners import DiodeOrientation from kmk.extensions.media_keys import MediaKeys from kmk.handlers.sequences import send_string, simple_key_sequence from kmk.modules.encoder import EncoderHandler # Keyboard Instanz erzeugen keyboard = KMKKeyboard() # Debugging keyboard.debug_enabled = True # Setup media_keys = MediaKeys() encoders = EncoderHandler() keyboard.modules = [encoders] keyboard.extensions.append(media_keys) # Tastatur Matrix keyboard.col_pins = (board.GP2, board.GP0, board.GP4) keyboard.row_pins = (board.GP1, board.GP6, board.GP5, board.GP3) keyboard.diode_orientation = DiodeOrientation.COL2ROW # Encoder (Pin A, Pin B, Pin Button) encoders.pins = ( (board.GP9, board.GP10, board.GP11, False), # Second Encoder ) # Keymaps keyboard.keymap = [ # Windows [ #KC.MEDIA_PREV_TRACK, send_string("http>&&www.heise.de;'[:\"{"), KC.MEDIA_PLAY_PAUSE, KC.MEDIA_NEXT_TRACK, KC.LGUI(KC.LSHIFT(KC.C)), KC.LALT(KC.SPACE), KC.LCTRL(KC.LSHIFT(KC.ESCAPE)), KC.LGUI(KC.LCTRL(KC.LEFT)), KC.LGUI(KC.LCTRL(KC.D)), KC.LGUI(KC.LCTRL(KC.RIGHT)), KC.LGUI(KC.L), KC.LCTRL(KC.LALT(KC.LSHIFT(KC.C))), KC.NO ] ] # Encoder encoders.map = ( # Layer 1 -> nach dem , käme Encoder 2 wenn vorhanden ((KC.VOLD, KC.VOLU, KC.MUTE),), ) if __name__ == '__main__': keyboard.go() ===== Layer ===== ==== LEDs ==== Die LEDs zeigen an, welcher Layer gerade aktiv ist. ==== LED Code umbauen ==== Layer 0 wird leider nicht angezeigt sondern erst ab Layer 1. Deswegen wird der entsprechende Code leicht modifiziert 8-) \\ Die Datei liegt unter ''kmk\extensions\statusled.py''. def _layer_indicator(self, layer_active, *args, **kwargs): ''' Indicates layer with leds For the time being just a simple consecutive single led indicator. And when there are more layers than leds it wraps around to the first led again. (Also works for a single led, which just lights when any layer is active) ''' if self._layer_last != layer_active: self.set_brightness(((self.brightness, 0)[layer_active!=0]), 1) self.set_brightness(((self.brightness, 0)[layer_active!=1]), 2) self.set_brightness(((self.brightness, 0)[layer_active!=2]), 3) print(layer_active) self._layer_last = layer_active # if self._layer_last != layer_active: # led_last = 0 if self._layer_last == 0 else 1 + (self._layer_last - 1) % 3 # print(layer_active) # if layer_active > 0: # led_active = 0 if layer_active == 0 else 1 + (layer_active - 1) % 3 # self.set_brightness(self.brightness, led_active) # self.set_brightness(0, led_last) # else: # self.set_brightness(0, led_last) # self._layer_last = layer_active ==== Layer umschalten ==== Das Layer Umschalten erfolgt über den Befehl ''KC.DF(1)''. Die 1 ist der einzuschaltende Layer. Die Layer zählen von 0 an und nicht (!) von 1. ===== komplettes Beispiel mit Layern ===== import board from kmk.kmk_keyboard import KMKKeyboard from kmk.keys import KC from kmk.extensions.media_keys import MediaKeys from kmk.scanners import DiodeOrientation from kmk.handlers.sequences import send_string, simple_key_sequence from kmk.modules.layers import Layers from kmk.modules.encoder import EncoderHandler from kmk.extensions.statusled import statusLED from kmk.extensions.international import International # Keyboard Instanz erzeugen keyboard = KMKKeyboard() # Debugging keyboard.debug_enabled = True # LED Konfig für Layer 1..3 statusLED = statusLED(led_pins=[board.GP14, board.GP26, board.GP15]) # Setup media_keys = MediaKeys() layers = Layers() encoders = EncoderHandler() keyboard.modules = [layers, encoders] keyboard.extensions.append(media_keys) keyboard.extensions.append(statusLED) keyboard.extensions.append(International()) # Tastatur Matrix keyboard.col_pins = (board.GP2, board.GP0, board.GP4) keyboard.row_pins = (board.GP1, board.GP6, board.GP5, board.GP3) keyboard.diode_orientation = DiodeOrientation.COL2ROW # Encoder (Pin A, Pin B, Pin Button) encoders.pins = ( (board.GP9, board.GP10, board.GP11, False), # Second Encoder ) # Keymaps keyboard.keymap = [ # Windows [ KC.MEDIA_PREV_TRACK, KC.MEDIA_PLAY_PAUSE, KC.MEDIA_NEXT_TRACK, KC.LGUI(KC.LSHIFT(KC.C)), KC.LALT(KC.SPACE), KC.LCTRL(KC.LSHIFT(KC.ESCAPE)), KC.LGUI(KC.LCTRL(KC.LEFT)), KC.LGUI(KC.LCTRL(KC.D)), KC.LGUI(KC.LCTRL(KC.RIGHT)), KC.LGUI(KC.L), KC.LCTRL(KC.LALT(KC.LSHIFT(KC.C))), KC.DF(1) ], # OBS [ KC.F13, KC.F14, KC.F15, KC.F16, KC.F17, KC.F18, KC.F19, KC.F20, KC.F21, KC.F22, KC.F23, KC.DF(2) ], # Schnitt [ KC.LCTRL(KC.C), KC.LCTRL(KC.V), KC.LCTRL(KC.X), KC.B, KC.R, KC.F, KC.LCTRL(KC.BSPACE), KC.LSHIFT(KC.S), KC.LCTRL(KC.N2), KC.COMMA, KC.DOT, KC.DF(0) ] ] # Encoder encoders.map = ( # Layer 1 -> nach dem , käme Encoder 2 wenn vorhanden ((KC.VOLD, KC.VOLU, KC.MUTE),), # Layer 2 ((KC.VOLD, KC.VOLU, KC.MUTE),), # Layer 3 ((KC.LCTRL(KC.LALT(KC.COMMA)), KC.LCTRL(KC.LALT(KC.DOT)), KC.LCTRL(KC.LSHIFT(KC.N7))),), ) if __name__ == '__main__': keyboard.go() ===== Layer Beschreigung ===== ==== Layer 1 (Windows) ==== ^ Key ^ Funktion ^ Key ^ Funktion ^ Key ^ Funktion ^ | 1 | Kopieren \\ STRG+C | 3 | Einfügen \\ STRG+V | 3 | Ausschneiden \\ STRG+X | | 4 | Coloir Picker \\ WIN+Shift+C | 5 | Power Run \\ ALT + Space | 6 | Taskmanager\\ Strg + Shift + Esc | | 7 | Previous Desktop \\ WIN + STRG + Left | 8 | New virtual Desktop \\ WIN + CTRL + D | 9 | Next Desktop \\ WIN + STRG + RIGHT | | * | Lock \\ WIN + L | 0 | Taschenrechner \\ STRG * ALT * SHIFT + C (Shortcut) | # | Layer 2 | === Rotary === Press -> Mute \\ Left -> Leiser \\ Right -> Lauter ==== Layer 2 (OBS) ==== ^ Key ^ Funktion ^ Key ^ Funktion ^ Key ^ Funktion ^ | 1 | F13 | 3 | F14 | 3 | F15 | | 4 | F16 | 5 | F17 | 6 | F18 | | 7 | F19 | 8 | F20 | 9 | F21 | | * | F22 | 0 | F23 | # | Layer 3 | === Rotary === Press -> Mute \\ Left -> Leiser \\ Right -> Lauter ==== Layer 3 (Schnitt) ==== ^ Key ^ Funktion ^ Key ^ Funktion ^ Key ^ Funktion ^ | 1 | Kopieren \\ STRG+C | 3 | Einfügen \\ STRG+V | 3 | Ausschneiden \\ STRG+X | | 4 | Medien\\ B | 5 | Bibliothek\\ R | 6 | Favoriten \\ F | | 7 | Löschen und Lücke schließen\\ STRG + Back | 8 | Audio stummschalten\\ SHIFT + S | 9 | Eigenwschaften An / Aus \\ STRG + 2 | | * | Frame zurück \\ , (Komma) | 0 | Frame vor \\ . (Punkt) | # | Layer 1 | === Rotary === Press -> Zoom All \\ Left -> Zeitleiste Links \\ Right -> Zeitleiste rechts ===== Links ===== * http://kmkfw.io/ * https://kmkfw.io/docs/ * https://github.com/KMKfw/kmk_firmware