1

I'm trying to get two identical joystics (Saitek cyborg 3D) running with the USB-Host-Shield on a Mega 2560 and an USB-Hub.

I already get the event-messages of both of them:

#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 Hid1(&Usb);    // first Joystick
HIDUniversal Hid2(&Usb);    // second Joystick

JoystickEvents Joy1Events;
JoystickEvents Joy2Events;

JoystickReportParser Joy1(&Joy1Events);
JoystickReportParser Joy2(&Joy2Events);

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 (!Hid1.SetReportParser(0, &Joy1))
                ErrorMessage<uint8_t > (PSTR("SetReportParser1"), 1);
        if (!Hid2.SetReportParser(0, &Joy2))
                ErrorMessage<uint8_t > (PSTR("SetReportParser2"), 1);
}

void loop() {
        Usb.Task();
        Serial.print("\tX1: ");
        PrintHex<uint8_t > (JoystickEvents::mostRecentEvent.X, 0x80);
        Serial.print("\tY1: ");
        PrintHex<uint8_t > (JoystickEvents::mostRecentEvent.Y, 0x80);
        Serial.print("\tX2: ");
        PrintHex<uint8_t > (JoystickEvents::mostRecentEvent.Z1, 0x80);
        Serial.print("\tY2: ");
        PrintHex<uint8_t > (JoystickEvents::mostRecentEvent.Z2, 0x80);
        Serial.print("\tRz: ");
        PrintHex<uint8_t > (JoystickEvents::mostRecentEvent.Rz, 0x80);
        Serial.println("");

}

My question is: How can I distinguish the events from the different joysticks.

I'm trying to get some kind of port-information from the USB-Hub. Unfortunately something like

!hid->GetAddress()

within the JoystickReportParser doesn't do the job as it always returns 0.

Any ideas?

  • look at the hub demo – jsotola Jan 29 '18 at 8:54
  • That's what I'm doing since several days but I don't get the clue. I get message-events but how do I recognize from which port they do come? In the hub demo there is this function: PrintAllAddresses() which takes a pointer to the device. But it's called within this statement: Usb.ForEachUsbDevice(&PrintAllAddresses); – Palmstroem Jan 29 '18 at 9:02
  • In the hub demo there is this function: PrintAllAddresses() which takes a pointer to the device. But it's called within this statement: Usb.ForEachUsbDevice(&PrintAllAddresses); So how would I call something like this from within the JoytickReportParser or the eventhandler OnGamepadChanged ? – Palmstroem Jan 29 '18 at 9:08
  • Or how do I get a pointer to the device from which a message-event comes in? – Palmstroem Jan 29 '18 at 9:09
  • To be honest. I'm not so familiar with all this pointer arithmetic. All these -> :: ! * . Is still a little bit wired to me. – Palmstroem Jan 29 '18 at 9:13
1

Not quite the question that was asked but part of the problem.

This is a simple introduction to pointers.

int variable = 42;                              // Create a variable
int* pointer = &variable;                       // Create a pointer to the variable (by getting its address)
*pointer = 99;                                  // Set the address to a new value
printf ("variable has the value %d", variable); // Print 99.

&x get the address of x

*y dereferences the pointer y, which means it 'turns it back to a variable' (this is simplistic view which isn't really true, but will do for now). So you could, if you wanted (which you wouldn't) do this *&z which would be the same as doing z.

Basically think of & and * as a pair of complimentary operators like - and + or * and /. (They aren't operators, but to start with it might help).

The next problem is when you do this

SomeFunction(&variable);

All function parameters in C/C++ are passed by value by default. This means the function gets a copy of them not the actual value. So if you had:

void FunctionOne (int val)
{
    val = 99;
}
int val = 4;
FunctionOne(val);
printf("val = %d", val);   // You will see 4 printed.

If you pass by reference then you will see 99 printed, to pass by reference you can do it one of two ways.

void FunctionTwo (int& valByRef);
void FunctionThree (int* valPointer);

FunctionTwo only works with C++ (It will work with an Arduino).

FunctionThree might cause a segmentation error if NULL is passed in and the function writes to it.

If it helps in my opinion pointers was one of the hardest concepts to grasp in classic C/C++ so don't worry if you don't understand it just have a play with it and see what you can do.

Calling Methods

  • object.method() - Call the function method on the instance called object which is of type X.
  • object->method() - Call the function method on the instance called object which is a pointer of type X.
  • object::method() - call the function method which is a static member of class object (static means it doesn't change any data within an instance of a class)
  • *object->method() - Avoid this like the plague. It either means *(object->method()) or (*object)->method() to know you would need to look at the type of object and the return type of the function. Its easier just to bracket it to remove ambiguity.

As for *object.&method() I've never come across that one, but that doesn't mean it doesn't exist. :)

  • Those who don't understand pointers are doomed to program in Javascript the rest of their lives. – user31481 Jan 29 '18 at 19:39
  • Thank you very much for this explanation. Good explanation! What confuses me is: Sometimes you can access a property by object.method or by object.object.method then by object::method and object->method or object.&method or *object.&object::method and object.@->/!%&wtf$method and so on. These things were not made for human brains to be understood. – Palmstroem Jan 29 '18 at 20:00
  • Are you saying I'm not human? :) (See edit) Its learning a new language, and you just have to remember certain rules, the more you use them the more they become ingrained, there is no short cut :( – Code Gorilla Jan 31 '18 at 1:07
  • Thank you very much. Superhuman! Any ideas for the original question? I'm inside a signal-handler-function and want to access an attribute of a parent or grand-parent class, but don't know how to find the right method. The documentation at felis.github.io/USB_Host_Shield_2.0/… seems to be quite comprehensive. But I don't get the clue. – Palmstroem Feb 1 '18 at 18:11
  • !Hid->GetAddress() always returns 0. Maybe I need to do something like *evt.HIDDevice.Hid->GetAddress() but all trials like that lead to compile errors. – Palmstroem Feb 1 '18 at 18:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.