I want to make a project to control my robot car with a Logitech joystick ( this is the picture of it : ).
Thus, I bought a USB Host Shield Arduino and I bought a Logitech Extreme 3D Pro Joystick. I have DC Motor Driver 2x 15A to make motors to move.
I downloaded the latest version of library from here: USB Host Shield Library 2.0 - Arduino Libraries.
From the library, there is an example to see the values we are getting from the joystick sticks and buttons on our arduino serial monitor. You can see the example file and its cpp and h files from here yourself too: USB_Host_Shield_2.0/examples/HID/USBHIDJoystick at master · felis/USB_Host_Shield_2.0 · GitHub. I am going to post the same example from the given link too and then ask my question to you.
USBHIDJoystick.ino sketch:
#include <usbhid.h>
#include <hiduniversal.h>
#include <usbhub.h>
// Satisfy IDE, which only needs to see the include statment in the ino.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>
#include "hidjoystickrptparser.h"
USB Usb;
USBHub Hub(&Usb);
HIDUniversal Hid(&Usb);
JoystickEvents JoyEvents;
JoystickReportParser Joy(&JoyEvents);
void setup() {
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();
}
Sketch's cpp file:
#include "hidjoystickrptparser.h"
JoystickReportParser::JoystickReportParser(JoystickEvents *evt) :
joyEvents(evt),
oldHat(0xDE),
oldButtons(0) {
for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++)
oldPad[i] = 0xD;
}
void JoystickReportParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
bool match = true;
// Checking if there are changes in report since the method was last called
for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++)
if (buf[i] != oldPad[i]) {
match = false;
break;
}
// Calling Game Pad event handler
if (!match && joyEvents) {
joyEvents->OnGamePadChanged((const GamePadEventData*)buf);
for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++) oldPad[i] = buf[i];
}
uint8_t hat = (buf[5] & 0xF);
// Calling Hat Switch event handler
if (hat != oldHat && joyEvents) {
joyEvents->OnHatSwitch(hat);
oldHat = hat;
}
uint16_t buttons = (0x0000 | buf[6]);
buttons <<= 4;
buttons |= (buf[5] >> 4);
uint16_t changes = (buttons ^ oldButtons);
// Calling Button Event Handler for every button changed
if (changes) {
for (uint8_t i = 0; i < 0x0C; i++) {
uint16_t mask = (0x0001 << i);
if (((mask & changes) > 0) && joyEvents) {
if ((buttons & mask) > 0)
joyEvents->OnButtonDn(i + 1);
else
joyEvents->OnButtonUp(i + 1);
}
}
oldButtons = buttons;
}
}
void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt) {
Serial.print("X1: ");
PrintHex<uint8_t > (evt->X, 0x80);
Serial.print("\tY1: ");
PrintHex<uint8_t > (evt->Y, 0x80);
Serial.print("\tX2: ");
PrintHex<uint8_t > (evt->Z1, 0x80);
Serial.print("\tY2: ");
PrintHex<uint8_t > (evt->Z2, 0x80);
Serial.print("\tRz: ");
PrintHex<uint8_t > (evt->Rz, 0x80);
Serial.println("");
}
void JoystickEvents::OnHatSwitch(uint8_t hat) {
Serial.print("Hat Switch: ");
PrintHex<uint8_t > (hat, 0x80);
Serial.println("");
}
void JoystickEvents::OnButtonUp(uint8_t but_id) {
Serial.print("Up: ");
Serial.println(but_id, DEC);
}
void JoystickEvents::OnButtonDn(uint8_t but_id) {
Serial.print("Dn: ");
Serial.println(but_id, DEC);
}
Sketch's h file:
#if !defined(__HIDJOYSTICKRPTPARSER_H__)
#define __HIDJOYSTICKRPTPARSER_H__
#include <usbhid.h>
struct GamePadEventData {
uint8_t X, Y, Z1, Z2, Rz;
};
class JoystickEvents {
public:
virtual void OnGamePadChanged(const GamePadEventData *evt);
virtual void OnHatSwitch(uint8_t hat);
virtual void OnButtonUp(uint8_t but_id);
virtual void OnButtonDn(uint8_t but_id);
};
#define RPT_GEMEPAD_LEN 5
class JoystickReportParser : public HIDReportParser {
JoystickEvents *joyEvents;
uint8_t oldPad[RPT_GEMEPAD_LEN];
uint8_t oldHat;
uint16_t oldButtons;
public:
JoystickReportParser(JoystickEvents *evt);
virtual void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
};
#endif // __HIDJOYSTICKRPTPARSER_H__
This is the code from cpp file we print the data values we get from joystick to serial monitor at arduino:
void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt) {
Serial.print("X1: ");
PrintHex<uint8_t > (evt->X, 0x80);
Serial.print("\tY1: ");
PrintHex<uint8_t > (evt->Y, 0x80);
Serial.print("\tX2: ");
PrintHex<uint8_t > (evt->Z1, 0x80);
Serial.print("\tY2: ");
PrintHex<uint8_t > (evt->Z2, 0x80);
Serial.print("\tRz: ");
PrintHex<uint8_t > (evt->Rz, 0x80);
Serial.println("");
}
How to apply these codes in cpp file or access these codes from cpp file to use on arduino's main code block side ( arduino sketch .ino ) ?
What do I need to write in void setup() and void loop() section to make my dc motors to move according to the values I get from the joystick ?
I thought so much and check internet to find any single clue to solve the main problem I encountered. This is my first time using HID device to work on arduino ( with the help of an arduino library ).
Shortly, I came here to seek your guidance and help. I really want to learn this topic and how to apply it too. I hope that some of you friends help me out. I look forward your replies to me in this thread. Thank you very much from now on.