USB Host shield accessing variables

Hi Folks,

Im working with a JoyStick module similar to >> http://www.circuitsathome.com/mcu/hid-joystick-code-sample and all is tested and working

in the USBHIDjoystick programme that comes with the latest USBHOST shield library 2.0 Im actually trying to access the hidjoystickrptparser.cpp variables that are returned by the programme when joy stick buttons are moved or clicked so i was trying to access these variables like in case of OnHatSwitch(uint8_t hat) hat variable in the main USBHIDjoystick.pde programme but now that returns me the error as follows:

USBHIDJoystick.cpp: In function 'void loop()': USBHIDJoystick:48: error: expected primary-expression before 'hat' USBHIDJoystick:48: error: 'OnHatSwitch' was not declared in this scope

how ever the OnHatSwitch is declared as Public then also im not able to access the variable declared under it in the main pde programme of arduino.

Any Remedy?

You need to post YOUR code. Why are you expecting us to go looking for code?

Main Arduino code running that calls up function etc parameters inherited from other classes in the programme’s hidjoystickrptparser.cpp and hidjoystickrptparser.h header file.

#include <avr/pgmspace.h>

#include <avrpins.h>
#include <max3421e.h>
#include <usbhost.h>
#include <usb_ch9.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <address.h>
#include <hid.h>
#include <hiduniversal.h>

#include "hidjoystickrptparser.h"

#include <printhex.h>
#include <message.h>
#include <hexdump.h>
#include <parsetools.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(6,9,8,5,4,3,2);
USB                                             Usb;
USBHub                                          Hub(&Usb);
HIDUniversal                                    Hid(&Usb);
JoystickEvents                                  JoyEvents;
JoystickReportParser                            Joy(&JoyEvents);

void setup()
{
  Serial.begin(9600);
  lcd.begin(20, 4);
  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();
    lcd.setCursor(0, 1);
    lcd.print(OnHatSwitch(uint8_t hat));
}

hidjoystickrptparser.cpp code as follows:

#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(HID *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("X: ");
	PrintHex<uint8_t>(evt->X);
	Serial.print("\tY: ");
	PrintHex<uint8_t>(evt->Y);
	Serial.print("\tZ: ");
	PrintHex<uint8_t>(evt->Z1);
	Serial.print("\tZ: ");
	PrintHex<uint8_t>(evt->Z2);
	Serial.print("\tRz: ");
	PrintHex<uint8_t>(evt->Rz);
	Serial.println("");
}

void JoystickEvents::OnHatSwitch(uint8_t hat)
{
	Serial.print("Hat Switch: ");
	PrintHex<uint8_t>(hat);
	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);
}

hidjoystickrptparser.h CODE

#if !defined(__HIDJOYSTICKRPTPARSER_H__)
#define __HIDJOYSTICKRPTPARSER_H__

#include <inttypes.h>
#include <avr/pgmspace.h>
#include "avrpins.h"
#include "max3421e.h"
#include "usbhost.h"
#include "usb_ch9.h"
#include "Usb.h"

#if defined(ARDUINO) && ARDUINO >=100
#include "Arduino.h"
#else
#include <WProgram.h>
#endif

#include "printhex.h"
#include "hexdump.h"
#include "message.h"
#include "confdescparser.h"
#include "hid.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(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
};

#endif // __HIDJOYSTICKRPTPARSER_H__

as you can see im trying to access the variables hat,bat_id and x,y,z1,z2,Rz(joystick direction)

    lcd.print(OnHatSwitch(uint8_t hat));

OnHatSwitch() is a member function. hat is a class variable. Not a class instance in site. No wonder they don't work.

Not a class instance in site. No wonder they don’t work.

What should I do then?

EDIT: Many of the other Arduino specific things are working like Serial printing but Why not this LCD thing ? i tried putting lcd in the cpp file where the serial prints are being made but not possible ,why this is happening?

So Now the Dilemma is that Variables are not being able to be accessed in the main Arduino Sketch and the cpp and h files do not let liquid crystal library utilisation it says does not name a type

What should I do then?

You have an instance of the JoyEvents class. It is that instance that you want to call the methods for.

OnHatSwitch() is an event callback. That method gets called when an event occurs. It does not make sense for you to call it, unless you are trying to emulate that event.

Yes i already did the same inheritence in the void loop()

given:

 void JoystickEvents::OnHatSwitch(uint8_t hat){statements;}

