USB joystick patch

Hi,
I have a Mega and a USB host shield and would like to use a USB joystick (T.16000M) to control two hobby servo motors.
Can somebody please show me how to make a patch for this setup?

Regards,

Brian

So, I’ve been able to write to code for the joystick.

Can someone give me some guidelines how to make a patch for the code?

/* Simplified Thrustmaster T.16000M FCS Joystick Report Parser */

#include <usbhid.h>
#include <hiduniversal.h>
#include <usbhub.h>
#include <Servo.h>

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#include <SPI.h>

#endif

// Thrustmaster T.16000M HID report
struct GamePadEventData
{
uint16_t buttons;
uint8_t hat;
uint16_t x;
uint16_t y;
uint8_t z;
uint8_t slider;
} attribute((packed));

class JoystickEvents
{
public:
virtual void OnGamePadChanged(const GamePadEventData *evt);
};

#define RPT_GAMEPAD_LEN sizeof(GamePadEventData)

class JoystickReportParser : public HIDReportParser
{
JoystickEvents *joyEvents;

uint8_t oldPad[RPT_GAMEPAD_LEN];

public:
JoystickReportParser(JoystickEvents *evt);

virtual void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);

};

JoystickReportParser::JoystickReportParser(JoystickEvents *evt) :
joyEvents(evt)
{}

void JoystickReportParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
{
// Checking if there are changes in report since the method was last called
bool match = (sizeof(oldPad) == len) && (memcmp(oldPad, buf, len) == 0);

// Calling Game Pad event handler
if (!match && joyEvents) {
joyEvents->OnGamePadChanged((const GamePadEventData*)buf);
memcpy(oldPad, buf, len);
}
}

//Value used to hold last reading from the joystick. Also used to set the servo starting position (range 0 to 16383)
uint16_t LastJoyX = 8192;
uint16_t LastJoyY = 8192;
uint8_t LastJoyZ = 128;
uint8_t LastSlider = 700;

//Button names:
#define BUTTON_A 0
#define BUTTON_B 1
#define BUTTON_C 2
#define BUTTON_D 3
#define HAT_UP 0
#define HAT_RIGHT 2
#define HAT_DOWN 4
#define HAT_LEFT 6

