Cannot compile USB Host examples

Hello:
I'm trying to get an Arduino mega 2560 with a USB Host Shield to work and use some example sketches in IDE 1.0 but I only get compile errors. For example, compiling 'Richard Ibbotson’s modified USB and PS3 library' makes the following output:
In file included from Max3421e.cpp:3:
/Max3421e.h:6:17: error: Spi.h: No such file or directory
In file included from Max3421e.cpp:3:
Max3421e.h:10: error: expected class-name before '{' token
Max3421e.cpp: In static member function 'static void MAX3421E::regWr(byte, byte)':
Max3421e.cpp:48: error: 'Spi' was not declared in this scope
Max3421e.cpp: In member function 'char* MAX3421E::bytesWr(byte, byte, char*)':
... and more similar lines

Prior to getting this I needed to open the sketch file, save it to a different folder with the same name that the sketch and copy there all the .h and .cpp files from other directories.
So now I have several questions:

  • What is the meaning ot the error message with two numbers, '/Max3421e.h:6:17:' ? 6 is the line number, but, what is 17?
  • Did I place the files correctly? Because I think that placing the all the library files together with the sketch doesn't seem a good practice?
  • Finally and the most important, why do I get the errorrs and how to solve them?

Thank you very much for your help
Rafael Caballos

There have been major changes to SPI over the last several versions of the IDE. One of the changes was to rename the class to all upper case letters.

What is the meaning ot the error message with two numbers, '/Max3421e.h:6:17:' ? 6 is the line number, but, what is 17?

File name, line number, column number.

Thank you PaulS for your answer. I almost guessed about the column number. I'm used to other IDEs and not yet with much practice to this one.
Regarding other errors, I changed the situation of some files and they reduced somehow to this:

In file included from C:\Documents and Settings\rafcab\Mis documentos\Proyectos\Arduino\Arduino-1.0\libraries\PS3USB/Usb.h:5,
from C:\Documents and Settings\rafcab\Mis documentos\Proyectos\Arduino\Arduino-1.0\libraries\PS3USB/ps3_usb.h:19,
from sketch_feb13a.cpp:3:
C:\Documents and Settings\rafcab\Mis documentos\Proyectos\Arduino\Arduino-1.0\libraries\PS3USB/MAX3421E.h:11: error: expected class-name before '{' token