but it shows me

MasterController.cpp: In function 'void loop()': MasterController:50: error: a function-definition is not allowed here before '{' token

EDIT:

One more thing i think i have to work it out the other way putting lcd.prints in the hidjoystickrptparser.cpp file because that is the one that gets called after USB.Task() is there in the void loop() , So why isn't the Liquid Crystal library not working in this .cpp file?? however other Arduino specific items are working like Serial.prints?

So why isn't the Liquid Crystal library not working in this .cpp file?

In which .cpp file? If you are talking about the hidjoystickrptparser.cpp file, it could possibly be because there is no mention of the LequidCrystal library in that file.

If you are talking about the hidjoystickrptparser.cpp file, it could possibly be because there is no mention of the LequidCrystal library in that file.

Yes Mr.Paul im talking about that same .cpp file , There was a mention as i tried LCD Crystal Library but it is not taking it and compile does not happens and says this:

'LiquidCrystal' does not name a type

You are once again asking questions about code you have not posted, or have modified after posting. That is not what this part of the forum is about. The psychic forum is, but it is not open to everyone.

In that Respective .cpp file:

#include "hidjoystickrptparser.h"

#include <LiquidCrystal.h>
LiquidCrystal lcd(6,9,8,5,4,3,2);
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(HID *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("X: ");
	PrintHex<uint8_t>(evt->X);
	Serial.print("\tY: ");
	PrintHex<uint8_t>(evt->Y);
	Serial.print("\tZ: ");
	PrintHex<uint8_t>(evt->Z1);
	Serial.print("\tZ: ");
	PrintHex<uint8_t>(evt->Z2);
	Serial.print("\tRz: ");
	PrintHex<uint8_t>(evt->Rz);
	Serial.println("");
}

void JoystickEvents::OnHatSwitch(uint8_t hat)
{
	Serial.print("Hat Switch: ");
	PrintHex<uint8_t>(hat);
	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);
}

The problem is that the compiler tells me:

hidjoystickrptparser.cpp:3:27: error: LiquidCrystal.h: No such file or directory
hidjoystickrptparser.cpp:3: error: ‘LiquidCrystal’ does not name a type

NOT even the .h header file is taking the Liquid Crystal library and showing the same error only in the PDE sketch i get to see this working.

hidjoystickrptparser.cpp:3:27: error: LiquidCrystal.h: No such file or directory

It would appear that you are trying to hide the use of a library (LiquidCrystal) from the sketch. That is not possible. All libraries that the sketch directly or indirectly uses MUST be included in the sketch.

It would appear that you are trying to hide the use of a library (LiquidCrystal) from the sketch. That is not possible. All libraries that the sketch directly or indirectly uses MUST be included in the sketch.

Mr.Paul i do not need these to be hidden and im making sure of this , no problem to me if they are visible ,the thing is even after including the library file i get this error.

I have tried including this library file at all of these 3 files the PDE,the .cpp and the .h header file but all i get is the same answer in case of .cpp and .h file it works fine in PDE but then i have to use LCD functions basically where the hat and all those variables are returned that are publicly defined and that file is the .cpp file.

Please post all of the code with the LiquidCrystal includes, instances, etc. There is no reason why you should not be able to use the LiquidCrystal library in another library. Therefore, it must be something that you are missing. Post your code so we can see what that might be.

Hi Mr.Paul,

Please see the codes below:

USBHIDjoystick code:

#include <avr/pgmspace.h>

#include <avrpins.h>
#include <max3421e.h>
#include <usbhost.h>
#include <usb_ch9.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <address.h>
#include <hid.h>
#include <hiduniversal.h>

#include "hidjoystickrptparser.h"

#include <printhex.h>
#include <message.h>
#include <hexdump.h>
#include <parsetools.h>

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

void setup()
{
  Serial.begin( 9600 );
  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();
}

The hidjoystickrptparser.cpp file ,This is the file that is executed to show the values returned by the USB descriptors after successful connection of USB joystick is made with USB host shield and various buttons are pressed, ALL works fine but when i add the LiquidCrystal.h library in this file i get the following error:
hidjoystickrptparser.cpp:1:27: error: LiquidCrystal.h: No such file or directory

#include <LiquidCrystal.h>

