joytsick_xl.hid

Initial USB configuration tools for use in boot.py setup.

This module provides the necessary functions to create a CircuitPython USB HID device with a descriptor that includes the configured type and quantity of inputs.

create_joystick(axes: int = 4, buttons: int = 16, hats: int = 1, report_id: int = 4) usb_hid.Device[source]

Create the usb_hid.Device required by usb_hid.enable() in boot.py.

Note

JoystickXL will add an entry to the boot_out.txt file on your CIRCUITPY drive. It is used by the Joystick module to retrieve configuration settings.

Parameters:
  • axes (int, optional) – The number of axes to support, from 0 to 8. (Default is 4)

  • buttons (int, optional) – The number of buttons to support, from 0 to 128. (Default is 16)

  • hats (int, optional) – The number of hat switches to support, from 0 to 4. (Default is 1)

  • report_id (int) – The USB HID report ID number to use. (Default is 4)

Returns:

A usb_hid.Device object with a descriptor identifying it as a joystick with the specified number of buttons, axes and hat switches.

Return type:

usb_hid.Device

joystick_xl.joystick

The base JoystickXL class for updating input states and sending USB HID reports.

This module provides the necessary functions to create a JoystickXL object, retrieve its input counts, associate input objects and update its input states.

class Joystick[source]

Create a JoystickXL object with all inputs in idle states.

from joystick_xl.joystick import Joystick

js = Joystick()

Note

A JoystickXL usb_hid.Device object has to be created in boot.py before creating a Joystick() object in code.py, otherwise an exception will be thrown.

property num_axes: int

Return the number of available axes in the USB HID descriptor.

property num_buttons: int

Return the number of available buttons in the USB HID descriptor.

property num_hats: int

Return the number of available hat switches in the USB HID descriptor.

axis

List of axis inputs associated with this joystick through add_input.

hat

List of hat inputs associated with this joystick through add_input.

button

List of button inputs associated with this joystick through add_input.

add_input(*input: Axis | Button | Hat) None[source]

Associate one or more axis, button or hat inputs with the joystick.

The provided input(s) are automatically added to the axis, button and hat lists based on their type. The order in which inputs are added will determine their index/reference number. (i.e., the first button object that is added will be Joystick.button[0].) Inputs of all types can be added at the same time and will be sorted into the correct list.

Parameters:

input (Axis, Button, or Hat) – One or more Axis, Button or Hat objects.

Raises:
  • TypeError – If an object that is not an Axis, Button or Hat is passed in.

  • OverflowError – If an attempt is made to add more than the available number of axes, buttons or hat switches to the respective list.

Return type:

None

update(always: bool = False, halt_on_error: bool = False) None[source]

Update all inputs in associated input lists and generate a USB HID report.

Parameters:
  • always (bool, optional) – When True, send a report even if it is identical to the last report that was sent out. Defaults to False.

  • halt_on_error (bool, optional) – When True, an exception will be raised and the program will halt if an OSError occurs when the report is sent. When False, the report will simply be dropped and no exception will be raised. Defaults to False.

Return type:

None

reset_all() None[source]

Reset all inputs to their idle states.

Return type:

None

update_axis(*axis: Tuple[int, int], defer: bool = False, skip_validation: bool = False) None[source]

Update the value of one or more axis input(s).

Parameters:
  • axis (Tuple[int, int]) – One or more tuples containing an axis index (0-based) and value (0 to 255, with 128 indicating the axis is idle/centered).

  • defer (bool) – When True, prevents sending a USB HID report upon completion. Defaults to False.

  • skip_validation (bool) – When True, bypasses the normal input number/value validation that occurs before they get processed. This is used for known good values that are generated using the Joystick.axis[], Joystick.button[] and Joystick.hat[] lists. Defaults to False.

Return type:

None

# Updates a single axis
update_axis((0, 42))  # 0 = x-axis

# Updates multiple axes
update_axis((1, 22), (3, 237))  # 1 = y-axis, 3 = rx-axis

Note

update_axis is called automatically for any axis objects added to the built in Joystick.axis[] list when Joystick.update() is called.

