Git Product home page Git Product logo

adafruit_circuitpython_hid's Introduction

Introduction

Documentation Status Discord Build Status Code Style: Black

This driver simulates USB HID devices. Currently keyboard and mouse are implemented.

Dependencies

This driver depends on:

Please ensure all dependencies are available on the CircuitPython filesystem. This is easily achieved by downloading the Adafruit library and driver bundle.

Additional Layouts

This library has an en-US layout. Please check out and expand the library from Neradoc for additional layouts.

Usage Example

The Keyboard class sends keypress reports for a USB keyboard device to the host.

The Keycode class defines USB HID keycodes to send using Keyboard.

import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode

# Set up a keyboard device.
kbd = Keyboard(usb_hid.devices)

# Type lowercase 'a'. Presses the 'a' key and releases it.
kbd.send(Keycode.A)

# Type capital 'A'.
kbd.send(Keycode.SHIFT, Keycode.A)

# Type control-x.
kbd.send(Keycode.CONTROL, Keycode.X)

# You can also control press and release actions separately.
kbd.press(Keycode.CONTROL, Keycode.X)
kbd.release_all()

# Press and hold the shifted '1' key to get '!' (exclamation mark).
kbd.press(Keycode.SHIFT, Keycode.ONE)
# Release the ONE key and send another report.
kbd.release(Keycode.ONE)
# Press shifted '2' to get '@'.
kbd.press(Keycode.TWO)
# Release all keys.
kbd.release_all()

The KeyboardLayoutUS sends ASCII characters using keypresses. It assumes the host is set to accept keypresses from a US keyboard.

If the host is expecting a non-US keyboard, the character to key mapping provided by KeyboardLayoutUS will not always be correct. Different keypresses will be needed in some cases. For instance, to type an 'A' on a French keyboard (AZERTY instead of QWERTY), Keycode.Q should be pressed.

Currently this package provides only KeyboardLayoutUS. More KeyboardLayout classes could be added to handle non-US keyboards and the different input methods provided by various operating systems.

import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS

kbd = Keyboard(usb_hid.devices)
layout = KeyboardLayoutUS(kbd)

# Type 'abc' followed by Enter (a newline).
layout.write('abc\n')

# Get the keycodes needed to type a '$'.
# The method will return (Keycode.SHIFT, Keycode.FOUR).
keycodes = layout.keycodes('$')

The Mouse class simulates a three-button mouse with a scroll wheel.

import usb_hid
from adafruit_hid.mouse import Mouse

m = Mouse(usb_hid.devices)

# Click the left mouse button.
m.click(Mouse.LEFT_BUTTON)

# Move the mouse diagonally to the upper left.
m.move(-100, -100, 0)

# Roll the mouse wheel away from the user one unit.
# Amount scrolled depends on the host.
m.move(0, 0, -1)

# Keyword arguments may also be used. Omitted arguments default to 0.
m.move(x=-100, y=-100)
m.move(wheel=-1)

# Move the mouse while holding down the left button. (click-drag).
m.press(Mouse.LEFT_BUTTON)
m.move(x=50, y=20)
m.release_all()       # or m.release(Mouse.LEFT_BUTTON)

The ConsumerControl class emulates consumer control devices such as remote controls, or the multimedia keys on certain keyboards.

import usb_hid
from adafruit_hid.consumer_control import ConsumerControl
from adafruit_hid.consumer_control_code import ConsumerControlCode

cc = ConsumerControl(usb_hid.devices)

# Raise volume.
cc.send(ConsumerControlCode.VOLUME_INCREMENT)

# Pause or resume playback.
cc.send(ConsumerControlCode.PLAY_PAUSE)

Documentation

API documentation for this library can be found on Read the Docs.

For information on building library documentation, please check out this guide.

Contributing

Contributions are welcome! Please read our Code of Conduct before contributing to help this project stay welcoming.

adafruit_circuitpython_hid's People

Contributors

andreblue avatar brennen avatar careyk007 avatar caternuson avatar dhalbert avatar evaherrada avatar foamyguy avatar jedgarpark avatar jepler avatar jfurcean avatar jpecor avatar jpewdev avatar kattni avatar ladyada avatar larsks avatar michalpokusa avatar mrmcwethy avatar neradoc avatar pythonmcpi avatar schlafa avatar schneider42 avatar siddacious avatar sigafoos avatar sommersoft avatar tannewt avatar tekktrik avatar zzsnzmn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adafruit_circuitpython_hid's Issues

ImportError: no module named '__future__'

