Last active
January 10, 2023 17:01
-
-
Save dglaude/c8634309c6bdfb29e33208b3f248d22b to your computer and use it in GitHub Desktop.
Circuit Python USB Host + Keyboard mirroring to USB and BLE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
This example acts as a BLE HID keyboard to peer devices. | |
It get's keycode from UART RX. | |
Color indication: | |
* BLUE_LED is blinking when not connected and steady blue when connected | |
* NEOPIXEL alternate between RED / GREEN / BLUE every time a keycode is transmitted (up and down event) | |
""" | |
import time | |
import board | |
#from digitalio import DigitalInOut, Direction | |
import digitalio | |
import busio | |
import usb_hid | |
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 | |
from adafruit_hid.keyboard import Keyboard | |
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS | |
from adafruit_hid.keycode import Keycode | |
import neopixel | |
# setup for LED to indicate BLE connection | |
blue_led = digitalio.DigitalInOut(board.BLUE_LED) | |
blue_led.direction = digitalio.Direction.OUTPUT | |
# Define the one NeoPixel on nRF52 | |
pixels = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.3, auto_write=True) | |
color_a = 255 | |
color_b = 0 | |
color_c = 0 | |
STX=0x02 | |
ETX=0x03 | |
uart = busio.UART(board.TX, board.RX, baudrate=115200) | |
hid = HIDService() | |
device_info = DeviceInfoService(software_revision=adafruit_ble.__version__, | |
manufacturer="Adafruit Industries") | |
advertisement = ProvideServicesAdvertisement(hid) | |
advertisement.appearance = 961 | |
scan_response = Advertisement() | |
scan_response.complete_name = "CircuitPython HID" | |
ble = adafruit_ble.BLERadio() | |
if not ble.connected: | |
print("advertising") | |
ble.start_advertising(advertisement, scan_response) | |
else: | |
print("already connected") | |
print(ble.connections) | |
keyboard = Keyboard(hid.devices) | |
keyboard_layout = KeyboardLayoutUS(keyboard) | |
while True: | |
while not ble.connected: | |
time.sleep(0.2) | |
blue_led.value = not blue_led.value | |
pixels.fill((0, 0, 0)) | |
print("Start typing:") | |
while ble.connected: | |
blue_led.value = True | |
data = uart.read(11) | |
if data is not None: | |
if (len(data) == 11) and (data[0] == STX) and (data[1] == 0x08) and (data[10] == ETX): | |
keyboard.report=bytearray(data[2:10]) | |
keyboard.send() | |
pixels.fill((color_a, color_b, color_c)) | |
color_a, color_b, color_c = (color_c, color_a, color_b) | |
print(data[2:10]) | |
elif len(data)>0: | |
# Scan for STX ... ETX to resync | |
print(data) | |
report = bytearray(11) | |
for i in range(0, len(data)): | |
if data[i] == STX: | |
report = data[i:len(data)] + uart.read(11-(len(data)-i)) | |
print(report) | |
if (len(report) == 11) and (report[0] == STX) and (report[1] == 0x08) and (report[10] == ETX): | |
keyboard.report=bytearray(report[2:10]) | |
keyboard.send() | |
ble.start_advertising(advertisement) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Demo: | |
A USB keyboard is connected (via USB OTG cable) to a Trinked M0. | |
Trinked run KBDADVUARTUSBH: Keyboard Advanced UART USB Host: | |
https://github.com/gdsports/usbhostcopro/tree/master/KBDADVUARTUSBH | |
The Trinked send it via UART TX to the UART RX of a nRF52840. | |
Every keyboard HID code is transmitted over USB and BLE simultaneously. | |
""" | |
import time | |
import board | |
from digitalio import DigitalInOut, Direction | |
import busio | |
import usb_hid | |
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 | |
from adafruit_hid.keyboard import Keyboard | |
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS | |
from adafruit_hid.keycode import Keycode | |
STX=0x02 | |
ETX=0x03 | |
uart = busio.UART(board.TX, board.RX, baudrate=115200) | |
hid = HIDService() | |
device_info = DeviceInfoService(software_revision=adafruit_ble.__version__, | |
manufacturer="Adafruit Industries") | |
advertisement = ProvideServicesAdvertisement(hid) | |
advertisement.appearance = 961 | |
scan_response = Advertisement() | |
scan_response.complete_name = "CircuitPython HID" | |
ble = adafruit_ble.BLERadio() | |
if not ble.connected: | |
print("advertising") | |
ble.start_advertising(advertisement, scan_response) | |
else: | |
print("already connected") | |
print(ble.connections) | |
keyboard = Keyboard(hid.devices) | |
keyboard_layout = KeyboardLayoutUS(keyboard) | |
usb_keyboard = Keyboard(usb_hid.devices) | |
usb_keyboard_layout = KeyboardLayoutUS(usb_keyboard) | |
while True: | |
while not ble.connected: | |
pass | |
print("Start typing:") | |
while ble.connected: | |
data = uart.read(11) | |
if data is not None: | |
if (len(data) == 11) and (data[0] == STX) and (data[1] == 0x08) and (data[10] == ETX): | |
keyboard.report=bytearray(data[2:10]) | |
keyboard.send() | |
usb_keyboard.report=bytearray(data[2:10]) | |
usb_keyboard.send() | |
print(data[2:10]) | |
elif len(data)>0: | |
# Scan for STX ... ETX to resync | |
print(data) | |
report = bytearray(11) | |
for i in range(0, len(data)): | |
if data[i] == STX: | |
report = data[i:len(data)] + uart.read(11-(len(data)-i)) | |
print(report) | |
if (len(report) == 11) and (report[0] == STX) and (report[1] == 0x08) and (report[10] == ETX): | |
keyboard.report=bytearray(report[2:10]) | |
keyboard.send() | |
usb_keyboard.report=bytearray(report[2:10]) | |
usb_keyboard.send() | |
ble.start_advertising(advertisement) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Added a BLE only version, that use the BLUE_LED and NEOPIXEL to indicate the status.
BLUE_LED blinking = not connected
BLUE_LED steady = connected
NEOPIXEL change color everytime a key is transmitted, both for up and down event
This can work standalone and the status is visible.