update_button(*button: Tuple[int, bool], defer: bool = False, skip_validation: bool = False) None[source]

Update the value of one or more button input(s).

Parameters:
  • button (Tuple[int, bool]) – One or more tuples containing a button index (0-based) and value (True if pressed, False if released).

  • defer (bool) – When True, prevents sending a USB HID report upon completion. Defaults to False.

  • skip_validation (bool) – When True, bypasses the normal input number/value validation that occurs before they get processed. This is used for known good values that are generated using the Joystick.axis[], Joystick.button[] and Joystick.hat[] lists. Defaults to False.

Return type:

None

# Update a single button
update_button((0, True))  # 0 = b1

# Updates multiple buttons
update_button((1, False), (7, True))  # 1 = b2, 7 = b8

Note

update_button is called automatically for any button objects added to the built in Joystick.button[] list when Joystick.update() is called.

update_hat(*hat: Tuple[int, int], defer: bool = False, skip_validation: bool = False) None[source]

Update the value of one or more hat switch input(s).

Parameters:
  • hat (Tuple[int, int]) –

    One or more tuples containing a hat switch index (0-based) and value. Valid hat switch values range from 0 to 8 as follows:

    • 0 = UP

    • 1 = UP + RIGHT

    • 2 = RIGHT

    • 3 = DOWN + RIGHT

    • 4 = DOWN

    • 5 = DOWN + LEFT

    • 6 = LEFT

    • 7 = UP + LEFT

    • 8 = IDLE

  • defer (bool) – When True, prevents sending a USB HID report upon completion. Defaults to False.

  • skip_validation (bool) – When True, bypasses the normal input number/value validation that occurs before they get processed. This is used for known good values that are generated using the Joystick.axis[], Joystick.button[] and Joystick.hat[] lists. Defaults to False.

Return type:

None

# Updates a single hat switch
update_hat((0, 3))  # 0 = h1

# Updates multiple hat switches
update_hat((1, 8), (3, 1))  # 1 = h2, 3 = h4

Note

update_hat is called automatically for any hat switch objects added to the built in Joystick.hat[] list when Joystick.update() is called.

joystick_xl.inputs

Classes to simplify mapping GPIO pins and values to JoystickXL inputs and states.

This module provides a set of classes to aid in configuring GPIO pins and convert their raw states to values that are usable by JoystickXL.

class VirtualInput(value: bool | int)[source]

Provide an object with a .value property to represent a remote input.

Parameters:

value (bool or int) – Sets the initial .value property (Should be True for active-low buttons, 32768 for idle/centered axes).

class Axis(source=None, deadband: int = 0, min: int = 0, max: int = 65535, invert: bool = False, bypass: bool = False)[source]

Provide data source storage and scaling/deadband processing for an axis input.

Parameters:
  • source (Any, optional) – CircuitPython pin identifier (i.e. board.A0) or any object with an int .value attribute. (Defaults to None, which will create a VirtualInput source instead.)

  • deadband (int, optional) – Raw, absolute value of the deadband to apply around the midpoint of the raw source value. The deadband is used to prevent an axis from registering minimal values when it is centered. Setting the deadband value to 250 means raw input values +/- 250 from the midpoint will all be treated as the midpoint. (defaults to 0)

  • min (int, optional) – The raw input value that corresponds to a scaled axis value of 0. Any raw input value <= to this value will get scaled to 0. Useful if the component used to generate the raw input never actually reaches 0. (defaults to 0)

  • max (int, optional) – The raw input value that corresponds to a scaled axis value of 255. Any raw input value >= to this value will get scaled to 255. Useful if the component used to generate the raw input never actually reaches 65535. (defaults to 65535)

  • invert (bool, optional) – Set to True to invert the scaled axis value. Useful if the physical orientation of the component used to generate the raw axis input does not match the logical direction of the axis input. (defaults to False)

  • bypass (bool, optional) – Set to True to make the axis always appear centered in USB HID reports back to the host device. (Defaults to False)

MIN = 0

Lowest possible axis value for USB HID reports.

MAX = 255