#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(HID *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("X: ");
	PrintHex<uint8_t>(evt->X);
	Serial.print("\tY: ");
	PrintHex<uint8_t>(evt->Y);
	Serial.print("\tZ: ");
	PrintHex<uint8_t>(evt->Z1);
	Serial.print("\tZ: ");
	PrintHex<uint8_t>(evt->Z2);
	Serial.print("\tRz: ");
	PrintHex<uint8_t>(evt->Rz);
	Serial.println("");
}

void JoystickEvents::OnHatSwitch(uint8_t hat)
{
	Serial.print("Hat Switch: ");
	PrintHex<uint8_t>(hat);
	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);
}

no changes to the hidjoystickrptparser.h file below as no changes are needed:

#if !defined(__HIDJOYSTICKRPTPARSER_H__)
#define __HIDJOYSTICKRPTPARSER_H__

#include <inttypes.h>
#include <avr/pgmspace.h>
#include "avrpins.h"
#include "max3421e.h"
#include "usbhost.h"
#include "usb_ch9.h"
#include "Usb.h"

#if defined(ARDUINO) && ARDUINO >=100
#include "Arduino.h"
#else
#include <WProgram.h>
#endif

#include "printhex.h"
#include "hexdump.h"
#include "message.h"
#include "confdescparser.h"
#include "hid.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(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
};

#endif // __HIDJOYSTICKRPTPARSER_H__

The sketch posted in the first box does not include LiquidCrystal.h. It needs to.

Mr.Paul it now compiles but only till i do not use the library as soon as i put in lcd.print(); in the .cpp code it shows me the following error:

USBHIDJoystick.cpp.o:(.bss.lcd+0x0): multiple definition of `lcd’
hidjoystickrptparser.cpp.o:(.bss.lcd+0x0): first defined here

it shows im defining it multiple times which i understand and remove the LiquidCrystal lcd(6,9,8,5,4,3,2); from the .cpp file but then i get this error:

hidjoystickrptparser.cpp: In member function ‘virtual void JoystickEvents::OnHatSwitch(uint8_t)’:
hidjoystickrptparser.cpp:83: error: ‘lcd’ was not declared in this scope

codes again

PDE/Main Arduino code:

#include <LiquidCrystal.h>
#include <avr/pgmspace.h>
#include <avrpins.h>
#include <max3421e.h>
#include <usbhost.h>
#include <usb_ch9.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <address.h>
#include <hid.h>
#include <hiduniversal.h>

#include "hidjoystickrptparser.h"

#include <printhex.h>
#include <message.h>
#include <hexdump.h>
#include <parsetools.h>

USB                                             Usb;
USBHub                                          Hub(&Usb);
HIDUniversal                                    Hid(&Usb);
JoystickEvents                                  JoyEvents;
JoystickReportParser                            Joy(&JoyEvents);
LiquidCrystal lcd(6,9,8,5,4,3,2);
void setup()
{
  Serial.begin( 9600 );
  Serial.println("Start");
  lcd.begin(20, 4);
  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();
}

.cpp file code:

#include <LiquidCrystal.h>
LiquidCrystal lcd(6,9,8,5,4,3,2);
#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(HID *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("X: ");
	PrintHex<uint8_t>(evt->X);
	Serial.print("\tY: ");
	PrintHex<uint8_t>(evt->Y);
	Serial.print("\tZ: ");
	PrintHex<uint8_t>(evt->Z1);
	Serial.print("\tZ: ");
	PrintHex<uint8_t>(evt->Z2);
	Serial.print("\tRz: ");
	PrintHex<uint8_t>(evt->Rz);
	Serial.println("");
}

void JoystickEvents::OnHatSwitch(uint8_t hat)
{
	Serial.print("Hat Switch: ");
	PrintHex<uint8_t>(hat);
        lcd.print("hat");
	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);
}

and the THIRD box .h file remaining the same unchanged as unneeded

So, now you have two instances of the LiquidCrystal class using the same hardware. That is not allowed, apparently.

You might be able to get do something like this in hidjoystickrptparser.cpp: LiquidCrystal lcd(6,9,8,5,4,3,2); extern LiquidCrystal lcd;

This would inherit the lcd instance from the sketch.

If that doesn't work, then you'd need to rewrite the LiquidCrystal class to give it a no-argument constructor and a begin() method that takes the arguments the current constructor takes (as the class should have been written in the first place).

extern doesnt work seems i need to mod the lcd lib class now! ..Man!!!!!