Skip to content
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

Examples using the keypad module for a keyboard and macros #108

Open
Neradoc opened this issue Nov 16, 2022 · 6 comments
Open

Examples using the keypad module for a keyboard and macros #108

Neradoc opened this issue Nov 16, 2022 · 6 comments

Comments

@Neradoc
Copy link
Contributor

Neradoc commented Nov 16, 2022

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).
@xgpt
Copy link

xgpt commented Nov 16, 2022

Today I was trying to write a class based around keypad.

Things I specifically needed to implement (that I'm still working on), that I think would be more accurate/easy with keypad vs. digitalio:

utilizing .timestamp and .key_pressed to track when a button is pressed

so creating a variable/object/attribute that tracks when a button is pressed, and when a button is pressed, it marks it as pressed.

I need a way to basically re-implement the following code without getting caught in the while loop, I'd very much so like to do it inside keypad instead of with digitalio.

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

button0=digitalio.DigitalInOut(board.D4)
button1=digitalio.DigitalInOut(board.D5)
button0.switch_to_input(pull=digitalio.Pull.DOWN)
button1.switch_to_input(pull=digitalio.Pull.DOWN)

m = Mouse(usb_hid.devices)

while True:
    if button0.value:
        timestamp=time.monotonic()+0.75
        while button0.value:
            if timestamp>=time.monotonic():
                m.move(0,1,0)
                print('slow')
            else:
                if button0.value:
                    timestamp=time.monotonic()+.75
                    while button0.value:
                        if timestamp>=time.monotonic():
                            m.move(0,3,0)
                            print('medium')
                        else:
                            m.move(0,7,0)
                            print('fast!')

The above is real code (I think , or at the very least test code) that is used by someone who uses a buttons-to-mouse-movement HID device I made with a headpointer. They need to move the mouse slowly at first, but if they need to get all the way across the screen it helps if it moves faster if the button has been held a while. Then they can let up off it, and press it again to regain slow and careful control to zero in on the UI target.

@todbot
Copy link

todbot commented Nov 16, 2022

Hi @xgpt,
Not sure if this is what you're asking for, but here's how I might do the above code using keypad. It frees you up from being stuck in while loops waiting for key holding or release. Is this sort of what you were after? (Using the key.timestamp property isn't that helpful here since you need to save the time anyway)

import time, board, keypad, usb_hid
from adafruit_hid.mouse import Mouse

m = Mouse(usb_hid.devices)

key_pins = (board.D4, board.D5)
        
keys = keypad.Keys(key_pins, value_when_pressed=True, pull=False)

print("waiting for keypresses...")

but0_press_time = 0  # when button0 was pressed. 0 means not currently pressed

while True:
    # get key events, if any, set butN_press_time as appropriate
    key = keys.events.get()
    if key:
        print(key.timestamp, key)  # see what key was pressed
        if key.key_number == 0:  # button0 
            if key.pressed:
                but0_press_time = time.monotonic()
            if key.released:
                but0_press_time = 0 # unpressed

    # handle sending mouse commands if buttons were pressed
    if but0_press_time:
        held_time = time.monotonic() - but0_press_time
        if held_time < 0.75:
            print("slow", held_time)
            m.move(0,1,0)
        elif held_time > 0.75 and held_time < 0.75*2:
            print("medium")
            m.move(0,3,0)
        elif held_time > 0.75*2:
            print("fast!")
            m.move(0,7,0)

@xgpt
Copy link

xgpt commented Nov 18, 2022

@todbot That's absolutely an excellent solution that solves my problem nearly entirely. I wonder if these commonly asked questions might better be incorporated into keypad itself, specifically things like "long hold" or "double click" questions.

@Neradoc mentioned that he even created a debouncer library in the Discord yesterday. https://github.com/Neradoc/keypad_debouncer

If such features aren't incorporated into the standard library, perhaps it would be worth mentioning how to implement them in the to-be-written guide?

I hope I'm not coming off as a demanding user here, just genuinely trying to make recommendations as a beginner on what would be helpful to be able to search up on the learning platform.

@partyexpress
Copy link

partyexpress commented Dec 2, 2022

Hi There,

I am trying to make a mouse and keyboard HID. I'm using a Raspberry Pi 4, with the USB C port as the connection. I've used the code below, and it says, "Could not find matching HID device. I can't seem to get around that. Can you please explain my issue. Thanks in advance.

Steve C.

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)

@todbot
Copy link

todbot commented Dec 2, 2022

@partyexpress, this library is for CircuitPython on microcontrollers. If you want to use Python to access USB HID on Raspberry Pis (or other unixes), check out https://pypi.org/project/hidapi/

@dhalbert
Copy link
Collaborator

I made a keypad example a while ago in https://learn.adafruit.com/key-pad-matrix-scanning-in-circuitpython/keys-one-key-per-pin#macropad-example-3099041. I am wondering if it is out of scope for simple library examples, or whether I should just add it to examples/.

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

No branches or pull requests

5 participants