Highest possible axis value for USB HID reports.

IDLE = 128

Idle/Center axis value for USB HID reports.

X = 0

Alias for the X-axis index.

Y = 1

Alias for the Y-axis index.

Z = 2

Alias for the Z-axis index.

RX = 3

Alias for the RX-axis index.

RY = 4

Alias for the RY-axis index.

RZ = 5

Alias for the RZ-axis index.

S0 = 6

Alias for the S0-axis index.

S1 = 7

Alias for the S1-axis index.

property value: int

Get the current, fully processed value of this axis.

Returns:

0 to 255, 128 if idle/centered or bypassed.

Return type:

int

property source_value: int

Get the raw source input value.

(For VirtualInput sources, this property can also be set.)

Returns:

0 to 65535

Return type:

int

property min: int

Get the configured minimum raw analogio input value.

Returns:

0 to 65535

Return type:

int

property max: int

Get the configured maximum raw analogio input value.

Returns:

0 to 65535

Return type:

int

property deadband: int

Get the raw, absolute value of the configured deadband.

Returns:

0 to 65535

Return type:

int

property invert: bool

Return True if the raw analogio input value is inverted.

Returns:

True if inverted, False otherwise

Return type:

bool

bypass

Set to True to make the axis always appear idle/centered.

class Button(source=None, active_low: bool = True, bypass: bool = False)[source]

Provide data source storage and value processing for a button input.

Parameters:
  • source (Any, optional) – CircuitPython pin identifier (i.e. board.D2), or any object with a boolean .value attribute. (Defaults to None, which will create a VirtualInput source instead.)

  • active_low (bool, optional) – Set to True if the input pin is active low (reads False when the button is pressed), otherwise set to False. (defaults to True)

  • bypass (bool, optional) – Set to True to make the button always appear released in USB HID reports back to the host device. (Defaults to False)

property value: bool

Get the current, fully processed value of this button input.

Warning

Accessing this property also updates the .was_pressed and .was_released logic, which means accessing .value directly anywhere other than in a call to Joystick.update_button() can make those properties unreliable. If you need to read the current state of a button anywhere else in your input processing loop, you should be using .is_pressed or .is_released rather than .value.

Returns:

True if pressed, False if released or bypassed.

Return type:

bool

property is_pressed: bool

Determine if this button is currently in the pressed state.

Returns:

True if button is pressed, otherwise False

Return type:

bool

property is_released: bool

Determine if this button is currently in the released state.

Returns:

True if button is released, otherwise False.

Return type:

bool

property was_pressed: bool

Determine if this button was just pressed.

Specifically, if the button state changed from released to pressed between the last two reads of Button.value.

Warning

This property only works reliably when Button.value is accessed once per iteration of your input processing loop. If your code uses the built-in Joystick.add_input() method and associated input lists along with a single call to Joystick.update(), you should be fine.

Returns:

True if the button was just pressed, False otherwise.

Return type:

bool

property was_released: bool

Determine if this button was just released.

Specifically, if the button state changed from pressed to released between the last two reads of Button.value.

Warning

This property only works reliably when Button.value is accessed once per iteration of your input processing loop. If your code uses the built-in Joystick.add_input() method and associated input lists along with a single call to Joystick.update(), you should be fine.

Returns:

True if the button was just released, False otherwise.

Return type:

bool

property source_value: bool

Get the raw source input value.

(For VirtualInput sources, this property can also be set.)

Returns:

True or False

Return type:

bool

property active_low: bool

Get the input configuration state of the button.

Returns:

True if the button is active low, False otherwise.

Return type:

bool

bypass

Set to True to make the button always appear released.

class Hat(up=None, down=None, left=None, right=None, active_low: bool = True, bypass: bool = False)[source]

Provide data source storage and value processing for a hat switch input.

