CircuitPython_JoystickXL icon indicating copy to clipboard operation
CircuitPython_JoystickXL copied to clipboard

Add usage examples for VirtualInput class

Open fasteddy516 opened this issue 2 years ago • 5 comments

The VirtualInput class decouples I/O pins from JoystickXL inputs and allows developers to do their own input processing before passing values along to JoystickXL. This functionality needs more documentation and examples.

fasteddy516 avatar Mar 28 '23 13:03 fasteddy516

Hello there. Is there any more information about this? I have a lot of problems creating a functional joystick where I don't have any axis directly from any pins.

Below example is redacted but its something like this:

import math
import time
import board
import busio
import adafruit_vl53l0x
from joystick_xl.inputs import Axis, Button, Hat
from joystick_xl.joystick import Joystick
from adafruit_simplemath import map_range

# Axis configuration constants
AXIS_DB = 0  # Deadband to apply to axis center points.
AXIS_MIN = 0  # Minimum raw axis value.
AXIS_MAX = 255  # Maximum raw axis value.

# Initialize joystick library
joystick = Joystick()
joystick.add_input(
    Axis(deadband=AXIS_DB, min=AXIS_MIN, max=AXIS_MAX),
    Axis(deadband=AXIS_DB, min=AXIS_MIN, max=AXIS_MAX)
)

<...>

while True:

    <...>
    axisvalue = <computed from I2C sensor>

    # Update joystick
    joystick.update_axis((0, 128))
    joystick.update_axis((1, axisvalue))
    joystick.update()

jtinbergen avatar Feb 16 '24 21:02 jtinbergen

There are a couple of things you'll need to modify to get that code to work as expected.

First, verify that the AXIS_DB, AXIS_MIN and AXIS_MAX configuration constants are set appropriately. These apply to the 16-bit raw input range, not the 8-bit scaled USB-HID axis report range. (CircuitPython scales all analog input pins to 16-bit values regardless of the actual bit-precision of the ADC hardware, so JoystickXL uses 16-bit raw axis input values, even for a VirtualInput). I suspect you want to set AXIS_MAX to 65535 rather than 255.

Next, you should avoid calling joystick.update_axis directly - it is called automatically for any axis objects in the joystick.axis collection which you've placed you're axes in using the joystick.add_input method. To set your axis values, use the source_value property like so:

joystick.axis[<axis name/number>].source_value = <some value between 0 to 65535>

When you're finished just call joystick.update(). It will use the source_value you set and process all of the inputs.

I've modified the example you posted above with these suggestions, you can give it a shot and see if it works better for you.

import math
import time
import board
import busio
import adafruit_vl53l0x
from joystick_xl.inputs import Axis, Button, Hat
from joystick_xl.joystick import Joystick
from adafruit_simplemath import map_range

# Axis configuration constants - remember that these are applied in the 16-bit raw input range,
# not the 8-bit scaled axis range.  
AXIS_DB = 0  # Deadband to apply to axis center points.
AXIS_MIN = 0  # Minimum raw axis value.
AXIS_MAX = 65535  # Maximum raw axis value.

# Initialize joystick library
joystick = Joystick()

# Add axis inputs as VirtualInputs with no direct connection to analog pins
joystick.add_input(
    Axis(deadband=AXIS_DB, min=AXIS_MIN, max=AXIS_MAX),  # x-axis
    Axis(deadband=AXIS_DB, min=AXIS_MIN, max=AXIS_MAX),  # y-axis
)

# ...

while True:
    # ...

    # Update the axis VirtualInput source values 
    joystick.axis[Axis.X].source_value = int_value_computed_from_I2C_sensor
    joystick.axis[Axis.Y].source_value = int_value_computed_elsewhere

    # Process all inputs and send a USB-HID report to the host
    joystick.update()

fasteddy516 avatar Feb 17 '24 15:02 fasteddy516

Excellent. Glad to see you're so active! Maybe its an idea to add this use case to the examples? most seem focused on actual pins.

jtinbergen avatar Feb 17 '24 18:02 jtinbergen

This is still a big issue, as there are many,many things that inputs can be gotten from that still need further processing outside of JoystickXL. I've been trying for 2 days now to figure out how to pass an input to JoystickXL to no avail and zero progress, and have admittedly exhausted my programming knowledge.

TheChemistAstronaut avatar Jul 07 '24 14:07 TheChemistAstronaut

@TheChemistAstronaut maybe this discussion topic example code will help you.

ndgipper avatar Aug 23 '24 00:08 ndgipper