Go Down

Topic: Trouble using USBHost library to interface with Logitech Extreme 3D Pro Joystick (Read 512 times) previous topic - next topic

abp250

Hi everyone,

I am working on a drone project where I'm going to use a joystick to control the drone. I thought the easiest way to do this would be to use a flight joystick and connect that to my Arduino Due native USB port and send data to the drone through radio. I found a library called USBHost ( https://github.com/arduino-libraries/USBHost ) and thought that would be perfect. I tested that library's mouse and keyboard examples and they worked perfectly. I couldnt find any complete code online for any type of joystick that worked so i decided to try and create my own. The USBHost library uses some C++ techniques that i am not familiar with so i tried my best to mimic the format of the mouse and keyboard code. Here is the code that I generated:


JoystickController.cpp

`
#include <JoystickController.h>

extern "C" {
void __joystickControllerEmptyCallback() { }
}


void OnJoystickChanged()  __attribute__ ((weak, alias("__joystickControllerEmptyCallback")));

uint8_t JoystickController::getButtons_a()      { return buttons_a; }
uint8_t JoystickController::getButtons_b()      { return buttons_b; }
uint8_t JoystickController::getSliderValue()   { return slider; }
uint32_t JoystickController::getAxesValues()   { return axes; }
uint16_t JoystickController::getXValue()      { return x; }
uint16_t JoystickController::getYValue()      { return y; }
uint8_t JoystickController::getHatValue()      { return hat; }
uint8_t JoystickController::getTwistValue()      { return twist; }
`

JoystickController.h
`
#ifndef JOYSTICK_CONTROLLER_H
#define JOYSTICK_CONTROLLER_H

#include <hidboot.h>



class JoystickController : public JoystickReportParser
{
public:
   JoystickController(USBHost &usb) : hostJoystick(&usb), axes(0) , buttons_a(0), buttons_b(0) , slider(0) {
      hostJoystick.SetReportParser(0, this);
   };
   
   uint8_t getButtons_a();
   uint8_t getButtons_b();
   uint8_t getSliderValue();
   uint32_t getAxesValues();
   uint16_t getXValue();
   uint16_t getYValue();
   uint8_t getHatValue();
   uint8_t getTwistValue();

protected:
   virtual void OnJoystickChanged(JOYSTICKINFO *js);
   

private:
  HIDBoot<HID_PROTOCOL_JOYSTICK> hostJoystick;
   union { //axes and hat switch
      uint32_t axes;
      struct {
        uint32_t x : 10;
        uint32_t y : 10;
        uint32_t hat : 4;
        uint32_t twist : 8;     
      };
   };
   uint8_t buttons_a;
   uint8_t buttons_b;   
   uint8_t slider;

};

#endif
`

I added this to hidboot.cpp

`
void JoystickReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
{
   bool match = true;
   JOYSTICKINFO *pjs = (JOYSTICKINFO*)buf;
 
   // Checking if there are changes in report since the method was last called
   for (uint8_t i=0; i<7; i++) {
      if( buf != prevState.oldPad ) {
         match = false;
         break;
      }
  }
     // Calling Game Pad event handler
   if (!match && pjs) {
      OnJoystickChanged((JOYSTICKINFO*)buf);
      //OnJoystickChanged(buf);
      
      for (uint8_t i=0; i<7; i++)
         prevState.oldPad = buf;
   }
}
`

and i added this to hdiboot.h

`
/**
 * \brief JOYINFO definition.
 */

 struct JOYSTICKINFO
{
   union { //axes and hat switch
      uint32_t axes;
      struct {
        uint32_t x : 10;
        uint32_t y : 10;
        uint32_t hat : 4;
        uint32_t twist : 8;     
      };
   };
   uint8_t buttons_a;
   uint8_t buttons_b;   
   uint8_t slider;


};

 
 


/**
 * \class JoystickReportParser definition.
 */
class JoystickReportParser : public HIDReportParser
{
   union
   {
//      JoystickEvents      *joystickEvents;
      JOYSTICKINFO      joystickInfo;
      uint8_t            oldPad[7];
      uint8_t            oldHat;
      uint16_t         oldButtons;
   }   prevState;

 
public:
   //JoystickReportParser(JoystickEvents *evt);
   virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
   
protected:
virtual void OnJoystickChanged(JOYSTICKINFO *js) {};

};
 `

And when I tried to impliment this in an arduino sketch, I got the following errors:

`
JoystickController:9: error: cannot declare variable 'joy' to be of abstract type 'JoystickController'

 JoystickController joy(usb);

                    ^

In file included from C:\Users\Aaron\Documents\Arduino\JoystickController\JoystickController.ino:3:0:

C:\Users\Aaron\Documents\Arduino\libraries\USBHost\src/JoystickController.h:11:7: note:   because the following virtual functions are pure within 'JoystickController':

 class JoystickController : public JoystickReportParser

       ^

In file included from C:\Users\Aaron\Documents\Arduino\libraries\USBHost\src/hidboot.h:24:0,

                 from C:\Users\Aaron\Documents\Arduino\libraries\USBHost\src/JoystickController.h:7,

                 from C:\Users\Aaron\Documents\Arduino\JoystickController\JoystickController.ino:3:

C:\Users\Aaron\Documents\Arduino\libraries\USBHost\src/hid.h:157:15: note:    virtual void HIDReportParser::Parse(HID*, bool, uint32_t, uint8_t*)

  virtual void Parse(HID *hid, bool is_rpt_id, uint32_t len, uint8_t *buf) = 0;

               ^

Using library USBHost at version 1.0.4 in folder: C:\Users\Aaron\Documents\Arduino\libraries\USBHost
exit status 1
cannot declare variable 'joy' to be of abstract type 'JoystickController'
`


I searched for any differences in how the mouse and keyboard controllers were initialized and I couldn't find anything. I'm not very experienced in C++ so i need some help.

Thanks in advance,

Aaron

Go Up