Parameters:
  • up (Any, optional) – CircuitPython pin identifier (i.e. board.D2) or any object with a boolean .value attribute. (Defaults to None, which will create a VirtualInput source instead.)

  • down (Any, optional) – CircuitPython pin identifier (i.e. board.D2) or any object with a boolean .value attribute. (Defaults to None, which will create a VirtualInput source instead.)

  • left (Any, optional) – CircuitPython pin identifier (i.e. board.D2) or any object with a boolean .value attribute. (Defaults to None, which will create a VirtualInput source instead.)

  • right (Any, optional) – CircuitPython pin identifier (i.e. board.D2) or any object with a boolean .value attribute. (Defaults to None, which will create a VirtualInput source instead.)

  • active_low (bool, optional) – Set to True if the input pins are active low (read False when buttons are pressed), otherwise set to False. (defaults to True)

  • bypass (bool, optional) – Set to True to make the hat switch always appear idle in USB HID reports back to the host device. (Defaults to False)

U = 0

Alias for the UP switch position.

UR = 1

Alias for the UP + RIGHT switch position.

R = 2

Alias for the RIGHT switch position.

DR = 3

Alias for the DOWN + RIGHT switch position.

D = 4

Alias for the DOWN switch position.

DL = 5

Alias for the DOWN + LEFT switch position.

L = 6

Alias for the LEFT switch position.

UL = 7

Alias for the UP + LEFT switch position.

IDLE = 8

Alias for the IDLE switch position.

property value: int

Get the current, fully processed value of this hat switch.

Returns:

Current position value (always IDLE if bypassed), as follows:

  • 0 = UP

  • 1 = UP + RIGHT

  • 2 = RIGHT

  • 3 = DOWN + RIGHT

  • 4 = DOWN

  • 5 = DOWN + LEFT

  • 6 = LEFT

  • 7 = UP + LEFT

  • 8 = IDLE

Return type:

int

property packed_source_values: int

Get the current packed value of all four button input source values.

Returns:

Packed button input source values in one byte (0000RLDU).

Return type:

int

property active_low: bool

Get the input configuration state of the hat switch buttons.

Returns:

True if the buttons are active low, False otherwise.

Return type:

bool

up

Button object associated with the up input.

down

Button object associated with the down input.

left

Button object associated with the left input.

right

Button object associated with the right input.

bypass

Set to True to make the hat switch always appear idle.

unpack_source_values(source_values: int) None[source]

Unpack all four source values from a single packed integer.

Parameters:

source_values (int) – Packed button source values in one byte (0000RLDU).

Return type:

None

Note

This operation is only valid for hat switches composed of VirtualInput objects.

joystick_xl.tools

Tools to assist in the development and general use of JoystickXL.

TestAxes(js: Joystick, step: int = 5, quiet: bool = False) None[source]

Exercise each axis in the supplied Joystick object.

Parameters:
  • js (Joystick) – The Joystick object to test.

  • step (int, optional) – The size of axis adjustment steps. A higher value provides coarser axis movement and faster tests. Set to 1 to test every possible axis value (which can result in long test runs). (Default is 5)

  • quiet (bool, optional) – Set to True to disable console output during testing. (Defaults to False)

Return type:

None

TestButtons(js: Joystick, pace: float = 0.05, quiet: bool = False) None[source]

Exercise each button in the supplied Joystick object.

Parameters:
  • js (Joystick) – The Joystick object to test.

  • pace (float, optional) – Duration (in seconds) and time between button presses. (Default is 0.05 seconds)

  • quiet (bool, optional) – Set to True to disable console output during testing. (Defaults to False.)

Return type:

None

TestHats(js: Joystick, pace: float = 0.25, quiet: bool = False) None[source]

Exercise each hat switch in the supplied Joystick object.

Parameters:
  • js (Joystick) – The Joystick object to test.

  • pace (float, optional) – Duration (in seconds) that each hat switch direction will be engaged for. (Default is 0.25 seconds)

  • quiet (bool, optional) – Set to True to disable console output during testing. (Defaults to False.)

Return type:

None

TestConsole(button_pin: microcontroller.Pin = None)[source]

Run JoystickXL’s REPL-based, built-in test console.

Parameters:

button_pin (microcontroller.Pin, optional) – Specify the pin to use as TestConsole’s test button. Defaults to board.D2 (board.GP2 on RP2040-based devices).