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

DRV8833-Based Rumble (for XInput) #1090

Merged
merged 11 commits into from
Jul 20, 2024

Conversation

nicolasrmerz
Copy link
Contributor

Adds DRV8833-based rumble functionality for XInput.

There are three main sets of changes:

  1. Added a GamepadRumbleState struct, currently containing left/right motor rumble and unused stubs for left/right trigger rumble for XBone.
  2. Fix some oddities with USB out endpoint writes in XInputDriver.cpp so that both LED and Rumble data is handled. Added a function in XInputDriver.cpp that checks if data in the out endpoint is rumble data and writes to GamepadRumbleState if it is. (Sidenote: I know there's a proper GamepadAuxState WIP - I believe the writes to GamepadRumbleState can be trivially ported to GamepadAuxState when it is fully merged).
  3. Added a DRV8833 Rumble Addon that reads from GamepadRumbleState and sends PWM to webconfig-defined pins that are hooked up to the DRV8833 module to start the left/right motors. There is also duty cycle rescaling to set the range of duty percentages that the addon will use (though 0 will be an "off" signal no matter what).

@mikepparks
Copy link
Contributor

mikepparks commented Jul 17, 2024

After getting my own DRV8833 module to test with, here's some things worth noting for documentation's sake.

  • Motor sleep pin setting can be optional (set to -1) to free up IO. Bring the module's SLP high by wiring to VCC. Sleep pin is likely preferred for the sake of power savings.
  • When setting pins for AIN#/BIN#, the pin that will not be controlled should be wired to GND.
  • Has been tested with small disc motors as well.
  • May need to press a button on the controller first before rumble becomes active.

Wiring as follows:

DRV8833 GP2040 Notes
VM VCC 5V likely best
GND GND
AIN1 Pin ## Left or Right
AIN2 GND
BIN1 Pin ## Left or Right
BIN2 GND
SLP Pin ## Can be pulled high by VCC

Use AOUT and BOUT pins for the haptic motors of choice.

@nicolasrmerz
Copy link
Contributor Author

nicolasrmerz commented Jul 17, 2024

Further notes.

PWM Frequency

PWM frequency set to 10 KHz by default. Probably doesn't need to be ever touched by the average user, but wanted to leave customizable. With the DRV8833, anything under 50 KHz should fly.

Duty Cycle Min/Max

First, consider Duty Cycle Min = 0 and Duty Cycle Max = 100 (ie. no rescaling done). The XInput rumble packets and the GamepadRumbleState structs use uint8 values for rumble, giving a range of 0-255. This range gets translated to duty cycle factors of 0/255, 1/255, 2/255, ... , 254/255, 255/255, giving a new range of 0% - 100%.

The problem is that the lower end of this range gives too low an average voltage to drive the motor (the minimum operating voltage is motor-specific). The Duty Cycle Minimum/Maximum seek to resolve this. Setting these rescales the 0% - 100% range to DutyCycleMinimum% - DutyCycleMaximum%. Note, however, that no matter the rescaling, uint8 value of 0 will ALWAYS turn off the motor.

Experimentally, with the XBOne motors (Vybronics VJQ24-35F580C), the motors started operating reliably at about 25% duty cycle, meaning I set Duty Cycle Minimum to 25% and kept Maximum at 100%. Thus, for the nonzero uint8 range of 1 - 255, the voltage will range from about 5V * 0.25 = 1.25V to 5V * 1.00 = 5V.

These values will have to be obtained on a per-motor basis by the user either from the motor's datasheet or experimentally.

Hooking up VM

Depending on the current draw of your motors, you may want to STRONGLY consider using VBUS (or maybe VSYS?) to connect to the VM pin on the DRV8833. If the motors have high enough current draw, they could easily pull more than the Pico is rated for.

Copy link
Contributor

@arntsonl arntsonl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic work, thank you for contributing this!

@arntsonl arntsonl merged commit c309d35 into OpenStickCommunity:main Jul 20, 2024
42 checks passed
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

Successfully merging this pull request may close these issues.

None yet

3 participants