Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
novaspirit authored Mar 26, 2021
1 parent c30078d commit bdecb98
Show file tree
Hide file tree
Showing 9 changed files with 1,190 additions and 0 deletions.
61 changes: 61 additions & 0 deletions code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import time
import usb_hid
from adafruit_hid.keycode import Keycode
from adafruit_hid.keyboard import Keyboard
import board
import digitalio


btn1_pin = board.GP9
btn2_pin = board.GP8
btn3_pin = board.GP7
btn4_pin = board.GP19
btn5_pin = board.GP20
btn6_pin = board.GP21

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

btn2 = digitalio.DigitalInOut(btn2_pin)
btn2.direction = digitalio.Direction.INPUT
btn2.pull = digitalio.Pull.DOWN

btn3 = digitalio.DigitalInOut(btn3_pin)
btn3.direction = digitalio.Direction.INPUT
btn3.pull = digitalio.Pull.DOWN

btn4 = digitalio.DigitalInOut(btn4_pin)
btn4.direction = digitalio.Direction.INPUT
btn4.pull = digitalio.Pull.DOWN

btn5 = digitalio.DigitalInOut(btn5_pin)
btn5.direction = digitalio.Direction.INPUT
btn5.pull = digitalio.Pull.DOWN

btn6 = digitalio.DigitalInOut(btn6_pin)
btn6.direction = digitalio.Direction.INPUT
btn6.pull = digitalio.Pull.DOWN

keyboard = Keyboard(usb_hid.devices)

while True:
if btn1.value:
keyboard.send(Keycode.CONTROL, Keycode.F7)
time.sleep(0.1)
if btn2.value:
keyboard.send(Keycode.CONTROL, Keycode.F8)
time.sleep(0.1)
if btn3.value:
keyboard.send(Keycode.CONTROL, Keycode.F9)
time.sleep(0.1)
if btn4.value:
keyboard.send(Keycode.CONTROL, Keycode.F10)
time.sleep(0.1)
if btn5.value:
keyboard.send(Keycode.CONTROL, Keycode.F11)
time.sleep(0.1)
if btn6.value:
keyboard.send(Keycode.CONTROL, Keycode.F12)
time.sleep(0.1)
time.sleep(0.1)
38 changes: 38 additions & 0 deletions lib/adafruit_hid/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# SPDX-FileCopyrightText: 2017 Scott Shawcroft for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
`adafruit_hid`
====================================================
This driver simulates USB HID devices.
* Author(s): Scott Shawcroft, Dan Halbert
Implementation Notes
--------------------
**Software and Dependencies:**
* Adafruit CircuitPython firmware for the supported boards:
https://github.com/adafruit/circuitpython/releases
"""

# imports

__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_HID.git"


def find_device(devices, *, usage_page, usage):
"""Search through the provided list of devices to find the one with the matching usage_page and
usage."""
if hasattr(devices, "send_report"):
devices = [devices]
for device in devices:
if (
device.usage_page == usage_page
and device.usage == usage
and hasattr(device, "send_report")
):
return device
raise ValueError("Could not find matching HID device.")
67 changes: 67 additions & 0 deletions lib/adafruit_hid/consumer_control.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# SPDX-FileCopyrightText: 2018 Dan Halbert for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
`adafruit_hid.consumer_control.ConsumerControl`
====================================================
* Author(s): Dan Halbert
"""

import sys

if sys.implementation.version[0] < 3:
raise ImportError(
"{0} is not supported in CircuitPython 2.x or lower".format(__name__)
)

# pylint: disable=wrong-import-position
import struct
import time
from . import find_device


class ConsumerControl:
"""Send ConsumerControl code reports, used by multimedia keyboards, remote controls, etc."""

def __init__(self, devices):
"""Create a ConsumerControl object that will send Consumer Control Device HID reports.
Devices can be a list of devices that includes a Consumer Control device or a CC device
itself. A device is any object that implements ``send_report()``, ``usage_page`` and
``usage``.
"""
self._consumer_device = find_device(devices, usage_page=0x0C, usage=0x01)

# Reuse this bytearray to send consumer reports.
self._report = bytearray(2)

# Do a no-op to test if HID device is ready.
# If not, wait a bit and try once more.
try:
self.send(0x0)
except OSError:
time.sleep(1)
self.send(0x0)