Hi, I'm getting the following error when trying to follow the MacroPad Basics tutorial:

code.py output:
Traceback (most recent call last):
  File "code.py", line 9, in <module>
  File "adafruit_macropad.py", line 62, in <module>
  File "adafruit_hid/__init__.py", line 21, in <module>
ImportError: no module named '__future__'

I've tried both the v7 and v8 files, and I get the same result both times.

I copied the files onto the board as instructed

Mouse not recognized on iPad

I created a test sketch that works with Windows, Linux and Mac. When plugging into an iPad nothing happens. No cursor is shown on the screen.

Here is the sample code for testing:

import time
import usb_hid 
from adafruit_hid.mouse import Mouse
import board
import digitalio

time.sleep(.5)
mouse = Mouse(usb_hid.devices)
time.sleep(.5)

led = digitalio.DigitalInOut(board.GP25)
led.direction = digitalio.Direction.OUTPUT

count = 0

while True:
    time.sleep(5)

    led.value = False
    time.sleep(.01)
    led.value = True
    while count<200:
        mouse.move(y=-5)
        mouse.move(x=-5)
        time.sleep(.01)
        count = count + 1
    count = 0
    while count<200:
        mouse.move(y=5)
        mouse.move(x=-5)
        time.sleep(.01)
        count = count + 1
    count = 0
    while count<200:
        mouse.move(y=5)
        mouse.move(x=5)
        time.sleep(.01)
        count = count + 1
    count = 0
    while count<200:
        mouse.move(y=-5)
        mouse.move(x=5)
        time.sleep(.01)
        count = count + 1
    count = 0

Board / Firmware:
Adafruit CircuitPython 6.2.0-beta.2 on 2021-02-11; Raspberry Pi Pico with rp2040

Doesn't work on gemma m0

works on feather m0 express but not gemma m0

Adafruit CircuitPython 1.0.0-rc.3-dirty on 2017-07-01; Adafruit Gemma M0 with samd21e18

from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
import time

kbd = Keyboard()
kbd.press(Keycode.A)
time.sleep(0.1)
kbd.release_all()

no errors - just no keypress

.send() and .write() behavior on Windows vs Pi OS

I ran into problems when using the Capacitive Touch HID on the Pi4. The problem boils down to the following: code utilizing the .send() and .write() functions (on e.g. the NeoTrinkey) work perfectly well on my Windows machine (they send and write keyboard commands as they are supposed to), but neither send nor write anything when connected to a Raspberry Pi 4 running the most recent Pi OS.

I already posted the issue on the Adafruit forum, where a more detailed discussion of the topic can be found:
https://forums.adafruit.com/viewtopic.php?f=52&t=180124&p=877286#p877286

Control the speed of layout.write()?

Is there a way to controll the speed of layout.write(), so that it runs faster? or is there a way to improve the speed of circuitpython on my rasperrypi pico?

I want to do a VS Code Keyboard, which runs things like:

while True:
    led.value = False
    if button.value:
        kbd.send(Keycode.COMMAND, Keycode.SHIFT, Keycode.P)
        # layout.write("Transform to Uppercase\n")
        layout.write("Uppercase\n")
        kbd.release_all()
        led.value = True
    time.sleep(0.2)

But it's reacting slow, or with a delay.

Implement HID LampArray Support

The new Dynamic Lighting feature in Windows 11 was just released. It uses a new standard called HID LampArray. This open standard aims to improve the overall lighting ecosystem for PC peripheral devices. Implementing this new standard into the current HID library would make it much easier to experiment with this new feature. My personal assumption is that almost all CircuitPython HID projects implement some form of RGB LEDs. For example, the Adafruit MacroPad implements many RGB LEDs, and this feature would be particularly useful.

Microsoft Support - Control your Dynamic Lighting devices in Windows

Microsoft Learn - Dynamic Lighting Devices

USB.org - HID Usage Tables for Universal Serial Bus (USB) Version 1.4

`find_device` module missing in `adafruit_hid.keyboard.Keyboard`

from . import find_device

Doesn't the line from . import find_device in adafruit_hid.keyboard.Keyboard.py expect that there is a find_device submodule in the adafruit_hid library hierarchy? Or am I missing something about importing Adafruit libraries. I am only trying to execute the code.py on an Adafruit Metro M4 Express board with updated bootloader and CircuitPython.

Support for zoom in/out