The line causing this error is: class MAX3421E : public SPI {

but SPI is already defined in SPI.h, which is included in the sketch.
What more should I do?

Thank you again
Rafael Caballos

What more should I do?

from sketch_feb13a.cpp:3:

Start by fixing your clock. Unless I took a very long nap, and you'd think I'd remember doing so, it's still January.

but SPI is already defined in SPI.h, which is included in the sketch.

But, is SPI.h included in ps3_usb.h? In Usb.h? In MAX3421E.h?

Sorry about february. I was working with date formats some days ago and forgot to change it back.

I am still working with the USB shield and I managed to use it with the Mega board. At least the USB_desc example. The problem was that the library was not correctly placed in the folder under 'libraries'.
The next step is using Ribbotson code for connecting a PS3 pad. At this moment I am getting some compiling errors with PS3servo example, and I'm afraid it could be because I did not copy the correct folders to the 'libraries'. Do you know if I should move any? I read the documentation but could not find anything about this.
And I added the SPI.h to the header files you suggest but the result is the same, the expected class-name before '{' token error as before.

Thank you
Rafael

We're just shooting in the dark without seeing YOUR code.

Well, in fact it's not my code. I'm trying to compile PS3servo.pde example from Ribbotson code in file 'ribbotson-USB-Host-17c8cba.zip', which can be downloaded from circuitsathome.com web.
It seems that I installed the USB Host Shield 2.0 library correctly, and now the next step is dealing with the PS3 code, which is causing the commented errors:

In file included from C:\Documents and Settings\rafcab\Mis documentos\Proyectos\Arduino\Arduino-1.0\libraries\PS3USB/Usb.h:6,
from C:\Documents and Settings\rafcab\Mis documentos\Proyectos\Arduino\Arduino-1.0\libraries\PS3USB/ps3_usb.h:20,
from PS3servo.cpp:3:
C:\Documents and Settings\rafcab\Mis documentos\Proyectos\Arduino\Arduino-1.0\libraries\PS3USB/MAX3421E.h:11: error: expected class-name before '{' token

Thank you
Rafael

Well, in fact it's not my code.

Well, then give it back.

Seriously, if people publish code on the web, they mean for you to take it and use it. Once you do, it becomes your code.

You are asking us to go to all the trouble of downloading a bunch of code, and figuring out why it won't compile on 1.0. I'm asking you to just post the code - at least the header files. Your choice.

Thank you again PaulS for your efforts. The sketch PS3servo is:


#include <Servo.h>
#include <SPI.h>
#include <ps3_usb.h>
#include <MemoryFree.h>
void setup(void);
void loop(void);

Servo servoOne; // create servo object for first Servo
Servo servoTwo; // create servo object for second Servo
PS3_USB PS3Game; // create an object for the PS3 Game Controller

int PositionOne, PositionTwo; //storage for servo positions
char servomode; // mode for servo control 0 = joystick 1 = accelerometer

void setup()
{
servoOne.attach(2); // attaches the first servo on pin 0 to the servo object
servoTwo.attach(3); // attaches the first servo on pin 1 to the servo object
PS3Game.init();
Serial.begin( 9600 );
Serial.println("PS3 Controller");
Serial.print("freeMemory() reports ");
Serial.println( freeMemory() );
}

void loop()
{
PS3Game.task(); // perform the regular USB routines

if ((PS3Game.statConnected()) && (PS3Game.statReportReceived())){ // report received ?

if(PS3Game.buttonChanged()){ // right and left buttons change mode joystick/Accelerometer

if(PS3Game.buttonPressed(buLeft)) {

servomode = 0;
PS3Game.LEDRumble(psLED1);
}
if(PS3Game.buttonPressed(buRight)) {

servomode = 1;
PS3Game.LEDRumble(psLED2);
}
}

if(servomode){ // Accelerometer mode

PositionOne = constrain(PS3Game.getMotion(AccelerometerX), 400, 600); // constrain to +/- 1g
PositionOne = map(PositionOne, 400, 600, 0, 179); // scale it to use it with the servo
PositionTwo = constrain(PS3Game.getMotion(AccelerometerY), 400, 600); // constrain to +/- 1g
PositionTwo = map(PositionTwo, 400, 600, 0, 179); // scale it to use it with the servo
}
else{ // Joystick mode
PositionOne = map(PS3Game.getJoystick(leftJoystickX), 0, 255, 0, 179); // scale it to use it with the servo
PositionTwo = map(PS3Game.getJoystick(leftJoystickY), 0, 255, 0, 179); // scale it to use it with the servo
}
}

servoOne.write(PositionOne); //sets the first servo position according to the scaled value
servoTwo.write(PositionTwo); // sets the first servo position according to the scaled value
delay(15); // waits for the servo low time

}

and I think the possible problematic unit is ps3_usb, with header file ps3_usb.h is:


/* ps3_usb.h - PS3 Game Controller on Arduino USB Host Library

Copyright (c) 2009 Richard Ibbotson richard.ibbotson@btinternet.com

All right reserved. This library is free software; you can redistribute it
and/or modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */

#ifndef ps3_usb_h
#define ps3_usb_h
#include <SPI.h>
#include "Usb.h"
#include <avr/pgmspace.h>

#define byteswap(x) ((x >> 8) | (x << 8))

/* PS3 data taken from descriptors */
#define PS3_ADDR 1
#define PS3_VID 0x054c // Sony VID
#define PS3_PID 0x0268 // Batch Device
#define PS3_CONFIGURATION 1
#define PS3_IF 0
#define PS3_NUM_EP 3
#define EP_MAXPKTSIZE 64
#define EP_INTERRUPT 0x03
#define EP_POLL 0x01
#define CONTROL_PIPE 0
#define OUTPUT_PIPE 1
#define INPUT_PIPE 2

/* Defines for bits in ps3_status */
#define statusDeviceConnected 0x01
#define statusUSBConfigured 0x02
#define statusPS3Connected 0x04
#define statusReportReceived 0x08

/* Defines of various parameters for PS3 Game controller reports */
#define PS3_F4_REPORT_LEN 4
#define PS3_F5_REPORT_LEN 8
#define PS3_01_REPORT_LEN 48
#define HID_REPORT_FEATURE 3
#define HID_REPORT_OUTPUT 2
#define PS3_F4_REPORT_ID 0xF4
#define PS3_01_REPORT_ID 0x01
#define PS3_F5_REPORT_ID 0xF5

/* Defines for the PS3 Buttons
*/

#define buSelect 0
#define buLAnalog 1
#define buRAnalog 2
#define buStart 3
#define buUp 4
#define buRight 5
#define buDown 6
#define buLeft 7
#define buL2 8
#define buR2 9
#define buL1 10
#define buR1 11
#define buTriangle 12
#define buCircle 13
#define buCross 14
#define buSquare 15
#define buPS 16

/* Defines for the PS3 Joysticks
*/

#define leftJoystickX 0
#define leftJoystickY 1
#define rightJoystickX 2
#define rightJoystickY 3

/* Defines for the PS3 Accelerometers and Gyro
*/

#define AccelerometerX 0
#define AccelerometerY 1
#define AccelerometerZ 2
#define GyrometerZ 3

/* Defines for the PS3 LED and Rumble
*/
#define psLED1 0x01
#define psLED2 0x02
#define psLED3 0x04
#define psLED4 0x08
#define psRumbleHigh 0x10
#define psRumbleLow 0x20

//Structure which describes the type 01 input report
typedef struct {
unsigned char ReportType; //Report Type 01
unsigned char Reserved1; // Unknown
unsigned int ButtonState; // Main buttons
unsigned char PSButtonState; // PS button
unsigned char Reserved2; // Unknown
unsigned char LeftStickX; // left Joystick X axis 0 - 255, 128 is mid
unsigned char LeftStickY; // left Joystick Y axis 0 - 255, 128 is mid
unsigned char RightStickX; // right Joystick X axis 0 - 255, 128 is mid
unsigned char RightStickY; // right Joystick Y axis 0 - 255, 128 is mid
unsigned char Reserved3[4]; // Unknown
unsigned char PressureUp; // digital Pad Up button Pressure 0 - 255
unsigned char PressureRight; // digital Pad Right button Pressure 0 - 255
unsigned char PressureDown; // digital Pad Down button Pressure 0 - 255
unsigned char PressureLeft; // digital Pad Left button Pressure 0 - 255
unsigned char PressureL2; // digital Pad L2 button Pressure 0 - 255
unsigned char PressureR2; // digital Pad R2 button Pressure 0 - 255
unsigned char PressureL1; // digital Pad L1 button Pressure 0 - 255
unsigned char PressureR1; // digital Pad R1 button Pressure 0 - 255
unsigned char PressureTriangle; // digital Pad Triangle button Pressure 0 - 255
unsigned char PressureCircle; // digital Pad Circle button Pressure 0 - 255
unsigned char PressureCross; // digital Pad Cross button Pressure 0 - 255
unsigned char PressureSquare; // digital Pad Square button Pressure 0 - 255
unsigned char Reserved4[3]; // Unknown
unsigned char Charge; // charging status ? 02 = charge, 03 = normal
unsigned char Power; // Battery status ?
unsigned char Connection; // Connection Type ?
unsigned char Reserved5[9]; // Unknown
unsigned int AccelX; // X axis accelerometer Big Endian 0 - 1023
unsigned int AccelY; // Y axis accelerometer Big Endian 0 - 1023
unsigned int AccelZ; // Z axis accelerometer Big Endian 0 - 1023
unsigned int GyroZ; // Z axis Gyro Big Endian 0 - 1023

} TYPE_01_REPORT;

class PS3_USB {

public:
PS3_USB( void );
void init(void);
void task( void );
unsigned char getStatus(void);
bool statConnected(void);
bool statReportReceived(void);
bool buttonChanged(void);
bool buttonPressed(unsigned char);
void LEDRumble(unsigned char);
unsigned int getMotion(unsigned char);
unsigned char getJoystick(unsigned char);
unsigned char getPressure(unsigned char);
void setBDADDR(unsigned char *);
void getBDADDR(unsigned char *);
TYPE_01_REPORT report;

private:
void PS3_init(void);
void PS3_poll(void);
};

#endif //ps3_usb_h

and ps3_usb.cpp file is:


/* ps3_usb.cpp - PS3 Game Controller on Arduino USB Host Library

Copyright (c) 2009 Richard Ibbotson richard.ibbotson@btinternet.com

All right reserved. This library is free software; you can redistribute it
and/or modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */

#include "ps3_usb.h"

static unsigned char ps3_status;
static unsigned int oldbuttonstate;
static unsigned char oldpsbuttonstate;

prog_char output_01_report[] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0xff, 0x27, 0x10, 0x00, 0x32, 0xff,
0x27, 0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00,
0x32, 0xff, 0x27, 0x10, 0x00, 0x32, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

prog_char feature_F4_report[] PROGMEM = {0x42, 0x0c, 0x00, 0x00};

EP_RECORD ep_record[ PS3_NUM_EP ]; //endpoint record structure for the PS3 controller
TYPE_01_REPORT report;

MAX3421E Max;
USB Usb;

/* constructor */

PS3_USB::PS3_USB() {

}

void PS3_USB::init(void){
Max.powerOn();
delay(200);
}

void PS3_USB::task(void){
Max.Task();
Usb.Task();

if( Usb.getUsbTaskState() == USB_DETACHED_SUBSTATE_INITIALIZE) { //reinitialised
ps3_status = 0;

}

if( Usb.getUsbTaskState() == USB_STATE_CONFIGURING ) { //wait for addressing state

PS3_init();
if( ps3_status & statusPS3Connected) Usb.setUsbTaskState( USB_STATE_RUNNING );
}
if( Usb.getUsbTaskState() == USB_STATE_RUNNING ) { //poll the PS3 Controller
PS3_poll();
}

}

/* Initialize PS3 Controller /
void PS3_USB::PS3_init( void )
{
byte rcode = 0; //return code
char buf[ 64 ] = { 0 }; //General purpose buffer for usb data
byte i;
USB_DEVICE_DESCRIPTOR
device_descriptor;

ps3_status = statusDeviceConnected;;

/* Initialize data structures for endpoints of device */
ep_record[ CONTROL_PIPE ] = *( Usb.getDevTableEntry( 0,0 )); //copy endpoint 0 parameters
ep_record[ OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint
ep_record[ OUTPUT_PIPE ].Attr = EP_INTERRUPT;
ep_record[ OUTPUT_PIPE ].MaxPktSize = EP_MAXPKTSIZE;
ep_record[ OUTPUT_PIPE ].Interval = EP_POLL;
ep_record[ OUTPUT_PIPE ].sndToggle = bmSNDTOG0;
ep_record[ OUTPUT_PIPE ].rcvToggle = bmRCVTOG0;
ep_record[ INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint
ep_record[ INPUT_PIPE ].Attr = EP_INTERRUPT;
ep_record[ INPUT_PIPE ].MaxPktSize = EP_MAXPKTSIZE;
ep_record[ INPUT_PIPE ].Interval = EP_POLL;
ep_record[ INPUT_PIPE ].sndToggle = bmSNDTOG0;
ep_record[ INPUT_PIPE ].rcvToggle = bmRCVTOG0;

Usb.setDevTableEntry( PS3_ADDR, ep_record ); //plug kbd.endpoint parameters to devtable
delay(200); // give time for address change
/* read the device descriptor and check VID and PID*/
rcode = Usb.getDevDescr( PS3_ADDR, ep_record[ CONTROL_PIPE ].epAddr, DEV_DESCR_LEN , buf );
if( rcode ) return;
device_descriptor = (USB_DEVICE_DESCRIPTOR *) &buf;
if(
(device_descriptor->idVendor != PS3_VID) ||(device_descriptor->idProduct != PS3_PID) ) return;

/* Configure device */
rcode = Usb.setConf( PS3_ADDR, ep_record[ CONTROL_PIPE ].epAddr, PS3_CONFIGURATION );
if( rcode ) return;
ps3_status |= statusUSBConfigured;

/* Set the PS3 controller to send reports */
for (i=0; i < PS3_F4_REPORT_LEN; i++) buf = pgm_read_byte_near( feature_F4_report + i);

  • rcode = Usb.setReport( PS3_ADDR, ep_record[ CONTROL_PIPE ].epAddr, PS3_F4_REPORT_LEN, PS3_IF, HID_REPORT_FEATURE, PS3_F4_REPORT_ID , buf );*
  • if( rcode ) return;*

_ /* Set the PS3 controller LED 1 On /_
for (i=0; i < PS3_01_REPORT_LEN; i++) buf = pgm_read_byte_near( output_01_report + i);
rcode = Usb.setReport( PS3_ADDR, ep_record[ CONTROL_PIPE ].epAddr, PS3_01_REPORT_LEN, PS3_IF, HID_REPORT_OUTPUT, PS3_01_REPORT_ID , buf );
_
if( rcode ) return;*_

* ps3_status |= statusPS3Connected;*

}
/* Poll PS3 interrupt pipe and process result if any */
void PS3_USB::PS3_poll( void )
{

byte rcode = 0; //return code
_ /* poll PS3 /_
rcode = Usb.inTransfer(PS3_ADDR, ep_record[ INPUT_PIPE ].epAddr, PS3_01_REPORT_LEN, (char ) &report );
_
if( rcode ) return;
_
* ps3_status |= statusReportReceived;
_
return;_
_
}_
unsigned char PS3_USB::getStatus( void ){
return( ps3_status);
_
}_
bool PS3_USB::statConnected( void){
return(ps3_status & statusPS3Connected);
_
}_
bool PS3_USB::statReportReceived( void){
bool rvalue = ps3_status & statusReportReceived;
ps3_status &= ~statusReportReceived; // clear the report received flag*

* return(rvalue);*
}
unsigned char PS3_USB::getJoystick(unsigned char joy){
* if (joy > 3) return(128); // not valid joystick*
_ return( (&report.LeftStickX + joy));_
_
}_
unsigned int PS3_USB::getMotion(unsigned char accel ){
_
if(accel > 3) return(512);_
_ return( byteswap((&report.AccelX + accel)));
}
unsigned char PS3_USB::getPressure(unsigned char button ){
* if ((button < 4) || (button > 15)) return(0);*
return((&report.PressureUp + button - 4));_
_
}_
bool PS3_USB::buttonChanged(void){
_
if ((report.ButtonState != oldbuttonstate) || (report.PSButtonState != oldpsbuttonstate)){_
_
oldbuttonstate = report.ButtonState;_
_
oldpsbuttonstate = report.PSButtonState;_
_
return(true);_
_
}_
_
return(false);_
_
}_
bool PS3_USB::buttonPressed(unsigned char button){
_
if(button == 16) return( report.PSButtonState & 0x01);_
_
return(report.ButtonState & (1 << button));*_

}
void PS3_USB::LEDRumble(unsigned char ledrum){
unsigned char i;
char buf[ 64 ] = { 0 }; //General purpose buffer for usb data
/* default buffer values */
for (i=0; i < PS3_01_REPORT_LEN; i++) buf = pgm_read_byte_near( output_01_report + i);
_ /* LED setings /
buf[9] = (ledrum & 0x0f) << 1;
/ rumble settings /
if (ledrum & 0x30){
buf[1] = buf[3] = 0xfe;
if (ledrum & 0x10) buf[4] = 0xff;
else buf[2] = 0xff;
}*_

* Usb.setReport( PS3_ADDR, ep_record[ CONTROL_PIPE ].epAddr, PS3_01_REPORT_LEN, PS3_IF, HID_REPORT_OUTPUT, PS3_01_REPORT_ID , buf );
_ return;
}_
void PS3_USB::setBDADDR(unsigned char * bdaddr){
char buf[ PS3_F5_REPORT_LEN ];
_ buf[0] = 0x01;
buf[1] = 0x00;
for (int i=0; i < 6; i++){
buf[i+2] = bdaddr;
}_

Usb.setReport( PS3_ADDR, ep_record[ CONTROL_PIPE ].epAddr, PS3_F5_REPORT_LEN, PS3_IF, HID_REPORT_FEATURE, PS3_F5_REPORT_ID , buf );
_ return;
}_

void PS3_USB::getBDADDR(unsigned char * bdaddr){
char buf[ PS3_F5_REPORT_LEN ];
Usb.getReport( PS3_ADDR, ep_record[ CONTROL_PIPE ].epAddr, PS3_F5_REPORT_LEN, PS3_IF, HID_REPORT_FEATURE, PS3_F5_REPORT_ID , buf );
_ for( int i=0; i < 6; i++){
bdaddr = buf[i + 2];
}
return;
}
---------------------------------------------------------------*

I understand this is a lot of code and difficult to check. I'll keep trying different things to solve the situation and if I am succesful I'll reply again.
Thank you
Rafael_

Please modify your last several posts, and post the code properly. Select all the code. Delete it. Select the # icon, and copy and paste the code again.

Also, the error message that we are trying to resolve is this one:
C:\Documents and Settings\rafcab\Mis documentos\Proyectos\Arduino\Arduino-1.0\libraries\PS3USB/MAX3421E.h:11: error: expected class-name before '{' token
Where is the code for the MAX3421E.h and MAX3421E.cpp files?

Perhaps, on second thought, you should just post links to the libraries.

This is Richard Ibbotson's PS3 code. It is not compatible with USB Host 2.0 library. In fact, he has his own fork of legacy library posted alongside PS3 code, this is what you need to use.

I used the USB library that comes in PS3 zip package but I get the same compiler error. Maybe it is because it is not compatible with the newest SPI library? If so, where can I find the correct version?

Thank you
Rafael