def send(self, consumer_code):
"""Send a report to do the specified consumer control action,
and then stop the action (so it will not repeat).
:param consumer_code: a 16-bit consumer control code.
Examples::
from adafruit_hid.consumer_control_code import ConsumerControlCode
# Raise volume.
consumer_control.send(ConsumerControlCode.VOLUME_INCREMENT)
# Advance to next track (song).
consumer_control.send(ConsumerControlCode.SCAN_NEXT_TRACK)
"""
struct.pack_into("<H", self._report, 0, consumer_code)
self._consumer_device.send_report(self._report)
self._report[0] = self._report[1] = 0x0
self._consumer_device.send_report(self._report)
43 changes: 43 additions & 0 deletions lib/adafruit_hid/consumer_control_code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# SPDX-FileCopyrightText: 2018 Dan Halbert for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
`adafruit_hid.consumer_control_code.ConsumerControlCode`
========================================================
* Author(s): Dan Halbert
"""


class ConsumerControlCode:
"""USB HID Consumer Control Device constants.
This list includes a few common consumer control codes from
https://www.usb.org/sites/default/files/hut1_21_0.pdf#page=118.
"""

# pylint: disable-msg=too-few-public-methods

RECORD = 0xB2
"""Record"""
FAST_FORWARD = 0xB3
"""Fast Forward"""
REWIND = 0xB4
"""Rewind"""
SCAN_NEXT_TRACK = 0xB5
"""Skip to next track"""
SCAN_PREVIOUS_TRACK = 0xB6
"""Go back to previous track"""
STOP = 0xB7
"""Stop"""
EJECT = 0xB8
"""Eject"""
PLAY_PAUSE = 0xCD
"""Play/Pause toggle"""
MUTE = 0xE2
"""Mute"""
VOLUME_DECREMENT = 0xEA
"""Decrease volume"""
VOLUME_INCREMENT = 0xE9
"""Increase volume"""
157 changes: 157 additions & 0 deletions lib/adafruit_hid/gamepad.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# SPDX-FileCopyrightText: 2018 Dan Halbert for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
`adafruit_hid.gamepad.Gamepad`
====================================================
* Author(s): Dan Halbert
"""

import struct
import time

from . import find_device


class Gamepad:
"""Emulate a generic gamepad controller with 16 buttons,
numbered 1-16, and two joysticks, one controlling
``x` and ``y`` values, and the other controlling ``z`` and
``r_z`` (z rotation or ``Rz``) values.
The joystick values could be interpreted
differently by the receiving program: those are just the names used here.
The joystick values are in the range -127 to 127."""

def __init__(self, devices):
"""Create a Gamepad object that will send USB gamepad HID reports.
Devices can be a list of devices that includes a gamepad device or a gamepad device
itself. A device is any object that implements ``send_report()``, ``usage_page`` and
``usage``.
"""
self._gamepad_device = find_device(devices, usage_page=0x1, usage=0x05)

# Reuse this bytearray to send mouse reports.
# Typically controllers start numbering buttons at 1 rather than 0.
# report[0] buttons 1-8 (LSB is button 1)
# report[1] buttons 9-16
# report[2] joystick 0 x: -127 to 127
# report[3] joystick 0 y: -127 to 127
# report[4] joystick 1 x: -127 to 127
# report[5] joystick 1 y: -127 to 127
self._report = bytearray(6)

# Remember the last report as well, so we can avoid sending
# duplicate reports.
self._last_report = bytearray(6)

# Store settings separately before putting into report. Saves code
# especially for buttons.
self._buttons_state = 0
self._joy_x = 0
self._joy_y = 0
self._joy_z = 0
self._joy_r_z = 0

# Send an initial report to test if HID device is ready.
# If not, wait a bit and try once more.
try:
self.reset_all()
except OSError:
time.sleep(1)
self.reset_all()

def press_buttons(self, *buttons):
"""Press and hold the given buttons. """
for button in buttons:
self._buttons_state |= 1 << self._validate_button_number(button) - 1
self._send()

def release_buttons(self, *buttons):
"""Release the given buttons. """
for button in buttons:
self._buttons_state &= ~(1 << self._validate_button_number(button) - 1)
self._send()

def release_all_buttons(self):
"""Release all the buttons."""

self._buttons_state = 0
self._send()

def click_buttons(self, *buttons):
"""Press and release the given buttons."""
self.press_buttons(*buttons)
self.release_buttons(*buttons)

def move_joysticks(self, x=None, y=None, z=None, r_z=None):
"""Set and send the given joystick values.
The joysticks will remain set with the given values until changed
One joystick provides ``x`` and ``y`` values,
and the other provides ``z`` and ``r_z`` (z rotation).
Any values left as ``None`` will not be changed.
All values must be in the range -127 to 127 inclusive.
Examples::
# Change x and y values only.
gp.move_joysticks(x=100, y=-50)
# Reset all joystick values to center position.
gp.move_joysticks(0, 0, 0, 0)
"""
if x is not None:
self._joy_x = self._validate_joystick_value(x)
if y is not None:
self._joy_y = self._validate_joystick_value(y)
if z is not None:
self._joy_z = self._validate_joystick_value(z)
if r_z is not None:
self._joy_r_z = self._validate_joystick_value(r_z)
self._send()

def reset_all(self):
"""Release all buttons and set joysticks to zero."""
self._buttons_state = 0
self._joy_x = 0
self._joy_y = 0
self._joy_z = 0
self._joy_r_z = 0
self._send(always=True)

def _send(self, always=False):
"""Send a report with all the existing settings.
If ``always`` is ``False`` (the default), send only if there have been changes.
"""
struct.pack_into(
"<Hbbbb",
self._report,
0,
self._buttons_state,
self._joy_x,
self._joy_y,
self._joy_z,
self._joy_r_z,
)

if always or self._last_report != self._report:
self._gamepad_device.send_report(self._report)
# Remember what we sent, without allocating new storage.
self._last_report[:] = self._report

@staticmethod
def _validate_button_number(button):
if not 1 <= button <= 16:
raise ValueError("Button number must in range 1 to 16")
return button

@staticmethod
def _validate_joystick_value(value):
if not -127 <= value <= 127:
raise ValueError("Joystick value must be in range -127 to 127")
return value
Loading

0 comments on commit bdecb98

Please sign in to comment.