I'm not even sure if this is a valid HID thing or if i.e. wireless touchpads do it some other way, but I'd love zooming support like pinch-to-zoom, but via some non-multitouch input. If anyone coming across this issue has any idea how to implement that, or an example like an open source mouse firmware or something, please do let me know.

Consumer Control not working

I'm trying to use consumer controls with pushbuttons
but I'm not getting anything.

I've tried the pushbutton with macros and it worked.

import time
import usb_hid
from adafruit_hid.keycode import Keycode
from adafruit_hid.keyboard import Keyboard
import board
import digitalio
from adafruit_hid.consumer_control import ConsumerControl
from adafruit_hid.consumer_control_code import ConsumerControlCode

> btn1_pin = board.GP9

> btn1 = digitalio.DigitalInOut(btn1_pin)
btn1.direction = digitalio.Direction.INPUT
btn1.pull = digitalio.Pull.DOWN

while True:

    if btn1.value:
        keyboard.send[[ConsumerControlCode.PLAY_PAUSE]]
        time.sleep(0.1)

QT Py M0 Haxpress hangs when using HID Library

Program hangs when using the adafruit_hid library on the QT Py M0 Haxpress. I could not replicate the issue on either the plain QT Py M0 or the Feather M4 Express. See the below example code. The mouse moves for a few seconds and then hangs. This issue occurs when the reset button is press or the board is unplugged and plugged back in. It does not occur when code.py is saved to the board.

import time
import usb_hid
from adafruit_hid.mouse import Mouse

m = Mouse(usb_hid.devices)

while True:
    m.move(10, 0, 0)
    time.sleep(.05)
    m.move(-10,0,0)
    time.sleep(.05)

The issue was originally raised in adafruit_nunchuk library: adafruit/Adafruit_CircuitPython_Nunchuk#22

Edit: this occurs on MacOS and couldn't be duplicated on Linux or Windows.

Control Codes in keyboard_layout_us not supported

Is there a reason that control codes besides LF (\n) are zeroed out in keyboard_layout_us.py?

For example, changing b"\x00" # CR \r to b"\xa8" # CR \r on line 48 allows \r to be used instead of \n

Now \r can be used to to send ascii art to a chat without breaking every line into separate messages:

ascii_art2 = \
"```           ___\r"\
"     |     | |\r"\
"    / \    | |\r"\
"   |--o|===|-|\r"\
"   |---|   | |\r"\
"  /     \  | |\r"\
" |       | | |\r"\
" |       |=| |\r"\
" |       | | |\r"\
" |_______| |_|\r"\
"  |@| |@|  | |\r"\
"___________|_|_\r```"\

The result:
image

Not connecting USB to host causes either hang or crash

I am writing a script that needs to run when the computer first turns on. When it is still turning on sometimes there is a large delay between when power is given to the board and when the USB controller in the computer wakes up. I am using the keyboard module and mouse module. When I was running circuitpython on my neotrinkey, and the computer was taking longer then normal to turn on, it would start flashing some code. I do not have a second pico to debug on.
This is a pretty niche use case but it also will happen if you just connect your pico to power and no data.
Maybe there is a way to tell when the host is ready to accept connection or throw an error if it is not ready?
That way you can just loop the connect command or return a message if there is no host device.

Pico keyboard is not "quite" a real keyboard?

I build a external keyboard with a Pico and the adafruit hid.

Using Win 10. It works well in the focussed app. BUT only sends(?) to foreground apps. I discovered this in OBS Studio, I can teach in the keystrokes my little Pico-Keyboard sends to OBS in the Hotkey section. And they work. The DO not work when I focus the App I want to record in OBS.

A test with a second just plain normal USB keyboard does not show that! So It seems the Pico-HID is some different kind. Maybe a security Reason? (e.g. if you make a malicious USB dongle which types in bad commands?)

Use proper signed/unsigned designations in `struct` format strings

