From 0b1601b559ca2168cc0e4c952eb1b921c856a277 Mon Sep 17 00:00:00 2001 From: Asi Sapir Date: Wed, 7 Dec 2022 15:28:16 +0200 Subject: [PATCH 1/2] Add support for mutiple throttles (max 2) --- .../ArcadeStickExample/ArcadeStickExample.ino | 4 +- .../DrivingControllerTest.ino | 7 + .../FlightControllerTest.ino | 12 +- .../FunduinoJoystickShield.ino | 14 +- examples/GamepadExample/GamepadExample.ino | 4 +- examples/HatSwitchTest/HatSwitchTest.ino | 7 + .../MultipleJoystickTest.ino | 8 +- src/Joystick.cpp | 356 ++++++++++-------- src/Joystick.h | 10 +- 9 files changed, 246 insertions(+), 176 deletions(-) diff --git a/examples/ArcadeStickExample/ArcadeStickExample.ino b/examples/ArcadeStickExample/ArcadeStickExample.ino index 1f9df66..8856d5a 100644 --- a/examples/ArcadeStickExample/ArcadeStickExample.ino +++ b/examples/ArcadeStickExample/ArcadeStickExample.ino @@ -35,10 +35,10 @@ #include Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD, - 8, 0, // Button Count, Hat Switch Count + 8, 0, 0, // Button Count, Hat Switch Count, Throttle Count true, true, false, // X and Y, but no Z Axis false, false, false, // No Rx, Ry, or Rz - false, false, // No rudder or throttle + false, // No rudder false, false, false); // No accelerator, brake, or steering void setup() { diff --git a/examples/DrivingControllerTest/DrivingControllerTest.ino b/examples/DrivingControllerTest/DrivingControllerTest.ino index a659e71..ed771fe 100644 --- a/examples/DrivingControllerTest/DrivingControllerTest.ino +++ b/examples/DrivingControllerTest/DrivingControllerTest.ino @@ -13,6 +13,13 @@ Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, false, false, false, false, false, false, false, false, true, true, true); +Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_MULTI_AXIS, + 4, 0, 0, // Button Count, Hat Switch Count, Throttle Count + false, false, false, // X and Y, but no Z Axis + false, false, false, // No Rx, Ry, or Rz + false, // No rudder + true, true, true); // No accelerator, brake, or steering + // Set to true to test "Auto Send" mode or false to test "Manual Send" mode. //const bool testAutoSendMode = true; const bool testAutoSendMode = false; diff --git a/examples/FlightControllerTest/FlightControllerTest.ino b/examples/FlightControllerTest/FlightControllerTest.ino index 2d7f633..ab7c998 100644 --- a/examples/FlightControllerTest/FlightControllerTest.ino +++ b/examples/FlightControllerTest/FlightControllerTest.ino @@ -8,10 +8,12 @@ #include "Joystick.h" -Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, - JOYSTICK_TYPE_MULTI_AXIS, 32, 0, - true, true, false, false, false, false, - true, true, false, false, false); +Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_MULTI_AXIS, + 32, 0, 1, // Button Count, Hat Switch Count, Throttle Count + true, true, false, // X and Y, but no Z Axis + false, false, false, // No Rx, Ry, or Rz + true, // rudder + false, false, false); // No accelerator, brake, or steering // Set to true to test "Auto Send" mode or false to test "Manual Send" mode. //const bool testAutoSendMode = true; @@ -103,7 +105,7 @@ void testXYAxis(unsigned int currentStep) void testThrottleRudder(unsigned int value) { - Joystick.setThrottle(value); + Joystick.setThrottle(0, value); Joystick.setRudder(255 - value); } diff --git a/examples/FunduinoJoystickShield/FunduinoJoystickShield.ino b/examples/FunduinoJoystickShield/FunduinoJoystickShield.ino index 71c277a..57f1b46 100644 --- a/examples/FunduinoJoystickShield/FunduinoJoystickShield.ino +++ b/examples/FunduinoJoystickShield/FunduinoJoystickShield.ino @@ -1,11 +1,15 @@ #include const uint8_t buttonCount = 7; -Joystick_ controller(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, buttonCount, - 0, true, true, false, - false, false, false, - false, false, false, - false, false); + +Joystick_ controller(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD, + buttonCount, 0, 0, // Button Count, Hat Switch Count, Throttle Count + true, true, false, // X and Y, but no Z Axis + false, false, false, // No Rx, Ry, or Rz + false, // rudder + false, false, false); // No accelerator, brake, or steering + + int const BTN_A_PIN = 2; int const BTN_B_PIN = 3; diff --git a/examples/GamepadExample/GamepadExample.ino b/examples/GamepadExample/GamepadExample.ino index ff728b3..dfa25c6 100644 --- a/examples/GamepadExample/GamepadExample.ino +++ b/examples/GamepadExample/GamepadExample.ino @@ -18,10 +18,10 @@ #include Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD, - 1, 0, // Button Count, Hat Switch Count + 1, 0, 0, // Button Count, Hat Switch Count, Throttle Count true, true, false, // X and Y, but no Z Axis false, false, false, // No Rx, Ry, or Rz - false, false, // No rudder or throttle + false, // No rudder false, false, false); // No accelerator, brake, or steering void setup() { diff --git a/examples/HatSwitchTest/HatSwitchTest.ino b/examples/HatSwitchTest/HatSwitchTest.ino index 22e040e..d0cbbf4 100644 --- a/examples/HatSwitchTest/HatSwitchTest.ino +++ b/examples/HatSwitchTest/HatSwitchTest.ino @@ -29,6 +29,13 @@ Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, false, false, false, false, false, false, false, false, false, false, false); +Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD, + 0, JOYSTICK_DEFAULT_HATSWITCH_COUNT, 0, // Button Count, Hat Switch Count, Throttle Count + false, false, false, // X and Y, but no Z Axis + false, false, false, // No Rx, Ry, or Rz + false, // No rudder + false, false, false); // No accelerator, brake, or steering + void setup() { // Initialize Button Pins diff --git a/examples/MultipleJoystickTest/MultipleJoystickTest.ino b/examples/MultipleJoystickTest/MultipleJoystickTest.ino index 60735c1..931f16c 100644 --- a/examples/MultipleJoystickTest/MultipleJoystickTest.ino +++ b/examples/MultipleJoystickTest/MultipleJoystickTest.ino @@ -13,10 +13,10 @@ #define JOYSTICK_COUNT 4 Joystick_ Joystick[JOYSTICK_COUNT] = { - Joystick_(0x03, JOYSTICK_TYPE_JOYSTICK, 4, 2, true, true, false, false, false, false, false, false, false, false, false), - Joystick_(0x04, JOYSTICK_TYPE_JOYSTICK, 8, 1, true, true, true, true, false, false, false, false, false, false, false), - Joystick_(0x05, JOYSTICK_TYPE_JOYSTICK, 16, 0, false, true, false, true, false, false, true, true, false, false, false), - Joystick_(0x06, JOYSTICK_TYPE_JOYSTICK, 32, 1, true, true, false, true, true, false, false, false, false, false, false) + Joystick_(0x03, JOYSTICK_TYPE_JOYSTICK, 4, 2, 0, true, true, false, false, false, false, false, false, false, false), + Joystick_(0x04, JOYSTICK_TYPE_JOYSTICK, 8, 1, 0, true, true, true, true, false, false, false, false, false, false), + Joystick_(0x05, JOYSTICK_TYPE_JOYSTICK, 16, 0, 1, false, true, false, true, false, false, true, false, false, false), + Joystick_(0x06, JOYSTICK_TYPE_JOYSTICK, 32, 1, 0, true, true, false, true, true, false, false, false, false, false) }; // Set to true to test "Auto Send" mode or false to test "Manual Send" mode. diff --git a/src/Joystick.cpp b/src/Joystick.cpp index c91841c..8bfcf5b 100644 --- a/src/Joystick.cpp +++ b/src/Joystick.cpp @@ -28,24 +28,25 @@ #define JOYSTICK_SIMULATOR_MINIMUM 0 #define JOYSTICK_SIMULATOR_MAXIMUM 65535 -#define JOYSTICK_INCLUDE_X_AXIS B00000001 -#define JOYSTICK_INCLUDE_Y_AXIS B00000010 -#define JOYSTICK_INCLUDE_Z_AXIS B00000100 +#define JOYSTICK_INCLUDE_X_AXIS B00000001 +#define JOYSTICK_INCLUDE_Y_AXIS B00000010 +#define JOYSTICK_INCLUDE_Z_AXIS B00000100 #define JOYSTICK_INCLUDE_RX_AXIS B00001000 #define JOYSTICK_INCLUDE_RY_AXIS B00010000 #define JOYSTICK_INCLUDE_RZ_AXIS B00100000 -#define JOYSTICK_INCLUDE_RUDDER B00000001 -#define JOYSTICK_INCLUDE_THROTTLE B00000010 +#define JOYSTICK_INCLUDE_RUDDER B00000001 +#define JOYSTICK_INCLUDE_THROTTLE B00000010 #define JOYSTICK_INCLUDE_ACCELERATOR B00000100 -#define JOYSTICK_INCLUDE_BRAKE B00001000 -#define JOYSTICK_INCLUDE_STEERING B00010000 +#define JOYSTICK_INCLUDE_BRAKE B00001000 +#define JOYSTICK_INCLUDE_STEERING B00010000 Joystick_::Joystick_( uint8_t hidReportId, uint8_t joystickType, - uint8_t buttonCount, + uint8_t buttonCount, uint8_t hatSwitchCount, + uint8_t throttleCount, bool includeXAxis, bool includeYAxis, bool includeZAxis, @@ -53,17 +54,18 @@ Joystick_::Joystick_( bool includeRyAxis, bool includeRzAxis, bool includeRudder, - bool includeThrottle, + // bool includeThrottle, bool includeAccelerator, bool includeBrake, bool includeSteering) { - // Set the USB HID Report ID - _hidReportId = hidReportId; + // Set the USB HID Report ID + _hidReportId = hidReportId; - // Save Joystick Settings - _buttonCount = buttonCount; + // Save Joystick Settings + _buttonCount = buttonCount; _hatSwitchCount = hatSwitchCount; + _throttleCount = throttleCount; _includeAxisFlags = 0; _includeAxisFlags |= (includeXAxis ? JOYSTICK_INCLUDE_X_AXIS : 0); _includeAxisFlags |= (includeYAxis ? JOYSTICK_INCLUDE_Y_AXIS : 0); @@ -73,13 +75,13 @@ Joystick_::Joystick_( _includeAxisFlags |= (includeRzAxis ? JOYSTICK_INCLUDE_RZ_AXIS : 0); _includeSimulatorFlags = 0; _includeSimulatorFlags |= (includeRudder ? JOYSTICK_INCLUDE_RUDDER : 0); - _includeSimulatorFlags |= (includeThrottle ? JOYSTICK_INCLUDE_THROTTLE : 0); + _includeSimulatorFlags |= ((throttleCount>0) ? JOYSTICK_INCLUDE_THROTTLE : 0); _includeSimulatorFlags |= (includeAccelerator ? JOYSTICK_INCLUDE_ACCELERATOR : 0); _includeSimulatorFlags |= (includeBrake ? JOYSTICK_INCLUDE_BRAKE : 0); _includeSimulatorFlags |= (includeSteering ? JOYSTICK_INCLUDE_STEERING : 0); - - // Build Joystick HID Report Description - + + // Build Joystick HID Report Description + // Button Calculations uint8_t buttonsInLastByte = _buttonCount % 8; uint8_t buttonPaddingBits = 0; @@ -87,41 +89,33 @@ Joystick_::Joystick_( { buttonPaddingBits = 8 - buttonsInLastByte; } - + // Axis Calculations - uint8_t axisCount = (includeXAxis == true) - + (includeYAxis == true) - + (includeZAxis == true) - + (includeRxAxis == true) - + (includeRyAxis == true) - + (includeRzAxis == true); - - uint8_t simulationCount = (includeRudder == true) - + (includeThrottle == true) - + (includeAccelerator == true) - + (includeBrake == true) - + (includeSteering == true); - - uint8_t tempHidReportDescriptor[150]; - int hidReportDescriptorSize = 0; - - // USAGE_PAGE (Generic Desktop) - tempHidReportDescriptor[hidReportDescriptorSize++] = 0x05; - tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01; - - // USAGE (Joystick - 0x04; Gamepad - 0x05; Multi-axis Controller - 0x08) - tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; - tempHidReportDescriptor[hidReportDescriptorSize++] = joystickType; - - // COLLECTION (Application) - tempHidReportDescriptor[hidReportDescriptorSize++] = 0xa1; - tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01; - - // REPORT_ID (Default: 3) - tempHidReportDescriptor[hidReportDescriptorSize++] = 0x85; - tempHidReportDescriptor[hidReportDescriptorSize++] = _hidReportId; - - if (_buttonCount > 0) { + uint8_t axisCount = (includeXAxis == true) + (includeYAxis == true) + (includeZAxis == true) + (includeRxAxis == true) + (includeRyAxis == true) + (includeRzAxis == true); + + uint8_t simulationCount = (includeRudder == true) + _throttleCount + (includeAccelerator == true) + (includeBrake == true) + (includeSteering == true); + + uint8_t tempHidReportDescriptor[150]; + int hidReportDescriptorSize = 0; + + // USAGE_PAGE (Generic Desktop) + tempHidReportDescriptor[hidReportDescriptorSize++] = 0x05; + tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01; + + // USAGE (Joystick - 0x04; Gamepad - 0x05; Multi-axis Controller - 0x08) + tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; + tempHidReportDescriptor[hidReportDescriptorSize++] = joystickType; + + // COLLECTION (Application) + tempHidReportDescriptor[hidReportDescriptorSize++] = 0xa1; + tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01; + + // REPORT_ID (Default: 3) + tempHidReportDescriptor[hidReportDescriptorSize++] = 0x85; + tempHidReportDescriptor[hidReportDescriptorSize++] = _hidReportId; + + if (_buttonCount > 0) + { // USAGE_PAGE (Button) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x05; @@ -131,7 +125,7 @@ Joystick_::Joystick_( tempHidReportDescriptor[hidReportDescriptorSize++] = 0x19; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01; - // USAGE_MAXIMUM (Button 32) + // USAGE_MAXIMUM (Button 32) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x29; tempHidReportDescriptor[hidReportDescriptorSize++] = _buttonCount; @@ -163,8 +157,9 @@ Joystick_::Joystick_( tempHidReportDescriptor[hidReportDescriptorSize++] = 0x81; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x02; - if (buttonPaddingBits > 0) { - + if (buttonPaddingBits > 0) + { + // REPORT_SIZE (1) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x75; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01; @@ -172,24 +167,25 @@ Joystick_::Joystick_( // REPORT_COUNT (# of padding bits) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x95; tempHidReportDescriptor[hidReportDescriptorSize++] = buttonPaddingBits; - + // INPUT (Const,Var,Abs) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x81; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x03; - + } // Padding Bits Needed } // Buttons - if ((axisCount > 0) || (_hatSwitchCount > 0)) { - + if ((axisCount > 0) || (_hatSwitchCount > 0)) + { + // USAGE_PAGE (Generic Desktop) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x05; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01; - } - if (_hatSwitchCount > 0) { + if (_hatSwitchCount > 0) + { // USAGE (Hat Switch) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; @@ -223,13 +219,14 @@ Joystick_::Joystick_( // REPORT_COUNT (1) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x95; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01; - + // INPUT (Data,Var,Abs) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x81; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x02; - - if (_hatSwitchCount > 1) { - + + if (_hatSwitchCount > 1) + { + // USAGE (Hat Switch) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x39; @@ -262,15 +259,16 @@ Joystick_::Joystick_( // REPORT_COUNT (1) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x95; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01; - + // INPUT (Data,Var,Abs) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x81; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x02; - - } else { - + } + else + { + // Use Padding Bits - + // REPORT_SIZE (1) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x75; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01; @@ -278,17 +276,18 @@ Joystick_::Joystick_( // REPORT_COUNT (4) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x95; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x04; - + // INPUT (Const,Var,Abs) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x81; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x03; - + } // One or Two Hat Switches? } // Hat Switches - if (axisCount > 0) { - + if (axisCount > 0) + { + // USAGE (Pointer) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x01; @@ -311,62 +310,69 @@ Joystick_::Joystick_( // REPORT_COUNT (axisCount) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x95; tempHidReportDescriptor[hidReportDescriptorSize++] = axisCount; - + // COLLECTION (Physical) tempHidReportDescriptor[hidReportDescriptorSize++] = 0xA1; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x00; - if (includeXAxis == true) { + if (includeXAxis == true) + { // USAGE (X) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x30; } - if (includeYAxis == true) { + if (includeYAxis == true) + { // USAGE (Y) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x31; } - - if (includeZAxis == true) { + + if (includeZAxis == true) + { // USAGE (Z) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x32; } - - if (includeRxAxis == true) { + + if (includeRxAxis == true) + { // USAGE (Rx) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x33; } - - if (includeRyAxis == true) { + + if (includeRyAxis == true) + { // USAGE (Ry) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x34; } - - if (includeRzAxis == true) { + + if (includeRzAxis == true) + { // USAGE (Rz) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x35; } - + // INPUT (Data,Var,Abs) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x81; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x02; - + // END_COLLECTION (Physical) tempHidReportDescriptor[hidReportDescriptorSize++] = 0xc0; - - } // X, Y, Z, Rx, Ry, and Rz Axis - - if (simulationCount > 0) { - + + } // X, Y, Z, Rx, Ry, and Rz Axis + + if (simulationCount > 0) + { + // USAGE_PAGE (Simulation Controls) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x05; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x02; - + // LOGICAL_MINIMUM (0) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x15; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x00; @@ -390,31 +396,39 @@ Joystick_::Joystick_( tempHidReportDescriptor[hidReportDescriptorSize++] = 0xA1; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x00; - if (includeRudder == true) { + if (includeRudder == true) + { // USAGE (Rudder) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; tempHidReportDescriptor[hidReportDescriptorSize++] = 0xBA; } - if (includeThrottle == true) { + // if (includeThrottle == true) + // { + for (int index = 0; index < _throttleCount; index++) + { // USAGE (Throttle) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; tempHidReportDescriptor[hidReportDescriptorSize++] = 0xBB; } + // } - if (includeAccelerator == true) { + if (includeAccelerator == true) + { // USAGE (Accelerator) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; tempHidReportDescriptor[hidReportDescriptorSize++] = 0xC4; } - if (includeBrake == true) { + if (includeBrake == true) + { // USAGE (Brake) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; tempHidReportDescriptor[hidReportDescriptorSize++] = 0xC5; } - if (includeSteering == true) { + if (includeSteering == true) + { // USAGE (Steering) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x09; tempHidReportDescriptor[hidReportDescriptorSize++] = 0xC8; @@ -423,38 +437,40 @@ Joystick_::Joystick_( // INPUT (Data,Var,Abs) tempHidReportDescriptor[hidReportDescriptorSize++] = 0x81; tempHidReportDescriptor[hidReportDescriptorSize++] = 0x02; - + // END_COLLECTION (Physical) tempHidReportDescriptor[hidReportDescriptorSize++] = 0xc0; - + } // Simulation Controls - // END_COLLECTION - tempHidReportDescriptor[hidReportDescriptorSize++] = 0xc0; + // END_COLLECTION + tempHidReportDescriptor[hidReportDescriptorSize++] = 0xc0; // Create a copy of the HID Report Descriptor template that is just the right size uint8_t *customHidReportDescriptor = new uint8_t[hidReportDescriptorSize]; memcpy(customHidReportDescriptor, tempHidReportDescriptor, hidReportDescriptorSize); - + // Register HID Report Description DynamicHIDSubDescriptor *node = new DynamicHIDSubDescriptor(customHidReportDescriptor, hidReportDescriptorSize, false); DynamicHID().AppendDescriptor(node); - - // Setup Joystick State - if (buttonCount > 0) { + + // Setup Joystick State + if (buttonCount > 0) + { _buttonValuesArraySize = _buttonCount / 8; - if ((_buttonCount % 8) > 0) { + if ((_buttonCount % 8) > 0) + { _buttonValuesArraySize++; } _buttonValues = new uint8_t[_buttonValuesArraySize]; } - + // Calculate HID Report Size _hidReportSize = _buttonValuesArraySize; _hidReportSize += (_hatSwitchCount > 0); _hidReportSize += (axisCount * 2); _hidReportSize += (simulationCount * 2); - + // Initialize Joystick State _xAxis = 0; _yAxis = 0; @@ -462,7 +478,10 @@ Joystick_::Joystick_( _xAxisRotation = 0; _yAxisRotation = 0; _zAxisRotation = 0; - _throttle = 0; + for (int index = 0; index < JOYSTICK_THROTTLE_COUNT_MAXIMUM; index++) + { + _throttle[index] = 0; + } _rudder = 0; _accelerator = 0; _brake = 0; @@ -471,10 +490,10 @@ Joystick_::Joystick_( { _hatSwitchValues[index] = JOYSTICK_HATSWITCH_RELEASE; } - for (int index = 0; index < _buttonValuesArraySize; index++) - { - _buttonValues[index] = 0; - } + for (int index = 0; index < _buttonValuesArraySize; index++) + { + _buttonValues[index] = 0; + } } void Joystick_::begin(bool initAutoSendState) @@ -500,92 +519,109 @@ void Joystick_::setButton(uint8_t button, uint8_t value) } void Joystick_::pressButton(uint8_t button) { - if (button >= _buttonCount) return; + if (button >= _buttonCount) + return; - int index = button / 8; - int bit = button % 8; + int index = button / 8; + int bit = button % 8; bitSet(_buttonValues[index], bit); - if (_autoSendState) sendState(); + if (_autoSendState) + sendState(); } void Joystick_::releaseButton(uint8_t button) { - if (button >= _buttonCount) return; + if (button >= _buttonCount) + return; - int index = button / 8; - int bit = button % 8; + int index = button / 8; + int bit = button % 8; - bitClear(_buttonValues[index], bit); - if (_autoSendState) sendState(); + bitClear(_buttonValues[index], bit); + if (_autoSendState) + sendState(); } void Joystick_::setXAxis(int32_t value) { _xAxis = value; - if (_autoSendState) sendState(); + if (_autoSendState) + sendState(); } void Joystick_::setYAxis(int32_t value) { _yAxis = value; - if (_autoSendState) sendState(); + if (_autoSendState) + sendState(); } void Joystick_::setZAxis(int32_t value) { _zAxis = value; - if (_autoSendState) sendState(); + if (_autoSendState) + sendState(); } void Joystick_::setRxAxis(int32_t value) { _xAxisRotation = value; - if (_autoSendState) sendState(); + if (_autoSendState) + sendState(); } void Joystick_::setRyAxis(int32_t value) { _yAxisRotation = value; - if (_autoSendState) sendState(); + if (_autoSendState) + sendState(); } void Joystick_::setRzAxis(int32_t value) { _zAxisRotation = value; - if (_autoSendState) sendState(); + if (_autoSendState) + sendState(); } void Joystick_::setRudder(int32_t value) { _rudder = value; - if (_autoSendState) sendState(); + if (_autoSendState) + sendState(); } -void Joystick_::setThrottle(int32_t value) +void Joystick_::setThrottle(int8_t throttle, int32_t value) { - _throttle = value; - if (_autoSendState) sendState(); + _throttle[throttle] = value; + if (_autoSendState) + sendState(); } void Joystick_::setAccelerator(int32_t value) { _accelerator = value; - if (_autoSendState) sendState(); + if (_autoSendState) + sendState(); } void Joystick_::setBrake(int32_t value) { _brake = value; - if (_autoSendState) sendState(); + if (_autoSendState) + sendState(); } void Joystick_::setSteering(int32_t value) { _steering = value; - if (_autoSendState) sendState(); + if (_autoSendState) + sendState(); } void Joystick_::setHatSwitch(int8_t hatSwitchIndex, int16_t value) { - if (hatSwitchIndex >= _hatSwitchCount) return; - + if (hatSwitchIndex >= _hatSwitchCount) + return; + _hatSwitchValues[hatSwitchIndex] = value; - if (_autoSendState) sendState(); + if (_autoSendState) + sendState(); } -int Joystick_::buildAndSet16BitValue(bool includeValue, int32_t value, int32_t valueMinimum, int32_t valueMaximum, int32_t actualMinimum, int32_t actualMaximum, uint8_t dataLocation[]) +int Joystick_::buildAndSet16BitValue(bool includeValue, int32_t value, int32_t valueMinimum, int32_t valueMaximum, int32_t actualMinimum, int32_t actualMaximum, uint8_t dataLocation[]) { int32_t convertedValue; uint8_t highByte; @@ -593,16 +629,20 @@ int Joystick_::buildAndSet16BitValue(bool includeValue, int32_t value, int32_t v int32_t realMinimum = min(valueMinimum, valueMaximum); int32_t realMaximum = max(valueMinimum, valueMaximum); - if (includeValue == false) return 0; + if (includeValue == false) + return 0; - if (value < realMinimum) { + if (value < realMinimum) + { value = realMinimum; } - if (value > realMaximum) { + if (value > realMaximum) + { value = realMaximum; } - if (valueMinimum > valueMaximum) { + if (valueMinimum > valueMaximum) + { // Values go from a larger number to a smaller number (e.g. 1024 to 0) value = realMaximum - value + realMinimum; } @@ -611,19 +651,19 @@ int Joystick_::buildAndSet16BitValue(bool includeValue, int32_t value, int32_t v highByte = (uint8_t)(convertedValue >> 8); lowByte = (uint8_t)(convertedValue & 0x00FF); - + dataLocation[0] = lowByte; dataLocation[1] = highByte; - + return 2; } -int Joystick_::buildAndSetAxisValue(bool includeAxis, int32_t axisValue, int32_t axisMinimum, int32_t axisMaximum, uint8_t dataLocation[]) +int Joystick_::buildAndSetAxisValue(bool includeAxis, int32_t axisValue, int32_t axisMinimum, int32_t axisMaximum, uint8_t dataLocation[]) { return buildAndSet16BitValue(includeAxis, axisValue, axisMinimum, axisMaximum, JOYSTICK_AXIS_MINIMUM, JOYSTICK_AXIS_MAXIMUM, dataLocation); } -int Joystick_::buildAndSetSimulationValue(bool includeValue, int32_t value, int32_t valueMinimum, int32_t valueMaximum, uint8_t dataLocation[]) +int Joystick_::buildAndSetSimulationValue(bool includeValue, int32_t value, int32_t valueMinimum, int32_t valueMaximum, uint8_t dataLocation[]) { return buildAndSet16BitValue(includeValue, value, valueMinimum, valueMaximum, JOYSTICK_SIMULATOR_MINIMUM, JOYSTICK_SIMULATOR_MAXIMUM, dataLocation); } @@ -632,16 +672,17 @@ void Joystick_::sendState() { uint8_t data[_hidReportSize]; int index = 0; - + // Load Button State for (; index < _buttonValuesArraySize; index++) { - data[index] = _buttonValues[index]; + data[index] = _buttonValues[index]; } // Set Hat Switch Values - if (_hatSwitchCount > 0) { - + if (_hatSwitchCount > 0) + { + // Calculate hat-switch values uint8_t convertedHatSwitch[JOYSTICK_HATSWITCH_COUNT_MAXIMUM]; for (int hatSwitchIndex = 0; hatSwitchIndex < JOYSTICK_HATSWITCH_COUNT_MAXIMUM; hatSwitchIndex++) @@ -653,12 +694,12 @@ void Joystick_::sendState() else { convertedHatSwitch[hatSwitchIndex] = (_hatSwitchValues[hatSwitchIndex] % 360) / 45; - } + } } // Pack hat-switch states into a single byte data[index++] = (convertedHatSwitch[1] << 4) | (B00001111 & convertedHatSwitch[0]); - + } // Hat Switches // Set Axis Values @@ -668,10 +709,15 @@ void Joystick_::sendState() index += buildAndSetAxisValue(_includeAxisFlags & JOYSTICK_INCLUDE_RX_AXIS, _xAxisRotation, _rxAxisMinimum, _rxAxisMaximum, &(data[index])); index += buildAndSetAxisValue(_includeAxisFlags & JOYSTICK_INCLUDE_RY_AXIS, _yAxisRotation, _ryAxisMinimum, _ryAxisMaximum, &(data[index])); index += buildAndSetAxisValue(_includeAxisFlags & JOYSTICK_INCLUDE_RZ_AXIS, _zAxisRotation, _rzAxisMinimum, _rzAxisMaximum, &(data[index])); - + // Set Simulation Values index += buildAndSetSimulationValue(_includeSimulatorFlags & JOYSTICK_INCLUDE_RUDDER, _rudder, _rudderMinimum, _rudderMaximum, &(data[index])); - index += buildAndSetSimulationValue(_includeSimulatorFlags & JOYSTICK_INCLUDE_THROTTLE, _throttle, _throttleMinimum, _throttleMaximum, &(data[index])); + // Load Throttle State + for (int t_index = 0; t_index < _throttleCount; t_index++) + { + index += buildAndSetSimulationValue(_includeSimulatorFlags & JOYSTICK_INCLUDE_THROTTLE, _throttle[t_index], _throttleMinimum, _throttleMaximum, &(data[index])); + } + // index += buildAndSetSimulationValue(_includeSimulatorFlags & JOYSTICK_INCLUDE_THROTTLE, _throttle, _throttleMinimum, _throttleMaximum, &(data[index])); index += buildAndSetSimulationValue(_includeSimulatorFlags & JOYSTICK_INCLUDE_ACCELERATOR, _accelerator, _acceleratorMinimum, _acceleratorMaximum, &(data[index])); index += buildAndSetSimulationValue(_includeSimulatorFlags & JOYSTICK_INCLUDE_BRAKE, _brake, _brakeMinimum, _brakeMaximum, &(data[index])); index += buildAndSetSimulationValue(_includeSimulatorFlags & JOYSTICK_INCLUDE_STEERING, _steering, _steeringMinimum, _steeringMaximum, &(data[index])); diff --git a/src/Joystick.h b/src/Joystick.h index de4900b..0f4b7c8 100644 --- a/src/Joystick.h +++ b/src/Joystick.h @@ -51,6 +51,8 @@ #define JOYSTICK_DEFAULT_HATSWITCH_COUNT 2 #define JOYSTICK_HATSWITCH_COUNT_MAXIMUM 2 #define JOYSTICK_HATSWITCH_RELEASE -1 +#define JOYSTICK_DEFAULT_THROTTLE_COUNT 1 +#define JOYSTICK_THROTTLE_COUNT_MAXIMUM 2 #define JOYSTICK_TYPE_JOYSTICK 0x04 #define JOYSTICK_TYPE_GAMEPAD 0x05 #define JOYSTICK_TYPE_MULTI_AXIS 0x08 @@ -66,7 +68,7 @@ class Joystick_ int32_t _xAxisRotation; int32_t _yAxisRotation; int32_t _zAxisRotation; - int32_t _throttle; + int32_t _throttle[JOYSTICK_THROTTLE_COUNT_MAXIMUM]; int32_t _rudder; int32_t _accelerator; int32_t _brake; @@ -79,6 +81,7 @@ class Joystick_ uint8_t _buttonCount; uint8_t _buttonValuesArraySize = 0; uint8_t _hatSwitchCount; + uint8_t _throttleCount; uint8_t _includeAxisFlags; uint8_t _includeSimulatorFlags; int32_t _xAxisMinimum = JOYSTICK_DEFAULT_AXIS_MINIMUM; @@ -118,6 +121,7 @@ class Joystick_ uint8_t joystickType = JOYSTICK_TYPE_JOYSTICK, uint8_t buttonCount = JOYSTICK_DEFAULT_BUTTON_COUNT, uint8_t hatSwitchCount = JOYSTICK_DEFAULT_HATSWITCH_COUNT, + uint8_t throttleCount = JOYSTICK_DEFAULT_THROTTLE_COUNT, bool includeXAxis = true, bool includeYAxis = true, bool includeZAxis = true, @@ -125,7 +129,7 @@ class Joystick_ bool includeRyAxis = true, bool includeRzAxis = true, bool includeRudder = true, - bool includeThrottle = true, + //bool includeThrottle = true, bool includeAccelerator = true, bool includeBrake = true, bool includeSteering = true); @@ -200,7 +204,7 @@ class Joystick_ // Set Simulation Values void setRudder(int32_t value); - void setThrottle(int32_t value); + void setThrottle(int8_t throttle, int32_t value); void setAccelerator(int32_t value); void setBrake(int32_t value); void setSteering(int32_t value); From 612ac0ab8b1d1990632587d557462a3b604cf9c7 Mon Sep 17 00:00:00 2001 From: Asi Sapir Date: Wed, 7 Dec 2022 15:34:52 +0200 Subject: [PATCH 2/2] Update README file --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7801179..6efe7ae 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Constructor used to initialize and setup the Joystick. The following optional pa - `JOYSTICK_TYPE_MULTI_AXIS` or `0x08` - Multi-axis Controller - `uint8_t buttonCount` - Default: `32` - Indicates how many buttons will be available on the joystick. - `uint8_t hatSwitchCount` - Default: `2` - Indicates how many hat switches will be available on the joystick. Range: `0` - `2` +- `uint8_t throttleCount` - Default: `1` - Indicates how many hat throttles will be available on the joystick. Range: `0` - `2` - `bool includeXAxis` - Default: `true` - Indicates if the X Axis is available on the joystick. - `bool includeYAxis` - Default: `true` - Indicates if the Y Axis is available on the joystick. - `bool includeZAxis` - Default: `true` - Indicates if the Z Axis (in some situations this is the right X Axis) is available on the joystick. @@ -104,7 +105,6 @@ Constructor used to initialize and setup the Joystick. The following optional pa - `bool includeRyAxis` - Default: `true` - Indicates if the Y Axis Rotation is available on the joystick. - `bool includeRzAxis` - Default: `true` - Indicates if the Z Axis Rotation is available on the joystick. - `bool includeRudder` - Default: `true` - Indicates if the Rudder is available on the joystick. -- `bool includeThrottle` - Default: `true` - Indicates if the Throttle is available on the joystick. - `bool includeAccelerator` - Default: `true` - Indicates if the Accelerator is available on the joystick. - `bool includeBrake` - Default: `true` - Indicates if the Brake is available on the joystick. - `bool includeSteering` - Default: `true` - Indicates if the Steering is available on the joystick. @@ -114,6 +114,7 @@ The following constants define the default values for the constructor parameters - `JOYSTICK_DEFAULT_REPORT_ID` is set to `0x03` - `JOYSTICK_DEFAULT_BUTTON_COUNT` is set to `32` - `JOYSTICK_DEFAULT_HATSWITCH_COUNT` is set to `2` +- `JOYSTICK_DEFAULT_THROTTLE_COUNT` is set to `1` ### Joystick.begin(bool initAutoSendState) @@ -183,9 +184,9 @@ Sets the Rudder value. See `setRudderRange` for the range. Sets the range of values that will be used for the Throttle. Default: `0` to `1023` -### Joystick.setThrottle(int32_t value) +### Joystick.setThrottle(int8_t throttle, int32_t value) -Sets the Throttle value. See `setThrottleRange` for the range. +Sets the value of the specified throttle. See `setThrottleRange` for the range. ### Joystick.setAcceleratorRange(int32_t minimum, int32_t maximum)