void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt)
{
//Store value from joystick to global variable
LastJoyX = evt->x;
LastJoyY = evt->y;
LastJoyZ = evt->z;
LastSlider = evt->slider;

//TEST BENCH FOR JOYSTICK AXIS / BUTTON VALUES ---------------
//INSERT “struct GamePadEventData” NAME:

//Serial.print(" SLIDER: ");
//Serial.println(evt->slider);
//Serial.println();
//Center: 111111
//Up : 0
//Right : 10
//Down : 100
//Left : 110

//BUTTON_A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
if (bitRead(evt->buttons, BUTTON_A))
{
//Button A is pressed…
Serial.print(" Button_A State: “);
Serial.println((bitRead(evt->buttons, BUTTON_A)));
Serial.println();
digitalWrite(13, HIGH);
}
else
{
//Button_A is released…
Serial.print(” Button_A State: “);
Serial.println((bitRead(evt->buttons, BUTTON_A)));
Serial.println();
digitalWrite(13, LOW);
}
//BUTTON_B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
if (bitRead(evt->buttons, BUTTON_B))
{
//Button B is pressed…
Serial.print(” Button_B State: “);
Serial.println((bitRead(evt->buttons, BUTTON_B)));
Serial.println();
//digitalWrite(12, HIGH);
}
else
{
//Button_B is released…
Serial.print(” Button_B State: “);
Serial.println((bitRead(evt->buttons, BUTTON_B)));
Serial.println();
//digitalWrite(12, LOW);
}
//BUTTON_C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
if (bitRead(evt->buttons, BUTTON_C))
{
//Button C is pressed…
Serial.print(” Button_C State: “);
Serial.println((bitRead(evt->buttons, BUTTON_C)));
Serial.println();
//digitalWrite(11, HIGH);
}
else
{
//Button_C is released…
Serial.print(” Button_C State: “);
Serial.println((bitRead(evt->buttons, BUTTON_C)));
Serial.println();
//digitalWrite(11, LOW);
}
//BUTTON_D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
if (bitRead(evt->buttons, BUTTON_D))
{
//Button D is pressed…
Serial.print(” Button_D State: “);
Serial.println((bitRead(evt->buttons, BUTTON_D)));
Serial.println();
digitalWrite(10, HIGH);
}
else
{
//Button_D is released…
Serial.print(” Button_D State: “);
Serial.println((bitRead(evt->buttons, BUTTON_D)));
Serial.println();
digitalWrite(10, LOW);
}
//HAT_UP UPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUP
if (evt->hat == 0)
{
//HAT_UP is pressed…
Serial.print(” HAT_UP State: “);
Serial.println(evt->hat);
Serial.println();
digitalWrite(12, HIGH);
}
else
{
//HAT_UP is released…
Serial.print(” HAT_UP State: “);
Serial.println(evt->hat);
Serial.println();
digitalWrite(12, LOW);
}
//HAT_DOWN DOWNDOWNDOWNDOWNDOWNDOWNDOWNDOWNDOWNDOWNDOWNDOWN
if (evt->hat == 4)
{
//HAT_DOWN is pressed…
Serial.print(” HAT_DOWN State: “);
Serial.println(evt->hat);
Serial.println();
digitalWrite(11, HIGH);
}
else
{
//HAT_DOWN is released…
Serial.print(” HAT_DOWN State: ");
Serial.println(evt->hat);
Serial.println();
digitalWrite(11, LOW);
}

}

USB Usb;
USBHub Hub(&Usb);
HIDUniversal Hid(&Usb);
JoystickEvents JoyEvents;
JoystickReportParser Joy(&JoyEvents);

Servo ServoX; // Create servo object to control a servo
Servo ServoY; // Create servo object to control a servo
Servo ServoZ; // Create servo object to control a servo
Servo ServoSlider; // Create servo object to control a servo

void setup()
{

//ServoX.attach(8); // Attaches the servo on pin 8 to the servo object
ServoY.attach(7); // Attaches the servo on pin 7 to the servo object
ServoZ.attach(6); // Attaches the servo on pin 6 to the servo object
ServoSlider.attach(8); // Attaches the servo on pin 8 to the servo object

pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
pinMode(10, OUTPUT);

ServoSlider.writeMicroseconds(LastSlider);

Serial.begin( 115200 );
#if !defined(MIPSEL)
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
Serial.println(“Start”);

if (Usb.Init() == -1)
Serial.println(“OSC did not start.”);

delay( 200 );

if (!Hid.SetReportParser(0, &Joy))
ErrorMessage<uint8_t>(PSTR(“SetReportParser”), 1 );
}

void loop()
{
Usb.Task();

//Write LastJoyX to the servo:
int JoyXmapped = map(LastJoyX, 0, 16383, 700, 2300); // Maps joystick range to servo (microseconds) range
ServoX.writeMicroseconds(JoyXmapped); // sets the servo position according to the scaled value. See “uint16_t LastJoyX =” for servo center position

//Write LastJoyY to the servo:
int JoyYmapped = map(LastJoyY, 0, 16383, 2000, 1000); // Maps joystick range to servo (microseconds) range
ServoY.writeMicroseconds(JoyYmapped); // sets the servo position according to the scaled value. See “uint16_t LastJoyX =” for servo center position

//Write LastJoyY to the servo:
int JoyZmapped = map(LastJoyZ, 0, 255, 2000, 1000); // Maps joystick range to servo (microseconds) range
ServoZ.writeMicroseconds(JoyZmapped); // sets the servo position according to the scaled value. See “uint8_t LastJoyX =” for servo center position

//Write LastSlider to the servo:
int SliderMapped = map(LastSlider, 255, 0, 700, 2300); // Maps joystick range to servo (microseconds) range
ServoSlider.writeMicroseconds(SliderMapped); // sets the servo position according to the scaled value. See “uint16_t LastJoyX =” for servo center position

if (JoyXmapped != 1500) {
Serial.print(" X: ");
Serial.println(JoyXmapped);

}
if (JoyYmapped != 1500) {
Serial.print(" Y: “);
Serial.println(JoyYmapped);
}
if (JoyZmapped != 1499) {
Serial.print(” Z: ");
Serial.println(JoyZmapped);
}

Serial.println(SliderMapped);
Serial.println();

delay(20); // waits for the servo to get there
}

At the moment, there are no libraries for USB HOST shields/modules and for HID devices. So a patch for your code is very difficult. However, you can try to port the Arduino library for HID devices into XOD by yourself. Wrapping Class-based Arduino Libraries.