from @ATMakersBill (part of adafruit/circuitpython#1451)

As we were trying to track down a problem w/the gamepad HID interface (or more likely the Microsoft XAC's implementation) @dhalbert and I saw that the format strings for pack_into() were not taking into consideration whether the variable was signed. For example in gamepad.py you'll find:

    struct.pack_into('<HBBBB', self._report, 0,
                     self._buttons_state,
                     self._joy_x, self._joy_y,
                     self._joy_z, self._joy_r_z)

The "<HBBBB" string says that it's expecting an unsigned 16-bit value followed by four unsigned bytes. However, we are sending signed bytes (-127 through 127) as defined in our descriptor.

In this case, circruitpython doesn't care because it would encode them the same way. However, CPython would error out after checking this and in general this is dangerous, because with types > 8 bit, we very much do care about endianness.

@dhalbert asked that I open an issue about this. The fix on gamepad.py is pretty simple, just change the string to "<Hbbbb", however, we should probably do a sanity check on this.

Pico + keyboard + output to monochrome 20x4 LCD?

*** Newbie alert ***

Would this library allow me to connect a keyboard and LCD to my Pico to create a word processor?

The whole thing would be battery powered. Something like an Alphasmart is what I'm thinking of.

CAPSLOCK LED wont work

My Code:

import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode

keyboard = Keyboard(usb_hid.devices)
keyboard_layout = KeyboardLayoutUS(keyboard)  # We're in the US :)


print(keyboard.led_on(0x02))

The Ouput:

Traceback (most recent call last):
  File "code.py", line 14, in <module>
AttributeError: 'Keyboard' object has no attribute 'led_on'

I think Keyboard has an attribute for led_on.

USB Keyboard no longer sends keystrokes after windows machine go to sleep

Issue is occurring with a RPi Pico running the most up to date circuit python, and hid library. The issue does not occur on mac machines (haven't tested linux) A power cycle of the RPi resolves the issue, however, unplugging and replugging my macro pad every time my pc goes to sleep is getting a little annoying.

I'm not really sure why this happens. I imagine it has to do with how windows handles "sleep" mode, probably still powering the device in some way, and somehow this messes with the device recognition, whereas mac probably just powers off the usb device? I'm not entirely sure..

In order to replicate this it's pretty simple:

  • Put circuitpython on a rpi pico
  • Put keyboard code device
  • Ensure the board works as expected
  • Put windows machine to sleep
  • Wake windows machine
  • Notice keyboard no longer sends keypresses

It could very well be sending the key presses, but windows isn't recognizing them. I have no idea, and I haven't been able to see anything about it online.

support for 16bit values in the gamepad module

My jstest command on Linux shows 16bits values for signed 8bit values sent from the gamepad.py module; would it be possible to send 16bit values? I need a better resolution for my project...

USB HID Button Page (0x9) support...

Adafruit has many wonderful button options: the trellis, the new pico one, the RGB Cherry MX switch board. While some folks might want to output as a keyboard, I think it would great to encourage more "plug and play" of these devices to support the Button page class. It supports like 250+ buttons!

HID devices not ready when main.py starts

On some hosts (reported on a Windows 10 machine), main.py can start before the HID devices are ready on the host side. Examples:
https://forums.adafruit.com/viewtopic.php?f=52&t=125560#p629406
https://forums.adafruit.com/viewtopic.php?f=52&t=130143
Also reported in Discord (thanks @PhunkMaster)

I added time.sleep(1) to some of the HID examples (e.g., https://learn.adafruit.com/adafruit-circuit-playground-express?view=all#circuitpython-hid-keyboard), but this should really be handled in the library or possibly in the native implementation. The creation operations like Mouse() and Keyboard() could sleep and retry after failure, possibly just once.

Keyboard press delay

Hello, I would like to thank you for this awesome library. To start with hardware-wise, I am using a raspberry pi zero wireless (Rev 1.1), running raspbian bullseye. I'm having an issue with keyboard_layout_us.write events happening so fast that they do not register 100 percent of the time, on the host machine. Normally the correct keycode will register, but the leading shift will be missed quite often. Instead of ^ keypess, you might get a 6 keypress. I'm using a US layout, so, it's basically only using shift key. While it doesn't occur as often on the current host machine, when connecting to a remote desktop session, or a remote desktop session in another remote desktop session, this happen very often. I can fix this issue by adding delays in the keyboard_layout_base.py _write function, after each of the press events. It would be nice to some have way to add in custom delay into the actual press command, at the keyboard.py level, which can be set on initialization. In my instance a 0.02 second delay has been enough to fix this issue, but I would expect this to be different for different hardware. I'm using this more as a password paste application, so this is more extreme then most other typing examples, as shift key is pressed or not pressed, nearly half the time for the next key. Thanks -Justin

Here is a example of sending the same string 10 times, with no modifications to this library. Correct is first line, the next 10 are showing 10 concurrent paste on a host. These are not me picking 10 bad ones out of 100 or 1000. These are just 10 concurrent keyboard_layout_us.write results.

keyboard_layout_us.write('MUnykeL!12I$HXVcRHdtaS^YkQIhU')
MUnykeL!12I$HXVcRHdtaS^YkQIhU

MUnykeL112i$HXvcrhdtaS^YkQihU
MUnykeL!12i$HXVcRHdtas6ykqihU
MUnykel!12i4HXVcrhdtas^YkQIhU
mUnykeL!12I$HxvcrHdtas^ykqIhu
munykeL!12i$hXVcRHdtas^ykqihu
munykeL!12I$HxVcRHdtaS6YkqIhU
Munykel112i$hXVcRHdtaS^YkqIhU
munykeL!12i$HXVcrhdtas6ykqihU
MUnykel112I$HxvcRHdtaS6YkqIhu
mUnykel112I$HXVcRhdtaS^YkQihu

Same machine, but with a (import time) time.sleep(0.20) added after each keyboard.press event on keyboard_layout_base.py _write function

keyboard_layout_us.write('MUnykeL!12I$HXVcRHdtaS^YkQIhU')
MUnykeL!12I$HXVcRHdtaS^YkQIhU

MUnykeL!12I$HXVcRHdtaS^YkQIhU
MUnykeL!12I$HXVcRHdtaS^YkQIhU
MUnykeL!12I$HXVcRHdtaS^YkQIhU
MUnykeL!12I$HXVcRHdtaS^YkQIhU
MUnykeL!12I$HXVcRHdtaS^YkQIhU
MUnykeL!12I$HXVcRHdtaS^YkQIhU
MUnykeL!12I$HXVcRHdtaS^YkQIhU
MUnykeL!12I$HXVcRHdtaS^YkQIhU
MUnykeL!12I$HXVcRHdtaS^YkQIhU
MUnykeL!12I$HXVcRHdtaS^YkQIhU

Add shuffle mode

Would it be possible to add shuffle to the available options?

I assume it's the RANDOM_PLAY function from the HID Usages and Descriptions document, so it would probably look like this (?):

RANDOM_PLAY = 0xB9 """Shuffle"""

Thanks!

Fix gamepad examples

gamepad.py is no longer in the base library, because the gamepad device was removed from CircuitPython 7.0.0.

  • Rename examples/gamepad.py to examples/hid_gamepad.py or similar, because gamepad.py overlaps with the gamepad built-in module.
  • Fix or remove the gamepad-based examples.
  • Add documentation about how to add a gamepad device to CircuitPython 7.0.0, or refer to a guide.

Does not load on Gemma M0?

I have a Gemma M0. I was attemping to follow through https://learn.adafruit.com/adafruit-gemma-m0/circuitpython-hid-keyboard-and-mouse, which claims to , but trying to from adafruit_hid.keyboard import Keyboard results in a memory allocation failure:

Adafruit CircuitPython 5.0.0 on 2020-03-02; Adafruit Gemma M0 with samd21e18
>>> from adafruit_hid.keyboard import Keyboard
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/lib/adafruit_hid/Keyboard.py", line 34, in <module>
MemoryError: memory allocation failed, allocating 832 bytes
>>> 

This is after a fresh boot, with nothing else loaded.

Is the adafruit_hid module expected to load on a Gemma M0? The article certainly seems to think so, but I'm not sure how to work around this error.

Possible error in Mouse movement library.

#yields only behavior in positive direction

VAR1 = -10
VAR2 = 10

def up():
    mouse.move(y=VAR1)
    time.sleep(1)

def down():
    mouse.move(y=VAR2)
    time.sleep(1)
#yields behavior in both directions

VAR1 = -10
VAR2 = 10

def up():
    mouse.move(y=-VAR1)
    time.sleep(1)

def down():
    mouse.move(y=VAR2)
    time.sleep(1)

Why?

RawHID support

Something that would be very helpful in communicating with computer side frameworks as an alternative to VCP would be the possiblity to have a RawHID class.
My understanding of USB is not too in-depth but afaik this would just mean a new descriptor that allows for a report of the maximum possible size to send buffers back and forth.

Right now I can already do this with the existing classes, I'm just limited to very few bytes per transaction and can't receive something back.
F.e. with the consumer key device:

import usb_hid

value = 4024
code = bytearray(2)
bytes = value.to_bytes(2,'big')
for device in usb_hid.devices:
            if device.usage_page == 0x0C and device.usage == 0x01:
                print('found consumer device')
                myDevice = device
                break
device.send_report(bytes)

I found this in the mpy docs but apart from this lonely docs page not much more and the pyb module does not seem to exist in CPY.

BLE Keyboard Functionality Issue on EFR32xG24 Explorer Kit

CircuitPython version

Adafruit CircuitPython 9.0.0-alpha.6 on 2023-12-12; SiLabs xG24 Explorer Kit with EFR32MG24B210F1536IM48

board
EFR32xG24 Explorer Kit

adafruit_hid version

>>> adafruit_hid.__version__
'6.0.3'

Code/REPL

# SPDX-FileCopyrightText: 2020 John Park for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
This example acts as a BLE HID keyboard to peer devices.
Attach five buttons with pullup resistors to Feather nRF52840
  each button will send a configurable keycode to mobile device or computer
"""
import time
import board
from digitalio import DigitalInOut, Direction

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

button_1 = DigitalInOut(board.PB2)
button_2 = DigitalInOut(board.PB3)
button_3 = DigitalInOut(board.PD2)
button_4 = DigitalInOut(board.PD3)
button_5 = DigitalInOut(board.PC9)

button_1.direction = Direction.INPUT
button_2.direction = Direction.INPUT
button_3.direction = Direction.INPUT
button_4.direction = Direction.INPUT
button_5.direction = Direction.INPUT

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)

k = Keyboard(hid.devices)
kl = KeyboardLayoutUS(k)
while True:
    while not ble.connected:
        pass
    print("Start typing:")

    while ble.connected:
        if not button_1.value:  # pull up logic means button low when pressed
            print("button_1: back")  # for debug in REPL
            k.send(Keycode.BACKSPACE)
            time.sleep(0.1)

        if not button_2.value:
            print("button_2: Bluefruit")
            kl.write("Bluefruit")  # use keyboard_layout for words
            time.sleep(0.4)

        if False and not button_3.value:
            k.send(Keycode.SHIFT, Keycode.L)  # add shift modifier
            time.sleep(0.4)

        if False and not button_4.value:
            kl.write("e")
            time.sleep(0.4)

        if False and not button_5.value:
            k.send(Keycode.ENTER)
            time.sleep(0.4)

    ble.start_advertising(advertisement)

Behavior
After connecting the Bluetooth HID device to my computer , pressing the button again, the program outputs and sends the button information, but the computer does not receive the operation.

>>> %Run -c $EDITOR_CONTENT
advertising
Start typing:
button_1: back
button_1: back
button_2: Bluefruit
button_2: Bluefruit
button_1: back
button_1: back

Description
I want to implement the EFR32xG24 Explorer Kit as a Bluetooth HID device, sending corresponding keyboard events to connected devices (computers or phones) through buttons.
I have successfully started the BLE UART service on this board and completed communication tests with the application on the phone.
However, the corresponding circuitpython for this board does not have a built-in usb-hid module.Thus, the above error occurred.
I want to know if there is a way to bypass usb-hid?

Additional information
I also noticed #121 and https://github.com/adafruit/Adafruit_CircuitPython_HID/releases/tag/6.0.2.
But no solution was found.

Greater mouse movement

Currently the mouse movement is limited to -127 to +127. Many screens are thousands of pixels long. Is this an artificial limit?

I Need Help With Swedish Layout

Hi im trying to get this Payload working but i cant get this symbol () on the Swedish keyboard To work and i can't do this string (STRING %USERPROFILE%\hotdog.jpg)
i have come up with a seclusion but i still cant get this \

Examples using the keypad module for a keyboard and macros

We could use [an] example[s] that uses the keypad module for a keyboard, and shortcuts or macros.
Mention to @kattni as promised.

Possibly showing concepts like:

  • use event.pressed to trigger a keyboard send or a layout write.
  • use pressed/released to hold a key while the button is down (like a real keyboard).

Maybe more advanced:

  • use a state variable to toggle a key on/off on button press. (That question comes up from time to time).

usb_hid behaviour at boot..

CircuitPython version

Adafruit CircuitPython 8.0.5 on 2023-03-31; Raspberry Pi Pico with rp2040

Code/REPL

import usb_midi
import usb_cdc
import usb_hid
import storage

usb_cdc.disable()   # Disable both serial devices.
usb_midi.disable()  # Disable mini
usb_hid.enable((usb_hid.Device.KEYBOARD, usb_hid.Device.CONSUMER_CONTROL))   # Enable just KEYBOARD and CONSUMER CONTROL

Behavior

...

Description

I have a project using circuitpython to provide a usb HID device (keyboard), however come up with some strange operating behaviour.

When connect a linux host (raspbian rpi4) at boot, the device is detected however doesnt function as a keyboard. Removing the usb connection and replugging back in, the device works as expected.

If I automount the CIRCUITPY disk at boot, then the device will work as expected also.

Is there a way to have this device function as expected without having to mount the usb-storage device?

dmesg output from boot

[    2.745421] usb 1-1.4: new full-speed USB device number 5 using xhci_hcd
[    2.892517] usb 1-1.4: New USB device found, idVendor=239a, idProduct=80f4, bcdDevice= 1.00
[    2.892543] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[    2.892561] usb 1-1.4: Product: Pico
[    2.892578] usb 1-1.4: Manufacturer: Raspberry Pi
[    2.892594] usb 1-1.4: SerialNumber: E66118C4173BBA26
[    2.900386] usb-storage 1-1.4:1.0: USB Mass Storage device detected
[    2.901230] scsi host0: usb-storage 1-1.4:1.0
[    2.910112] input: Raspberry Pi Pico Keyboard as /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.4/1-1.4:1.1/0003:239A:80F4.0003/input/input2
[    2.976415] input: Raspberry Pi Pico Consumer Control as /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.4/1-1.4:1.1/0003:239A:80F4.0003/input/input3

Additional information

No response

Gamecontroller setup under mac

I am using https://learn.adafruit.com/gamepad-qt with https://learn.adafruit.com/esp32-s3-reverse-tft-feather.

My goal is to let the gamepad be recognized as gamecontroller input on my Mac to play a game with it.
I have looked at the gamepad example here: https://docs.circuitpython.org/projects/hid/en/latest/examples.html#id4
and added the gamepad boiler plate code shown here: https://learn.adafruit.com/customizing-usb-devices-in-circuitpython/hid-devices#custom-hid-devices-3096614-9 to my boot.py.
This doesn't run into any errors, but also does not lead to recognition of a gamecontroller as input device under MacOS.

Has anybody tried this?

adafruit_hid.keyboard.Keyboard.led_on only returns True once only

CircuitPython version

Adafruit CircuitPython 8.0.4 on 2023-03-15; Raspberry Pi Zero W with bcm2835

Code/REPL

import time
import usb_hid
from adafruit_hid.keyboard import Keyboard

kbd = Keyboard(usb_hid.devices)
while True:
    print(kbd.led_on(Keyboard.LED_CAPS_LOCK))
    time.sleep(0.1)

Behavior

adafruit_hid.keyboard.Keyboard.led_on only reports True once and not the whole time the LED is on.

The above code should print out True while caps lock is on and False otherwise. Testing this code in a RPi Pico confirms this behavior. On the RPi Zero though True is only printed once per loop then immediately returns back to False even though the caps lock is still on.

Description

No response

Additional information

No response

Fn Key Support

I'd like to be able to emit the media control key press for macOS, such as pause/play Fn + F7. From my looking through adafruit_hid.keycode and documentation I don't currently believe this is supported but I'd love to see it made available.

Is there a way to receive data? (from the PC it's connected to)

Hi, I'm wondering if it is possible to use this library to instead of only sending data (keypresses) to the connected PC, also receive data from that PC. The scenario I'm thinking about is to use the LED's (or the screen) of the Adafruit Macropad to represent a state, for example:

  • light up a LED when there is an incoming email
  • have a red/green LED representing the busy/available state in Teams, Discord, Slack ...
  • ...

I've been looking into the CircuitPython MIDI library, where it's possible to have IN and OUT data. But I'd prefer to have my Macropad act as a HID instead of a MIDI device.

Btw, I understand that on the PC there will have to be some code running to figure out a state and send the data/command to the Macropad. My question is related to the code on the Macropad itself to make this possible.

Thanks a lot!
Jan

Missing Type Annotations

There are missing type annotations for some functions in this library.

The typing module does not exist on CircuitPython devices so the import needs to be wrapped in try/except to catch the error for missing import. There is an example of how that is done here:

try:
    from typing import List, Tuple
except ImportError:
    pass

Once imported the typing annotations for the argument type(s), and return type(s) can be added to the function signature. Here is an example of a function that has had this done already:

def wrap_text_to_pixels(
    string: str, max_width: int, font=None, indent0: str = "", indent1: str = ""
) -> List[str]:

If you are new to Git or Github we have a guide about contributing to our projects here: https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github

There is also a guide that covers our CI utilities and how to run them locally to ensure they will pass in Github Actions here: https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library/check-your-code In particular the pages: Sharing docs on ReadTheDocs and Check your code with pre-commit contain the tools to install and commands to run locally to run the checks.

If you are attempting to resolve this issue and need help, you can post a comment on this issue and tag both @FoamyGuy and @kattni or reach out to us on Discord: https://adafru.it/discord in the #circuitpython-dev channel.

The following locations are reported by mypy to be missing type annotations:

  • adafruit_hid/keycode.py:302
  • adafruit_hid/__init__.py:26
  • adafruit_hid/mouse.py:26
  • adafruit_hid/mouse.py:50
  • adafruit_hid/mouse.py:67
  • adafruit_hid/mouse.py:81
  • adafruit_hid/mouse.py:99
  • adafruit_hid/mouse.py:145
  • adafruit_hid/keyboard_layout_us.py:166
  • adafruit_hid/keyboard_layout_us.py:179
  • adafruit_hid/keyboard_layout_us.py:200
  • adafruit_hid/keyboard_layout_us.py:225
  • adafruit_hid/keyboard.py:36
  • adafruit_hid/keyboard.py:67
  • adafruit_hid/keyboard.py:93
  • adafruit_hid/keyboard.py:115
  • adafruit_hid/keyboard.py:123
  • adafruit_hid/keyboard.py:144
  • adafruit_hid/keyboard.py:161
  • adafruit_hid/consumer_control.py:28
  • adafruit_hid/consumer_control.py:48
  • adafruit_hid/consumer_control.py:67

Add support for "Pan" or "Horizontal" wheel movement as well as Back/Forward Buttons

Looks like the library doesn't support the full mouse HID report that computers can understand.

The TinyUSB library makes available a few more buttons:
MOUSE_BUTTON_BACKWARD
MOUSE_BUTTON_FORWARD

https://github.com/adafruit/Adafruit_TinyUSB_ArduinoCore/blob/81e146ecf41823046a3c37b7ecaa32276931bb3c/tinyusb/src/class/hid/hid.h#L259

And makes as horizontal (pan) movements available too:

https://github.com/adafruit/Adafruit_TinyUSB_Arduino/blob/master/src/class/hid/hid_device.c#L146

It's not clear if the Circuitpython library supports these buttons and movements but at first glance it doesn't appears to.

BLE Keyboard Functionality Issue

CircuitPython version

Adafruit CircuitPython 8.2.7 and 9.0.0-alpha4; ItsyBitsy NRF52840 Express

Code/REPL

#https://learn.adafruit.com/ble-hid-keyboard-buttons-with-circuitpython/ble-keyboard-buttons-libraries-and-code

import time
import board
from digitalio import DigitalInOut, Direction, Pull
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

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()
k = Keyboard(hid.devices)

# Start Advertising
if not ble.connected:
    ble.start_advertising(advertisement, scan_response)

# Main Loop
while True:    
    k.send(Keycode.Q)        
    time.sleep(0.5)

Behavior

When the ItsyBitsy NRF52840 Express is connected via USB to a PC, BLE keyboard functionality works as expected, allowing the device to send keystrokes to connected devices. However, when powered by a TP4056 module, a 3.7V lipo battery pack, or a USB charger (without data connection), the board will advertise BLE services and can be successfully paired, but it will not send keystrokes.

Description

Encountering an issue with the ItsyBitsy NRF52840 Express where BLE keyboard commands are not transmitted unless the device is connected to a PC via USB. Despite successful BLE service advertisement and pairing with external devices when powered through alternative means (such as a TP4056 module, a 3.7V lipo battery, or a USB charger without data), keystrokes are not sent. This problem persists across different boards and CircuitPython versions.

Additional information

The problem was replicated on other boards: Seeed Studio XIAO nRF52840 Sense and Feather nRF52840 Express.
Bootloaders 0.7.0 and 0.8.0 were tested on all devices.
The issue was confirmed by another Adafruit forum user, who replicated it on their ItsyBitsy NRF52840.
https://forums.adafruit.com/viewtopic.php?t=205776
Original project: https://learn.adafruit.com/ble-hid-keyboard-buttons-with-circuitpython/ble-keyboard-buttons-libraries-and-code

Double key in Discord shortcuts

There is a weird effect that happens in Discord shortcuts when sending a key. (Seen on mac).
A simple kbd.send(Keycode.R) code will cause the shortcut to be recorded as "R + R". Pressing the key with the keyboard gets a normal "R". (With any key tested).
It might be an issue with discord, but the discrepancy between the keyboard and adafruit_hid makes me wonder what is different in CP to cause that. It might very well be a builtin usb_hid issue too.

  • adafruit_hid

bad

  • keyboard

good

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.