From bb759ddae6c9f4acf1a4a07ba3335bfed29f2038 Mon Sep 17 00:00:00 2001 From: Liz Date: Mon, 15 Jul 2024 14:20:46 -0400 Subject: [PATCH 1/2] adding code for ESP32-S3 macropad --- ESP32-S3_BLE_MacroPad/code.py | 170 ++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 ESP32-S3_BLE_MacroPad/code.py diff --git a/ESP32-S3_BLE_MacroPad/code.py b/ESP32-S3_BLE_MacroPad/code.py new file mode 100644 index 000000000..46cd4e1fe --- /dev/null +++ b/ESP32-S3_BLE_MacroPad/code.py @@ -0,0 +1,170 @@ +# SPDX-FileCopyrightText: 2024 Liz Clark for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +import board +import keypad +import rotaryio +import neopixel +import usb_hid +from adafruit_hid.keyboard import Keyboard +from adafruit_hid.keycode import Keycode +import adafruit_ble +from adafruit_ble.advertising import Advertisement +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from adafruit_ble.services.standard.hid import HIDService +from adafruit_ble.services.standard.device_info import DeviceInfoService + +# BLE advertisement names +ble_maker = "Adafruit Industries" +ble_name = "BLE ESP32-S3 MacroPad" +# neopixel colors +RED = (255, 0, 0) +ORANGE = (255, 127, 0) +YELLOW = (255, 255, 0) +GREEN = (0, 255, 0) +AQUA = (0, 255, 255) +BLUE = (0, 0, 255) +PURPLE = (127, 0, 255) +PINK = (255, 0, 255) +OFF = (0, 0, 0) +# axis states selected with keys 9-11 +axis_states = [0, "x", "y", "z"] +state = axis_states[0] +# keymap for key matrix +keymap = { + (0): (axis_states[0], [Keycode.HOME], RED), # HOME X/Y + (1): (axis_states[0], [Keycode.END], ORANGE), # HOME Z + (2): (axis_states[0], (Keycode.HOME, Keycode.END), YELLOW), # HOME ALL + + (3): (axis_states[0], (Keycode.SHIFT, Keycode.A), GREEN), # SHORTCUT A + (4): (axis_states[0], (Keycode.SHIFT, Keycode.B), AQUA), # SHORTCUT B + (5): (axis_states[0], (Keycode.SHIFT, Keycode.C), BLUE), # SHORTCUT C + + (6): (axis_states[0], [Keycode.TWO], AQUA), # SET STEPS 1MM + (7): (axis_states[0], [Keycode.THREE], PURPLE), # SET STEPS 10MM + (8): (axis_states[0], [Keycode.FOUR], PINK), # SET STEPS 100MM + + (9): (axis_states[1], None, RED), # SET X-AXIS STATE + (10): (axis_states[2], None, GREEN), # SET Y-AXIS STATE + (11): (axis_states[3], None, BLUE), # SET Z-AXIS STATE +} +# keymap for encoder based on state; pos = [0], neg = [1] +encoder_map = { + ("x"): ([Keycode.RIGHT_ARROW], [Keycode.LEFT_ARROW]), + ("y"): ([Keycode.UP_ARROW], [Keycode.DOWN_ARROW]), + ("z"): ([Keycode.W], [Keycode.S]), +} +# make a keyboard +kbd = Keyboard(usb_hid.devices) +# key matrix +COLUMNS = 3 +ROWS = 4 +keys = keypad.KeyMatrix( + row_pins=(board.D12, board.D11, board.D10, board.D9), + column_pins=(board.A0, board.A1, board.A2), + columns_to_anodes=False, +) +# neopixels and key num to pixel function +pixels = neopixel.NeoPixel(board.D5, 12, brightness=0.3) +def key_to_pixel_map(key_number): + row = key_number // COLUMNS + column = key_number % COLUMNS + if row % 2 == 1: + column = COLUMNS - column - 1 + return row * COLUMNS + column +pixels.fill(OFF) # Begin with pixels off. + +# make an encoder +encoder = rotaryio.IncrementalEncoder(board.A3, board.A4) +last_position = 0 + +# connect to BLE +hid = HIDService() +device_info = DeviceInfoService(software_revision=adafruit_ble.__version__, + manufacturer=ble_maker) +advertisement = ProvideServicesAdvertisement(hid) +# Advertise as "Keyboard" (0x03C1) icon when pairing +# https://www.bluetooth.com/specifications/assigned-numbers/ +advertisement.appearance = 961 +scan_response = Advertisement() +scan_response.complete_name = ble_name + +ble = adafruit_ble.BLERadio() +if not ble.connected: + print("advertising") + ble.start_advertising(advertisement, scan_response) +else: + print("already connected") + print(ble.connections) + +while True: + while not ble.connected: + pass + while ble.connected: + # poll for key event + key_event = keys.events.get() + # get position of encoder + position = encoder.position + # if position changes.. + if position != last_position: + # ..and it increases.. + if position > last_position: + # ..and state is x: + if state is axis_states[1]: + kbd.press(*encoder_map[state][0]) + # ..and state is y: + if state is axis_states[2]: + kbd.press(*encoder_map[state][0]) + # ..and state is z: + if state is axis_states[3]: + kbd.press(*encoder_map[state][0]) + # ..and it decreases.. + if position < last_position: + # ..and state is x: + if state is axis_states[1]: + kbd.press(*encoder_map[state][1]) + # ..and state is y: + if state is axis_states[2]: + kbd.press(*encoder_map[state][1]) + # ..and state is z: + if state is axis_states[3]: + kbd.press(*encoder_map[state][1]) + # print(position) + # release all keys + kbd.release_all() + # update last_position + last_position = position + # if a key event.. + if key_event: + # print(key_event) + # ..and it's pressed.. + if key_event.pressed: + # ..and it's keys 0-8, send key presses from keymap: + if keymap[key_event.key_number][0] is axis_states[0]: + state = axis_states[0] + kbd.press(*keymap[key_event.key_number][1]) + # ..and it's key 9, set state to x + if keymap[key_event.key_number][0] is axis_states[1]: + state = axis_states[1] + pixels[key_to_pixel_map(10)] = OFF + pixels[key_to_pixel_map(11)] = OFF + # ..and it's key 10, set state to y + if keymap[key_event.key_number][0] is axis_states[2]: + state = axis_states[2] + pixels[key_to_pixel_map(9)] = OFF + pixels[key_to_pixel_map(11)] = OFF + # ..and it's key 11, set state to z + if keymap[key_event.key_number][0] is axis_states[3]: + state = axis_states[3] + pixels[key_to_pixel_map(9)] = OFF + pixels[key_to_pixel_map(10)] = OFF + # turn on neopixel for key with color from keymap + pixels[key_to_pixel_map(key_event.key_number)] = keymap[key_event.key_number][2] + # ..and it's released.. + if key_event.released: + # if it's key 0-8, release the key press and turn off neopixel + if keymap[key_event.key_number][0] is axis_states[0]: + kbd.release(*keymap[key_event.key_number][1]) + pixels.fill(OFF) + ble.start_advertising(advertisement) From 9fd7bf6c24221997133b46ec5b05295e00dc7d88 Mon Sep 17 00:00:00 2001 From: Liz Date: Thu, 18 Jul 2024 10:25:37 -0400 Subject: [PATCH 2/2] updating to be usb instead of BLE --- ESP32-S3_BLE_MacroPad/code.py | 170 ---------------------------------- ESP32-S3_CNC_MacroPad/code.py | 139 +++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 170 deletions(-) delete mode 100644 ESP32-S3_BLE_MacroPad/code.py create mode 100644 ESP32-S3_CNC_MacroPad/code.py diff --git a/ESP32-S3_BLE_MacroPad/code.py b/ESP32-S3_BLE_MacroPad/code.py deleted file mode 100644 index 46cd4e1fe..000000000 --- a/ESP32-S3_BLE_MacroPad/code.py +++ /dev/null @@ -1,170 +0,0 @@ -# SPDX-FileCopyrightText: 2024 Liz Clark for Adafruit Industries -# -# SPDX-License-Identifier: MIT - -import board -import keypad -import rotaryio -import neopixel -import usb_hid -from adafruit_hid.keyboard import Keyboard -from adafruit_hid.keycode import Keycode -import adafruit_ble -from adafruit_ble.advertising import Advertisement -from adafruit_ble.advertising.standard import ProvideServicesAdvertisement -from adafruit_ble.services.standard.hid import HIDService -from adafruit_ble.services.standard.device_info import DeviceInfoService - -# BLE advertisement names -ble_maker = "Adafruit Industries" -ble_name = "BLE ESP32-S3 MacroPad" -# neopixel colors -RED = (255, 0, 0) -ORANGE = (255, 127, 0) -YELLOW = (255, 255, 0) -GREEN = (0, 255, 0) -AQUA = (0, 255, 255) -BLUE = (0, 0, 255) -PURPLE = (127, 0, 255) -PINK = (255, 0, 255) -OFF = (0, 0, 0) -# axis states selected with keys 9-11 -axis_states = [0, "x", "y", "z"] -state = axis_states[0] -# keymap for key matrix -keymap = { - (0): (axis_states[0], [Keycode.HOME], RED), # HOME X/Y - (1): (axis_states[0], [Keycode.END], ORANGE), # HOME Z - (2): (axis_states[0], (Keycode.HOME, Keycode.END), YELLOW), # HOME ALL - - (3): (axis_states[0], (Keycode.SHIFT, Keycode.A), GREEN), # SHORTCUT A - (4): (axis_states[0], (Keycode.SHIFT, Keycode.B), AQUA), # SHORTCUT B - (5): (axis_states[0], (Keycode.SHIFT, Keycode.C), BLUE), # SHORTCUT C - - (6): (axis_states[0], [Keycode.TWO], AQUA), # SET STEPS 1MM - (7): (axis_states[0], [Keycode.THREE], PURPLE), # SET STEPS 10MM - (8): (axis_states[0], [Keycode.FOUR], PINK), # SET STEPS 100MM - - (9): (axis_states[1], None, RED), # SET X-AXIS STATE - (10): (axis_states[2], None, GREEN), # SET Y-AXIS STATE - (11): (axis_states[3], None, BLUE), # SET Z-AXIS STATE -} -# keymap for encoder based on state; pos = [0], neg = [1] -encoder_map = { - ("x"): ([Keycode.RIGHT_ARROW], [Keycode.LEFT_ARROW]), - ("y"): ([Keycode.UP_ARROW], [Keycode.DOWN_ARROW]), - ("z"): ([Keycode.W], [Keycode.S]), -} -# make a keyboard -kbd = Keyboard(usb_hid.devices) -# key matrix -COLUMNS = 3 -ROWS = 4 -keys = keypad.KeyMatrix( - row_pins=(board.D12, board.D11, board.D10, board.D9), - column_pins=(board.A0, board.A1, board.A2), - columns_to_anodes=False, -) -# neopixels and key num to pixel function -pixels = neopixel.NeoPixel(board.D5, 12, brightness=0.3) -def key_to_pixel_map(key_number): - row = key_number // COLUMNS - column = key_number % COLUMNS - if row % 2 == 1: - column = COLUMNS - column - 1 - return row * COLUMNS + column -pixels.fill(OFF) # Begin with pixels off. - -# make an encoder -encoder = rotaryio.IncrementalEncoder(board.A3, board.A4) -last_position = 0 - -# connect to BLE -hid = HIDService() -device_info = DeviceInfoService(software_revision=adafruit_ble.__version__, - manufacturer=ble_maker) -advertisement = ProvideServicesAdvertisement(hid) -# Advertise as "Keyboard" (0x03C1) icon when pairing -# https://www.bluetooth.com/specifications/assigned-numbers/ -advertisement.appearance = 961 -scan_response = Advertisement() -scan_response.complete_name = ble_name - -ble = adafruit_ble.BLERadio() -if not ble.connected: - print("advertising") - ble.start_advertising(advertisement, scan_response) -else: - print("already connected") - print(ble.connections) - -while True: - while not ble.connected: - pass - while ble.connected: - # poll for key event - key_event = keys.events.get() - # get position of encoder - position = encoder.position - # if position changes.. - if position != last_position: - # ..and it increases.. - if position > last_position: - # ..and state is x: - if state is axis_states[1]: - kbd.press(*encoder_map[state][0]) - # ..and state is y: - if state is axis_states[2]: - kbd.press(*encoder_map[state][0]) - # ..and state is z: - if state is axis_states[3]: - kbd.press(*encoder_map[state][0]) - # ..and it decreases.. - if position < last_position: - # ..and state is x: - if state is axis_states[1]: - kbd.press(*encoder_map[state][1]) - # ..and state is y: - if state is axis_states[2]: - kbd.press(*encoder_map[state][1]) - # ..and state is z: - if state is axis_states[3]: - kbd.press(*encoder_map[state][1]) - # print(position) - # release all keys - kbd.release_all() - # update last_position - last_position = position - # if a key event.. - if key_event: - # print(key_event) - # ..and it's pressed.. - if key_event.pressed: - # ..and it's keys 0-8, send key presses from keymap: - if keymap[key_event.key_number][0] is axis_states[0]: - state = axis_states[0] - kbd.press(*keymap[key_event.key_number][1]) - # ..and it's key 9, set state to x - if keymap[key_event.key_number][0] is axis_states[1]: - state = axis_states[1] - pixels[key_to_pixel_map(10)] = OFF - pixels[key_to_pixel_map(11)] = OFF - # ..and it's key 10, set state to y - if keymap[key_event.key_number][0] is axis_states[2]: - state = axis_states[2] - pixels[key_to_pixel_map(9)] = OFF - pixels[key_to_pixel_map(11)] = OFF - # ..and it's key 11, set state to z - if keymap[key_event.key_number][0] is axis_states[3]: - state = axis_states[3] - pixels[key_to_pixel_map(9)] = OFF - pixels[key_to_pixel_map(10)] = OFF - # turn on neopixel for key with color from keymap - pixels[key_to_pixel_map(key_event.key_number)] = keymap[key_event.key_number][2] - # ..and it's released.. - if key_event.released: - # if it's key 0-8, release the key press and turn off neopixel - if keymap[key_event.key_number][0] is axis_states[0]: - kbd.release(*keymap[key_event.key_number][1]) - pixels.fill(OFF) - ble.start_advertising(advertisement) diff --git a/ESP32-S3_CNC_MacroPad/code.py b/ESP32-S3_CNC_MacroPad/code.py new file mode 100644 index 000000000..0baba77a7 --- /dev/null +++ b/ESP32-S3_CNC_MacroPad/code.py @@ -0,0 +1,139 @@ +# SPDX-FileCopyrightText: 2024 Liz Clark for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +import board +import keypad +import rotaryio +import neopixel +import usb_hid +from adafruit_hid.keyboard import Keyboard +from adafruit_hid.keycode import Keycode + +# neopixel colors +RED = (255, 0, 0) +ORANGE = (255, 127, 0) +YELLOW = (255, 255, 0) +GREEN = (0, 255, 0) +AQUA = (0, 255, 255) +BLUE = (0, 0, 255) +PURPLE = (127, 0, 255) +PINK = (255, 0, 255) +OFF = (0, 0, 0) +# axis states selected with keys 9-11 +axis_states = [0, "x", "y", "z"] +state = axis_states[0] +# keymap for key matrix +keymap = { + (0): (axis_states[0], [Keycode.HOME], RED), # HOME X/Y + (1): (axis_states[0], [Keycode.END], ORANGE), # HOME Z + (2): (axis_states[0], (Keycode.HOME, Keycode.END), YELLOW), # HOME ALL + + (3): (axis_states[0], (Keycode.SHIFT, Keycode.A), GREEN), # SHORTCUT A + (4): (axis_states[0], (Keycode.SHIFT, Keycode.B), AQUA), # SHORTCUT B + (5): (axis_states[0], (Keycode.SHIFT, Keycode.C), BLUE), # SHORTCUT C + + (6): (axis_states[0], [Keycode.TWO], AQUA), # SET STEPS 1MM + (7): (axis_states[0], [Keycode.THREE], PURPLE), # SET STEPS 10MM + (8): (axis_states[0], [Keycode.FOUR], PINK), # SET STEPS 100MM + + (9): (axis_states[1], None, RED), # SET X-AXIS STATE + (10): (axis_states[2], None, GREEN), # SET Y-AXIS STATE + (11): (axis_states[3], None, BLUE), # SET Z-AXIS STATE +} +# keymap for encoder based on state; pos = [0], neg = [1] +encoder_map = { + ("x"): ([Keycode.RIGHT_ARROW], [Keycode.LEFT_ARROW]), + ("y"): ([Keycode.UP_ARROW], [Keycode.DOWN_ARROW]), + ("z"): ([Keycode.W], [Keycode.S]), +} +# make a keyboard +kbd = Keyboard(usb_hid.devices) +# key matrix +COLUMNS = 3 +ROWS = 4 +keys = keypad.KeyMatrix( + row_pins=(board.D12, board.D11, board.D10, board.D9), + column_pins=(board.A0, board.A1, board.A2), + columns_to_anodes=False, +) +# neopixels and key num to pixel function +pixels = neopixel.NeoPixel(board.D5, 12, brightness=0.3) +def key_to_pixel_map(key_number): + row = key_number // COLUMNS + column = key_number % COLUMNS + if row % 2 == 1: + column = COLUMNS - column - 1 + return row * COLUMNS + column +pixels.fill(OFF) # Begin with pixels off. + +# make an encoder +encoder = rotaryio.IncrementalEncoder(board.A3, board.A4) +last_position = 0 + +while True: + # poll for key event + key_event = keys.events.get() + # get position of encoder + position = encoder.position + # if position changes.. + if position != last_position: + # ..and it increases.. + if position > last_position: + # ..and state is x: + if state is axis_states[1]: + kbd.press(*encoder_map[state][0]) + # ..and state is y: + if state is axis_states[2]: + kbd.press(*encoder_map[state][0]) + # ..and state is z: + if state is axis_states[3]: + kbd.press(*encoder_map[state][0]) + # ..and it decreases.. + if position < last_position: + # ..and state is x: + if state is axis_states[1]: + kbd.press(*encoder_map[state][1]) + # ..and state is y: + if state is axis_states[2]: + kbd.press(*encoder_map[state][1]) + # ..and state is z: + if state is axis_states[3]: + kbd.press(*encoder_map[state][1]) + # print(position) + # release all keys + kbd.release_all() + # update last_position + last_position = position + # if a key event.. + if key_event: + # print(key_event) + # ..and it's pressed.. + if key_event.pressed: + # ..and it's keys 0-8, send key presses from keymap: + if keymap[key_event.key_number][0] is axis_states[0]: + state = axis_states[0] + kbd.press(*keymap[key_event.key_number][1]) + # ..and it's key 9, set state to x + if keymap[key_event.key_number][0] is axis_states[1]: + state = axis_states[1] + pixels[key_to_pixel_map(10)] = OFF + pixels[key_to_pixel_map(11)] = OFF + # ..and it's key 10, set state to y + if keymap[key_event.key_number][0] is axis_states[2]: + state = axis_states[2] + pixels[key_to_pixel_map(9)] = OFF + pixels[key_to_pixel_map(11)] = OFF + # ..and it's key 11, set state to z + if keymap[key_event.key_number][0] is axis_states[3]: + state = axis_states[3] + pixels[key_to_pixel_map(9)] = OFF + pixels[key_to_pixel_map(10)] = OFF + # turn on neopixel for key with color from keymap + pixels[key_to_pixel_map(key_event.key_number)] = keymap[key_event.key_number][2] + # ..and it's released.. + if key_event.released: + # if it's key 0-8, release the key press and turn off neopixel + if keymap[key_event.key_number][0] is axis_states[0]: + kbd.release(*keymap[key_event.key_number][1]) + pixels.fill(OFF)