Thanks to visit codestin.com
Credit goes to github.com

Skip to content

WIP: examples/bluetooth: Add BLE HID mouse and keyboard examples. #6559

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

dpgeorge
Copy link
Member

This PR adds simple BLE HID mouse and keyboard examples. It is work-in-progress, the examples work with an Android phone (tested with PYBD-SF6) but may not work with other devices.

Copy link
Member

@jimmo jimmo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This has been on my TODO list for a long time :)

b"\x09\x09MP-mouse" # complete local name
)
conn_handle = None
ble.gap_advertise(100_000, adv)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import ble_advertising
_ADV_APPEARANCE_MOUSE = const(962)
adv = ble_advertising.advertising_payload(services=[UUID(0x1812)], appearance=_ADV_APPEARANCE_MOUSE, name="MP-mouse")

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kind of wanted this example to be raw and just use the bluetooth module as-is, without any helpers. As a way to show exactly what's needed to make a BLE HID, to show there's no complexity hiding anywhere. IMO that's valuable for learning about BLE (and HID). That's also why I added mouse and keyboard as separate but very similar files.

So maybe we can have a "raw" example (perhaps just mouse, it's simpler) and then a more "friendly" version which has both keyboard and mouse support (selectable via some option).

And then eventually also a proper (async) HID library, but that's for the future.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, sounds good!

b"\x0c\x09MP-keyboard" # complete local name
)
conn_handle = None
ble.gap_advertise(100_000, adv)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import ble_advertising
_ADV_APPEARANCE_KEYBOARD = const(961)
adv = ble_advertising.advertising_payload(services=[UUID(0x1812)], appearance=_ADV_APPEARANCE_KEYBOARD, name="MP-keyboard")



def send_mouse(button_mask, x, y, wheel):
ble.gatts_notify(conn_handle, h_rep, struct.pack("4B", button_mask, x, y, wheel))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if conn_handle is not None


def ble_irq(event, data):
global conn_handle
if event == 1:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
if event == _IRQ_CENTRAL_CONNECT:
    print("connect")
    conn_handle, _, _ = data
elif event == _IRQ_CENTRAL_DISCONNECT:
    conn_handle = None

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another suggestion would be to start again advertising upon disconnect.

def advertise():
    global conn_handle
    conn_handle = None
    adv = (
        b"\x02\x01\x06"
        b"\x03\x03\x12\x18"  # complete list of 16-bit service UUIDs: 0x1812
        b"\x03\x19\xc2\x03"  # appearance: mouse
        b"\x09\x09MP-mouse"  # complete local name
    )
    ble.gap_advertise(100_000, adv)

Create global variable conn_handle and call advertise() here (in disconnect) in addition to calling it after registering the service. Thanks for this example, it was exactly what I needed to get myself started!

@dmazzella
Copy link
Contributor

from HOGP_SPEC_V10.pdf - Table 3.1: HID Device Service Requirements

HID Service M
Battery Service M
Device Information Service M

Both Bonding and encryption are Mandatory.

These are required for ios and for windows.

@dmwyatt
Copy link

dmwyatt commented Dec 31, 2021

What about this is still a WIP?

tannewt pushed a commit to tannewt/circuitpython that referenced this pull request Jul 11, 2022
tannewt added a commit to tannewt/circuitpython that referenced this pull request Jul 11, 2022
@dpgeorge dpgeorge added the examples Relates to examples/ directory in source label Aug 10, 2023
@liangfyx
Copy link

Hello, I tried to use "ble_hid_keyboard.py" to create a Bluetooth keyboard, but windows shows a driver error when it is connected to the Bluetooth keyboard.
Micropython firmware version: 1.2.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
examples Relates to examples/ directory in source
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants