Updated comments to work with Doxygen

This commit is contained in:
Kristian Sloth Lauszus 2013-02-05 19:51:45 +01:00
parent 92d3f2201b
commit 1333e9a63b
11 changed files with 1033 additions and 262 deletions

View file

@ -19,6 +19,7 @@
#define DEBUG // Uncomment to print data for debugging #define DEBUG // Uncomment to print data for debugging
//#define EXTRADEBUG // Uncomment to get even more debugging data //#define EXTRADEBUG // Uncomment to get even more debugging data
const uint8_t BTD::BTD_CONTROL_PIPE = 0;
const uint8_t BTD::BTD_EVENT_PIPE = 1; const uint8_t BTD::BTD_EVENT_PIPE = 1;
const uint8_t BTD::BTD_DATAIN_PIPE = 2; const uint8_t BTD::BTD_DATAIN_PIPE = 2;
const uint8_t BTD::BTD_DATAOUT_PIPE = 3; const uint8_t BTD::BTD_DATAOUT_PIPE = 3;

302
BTD.h
View file

@ -130,36 +130,88 @@
#define BTD_MAX_ENDPOINTS 4 #define BTD_MAX_ENDPOINTS 4
#define BTD_NUMSERVICES 4 // Max number of Bluetooth services #define BTD_NUMSERVICES 4 // Max number of Bluetooth services
class BluetoothService { // All services should include this class /** All Bluetooth services should include this class. */
class BluetoothService {
public: public:
virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services /**
virtual void Run(); // Used to run the different state machines * Used to pass acldata to the Bluetooth service.
virtual void Reset(); // Used to reset the services * @param ACLData Pointer to the incoming acldata.
virtual void disconnect(); // Used to disconnect both the L2CAP Channel and the HCI Connection */
virtual void ACLData(uint8_t* ACLData);
/** Used to run the different state machines in the Bluetooth service. */
virtual void Run();
/** Used to reset the Bluetooth service. */
virtual void Reset();
/** Used to disconnect both the L2CAP Channel and the HCI Connection for the Bluetooth service. */
virtual void disconnect();
}; };
/**
* The Bluetooth Dongle class will take care of all the USB communication
* and then pass the data to the BluetoothService classes.
*/
class BTD : public USBDeviceConfig, public UsbConfigXtracter { class BTD : public USBDeviceConfig, public UsbConfigXtracter {
public: public:
BTD(USB *p); // Constructor /**
* Constructor for the BTD class.
* @param p Pointer to USB class instance.
*/
BTD(USB *p);
// USBDeviceConfig implementation /** @name USBDeviceConfig implementation */
/**
* Initialize the Bluetooth dongle.
* @param parent Hub number.
* @param port Port number on the hub.
* @param lowspeed Speed of the device.
* @return 0 on success.
*/
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed); virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
/**
* Release the USB device.
* @return 0 on success.
*/
virtual uint8_t Release(); virtual uint8_t Release();
/**
* Poll the USB Input endpoins and run the state machines.
* @return 0 on success.
*/
virtual uint8_t Poll(); virtual uint8_t Poll();
/**
* Get the device address.
* @return The device address.
*/
virtual uint8_t GetAddress() { return bAddress; }; virtual uint8_t GetAddress() { return bAddress; };
/**
* Used to check if the dongle has been initialized.
* @return True if it's ready.
*/
virtual bool isReady() { return bPollEnable; }; virtual bool isReady() { return bPollEnable; };
/**@}*/
// UsbConfigXtracter implementation, used to extract endpoint information /** @name UsbConfigXtracter implementation */
/**
* UsbConfigXtracter implementation, used to extract endpoint information.
* @param conf Configuration value.
* @param iface Interface number.
* @param alt Alternate setting.
* @param proto Interface Protocol.
* @param ep Endpoint Descriptor.
*/
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep); virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
/**@}*/
bool watingForConnection; // Use this to see if it is waiting for a incoming connection /** Disconnects both the L2CAP Channel and the HCI Connection for all Bluetooth services. */
void disconnect() { // Used this void to disconnect all services void disconnect() {
for (uint8_t i=0; i<BTD_NUMSERVICES; i++) for (uint8_t i=0; i<BTD_NUMSERVICES; i++)
if (btService[i]) if (btService[i])
btService[i]->disconnect(); // Disconnect both the L2CAP Channel and the HCI Connection btService[i]->disconnect();
}; };
/**
/* Register bluetooth dongle members/services */ * Register bluetooth dongle members/services.
* @param pService Pointer to BluetoothService class instance.
* @return The serice ID on succes or -1 on fail.
*/
int8_t registerServiceClass(BluetoothService *pService) { int8_t registerServiceClass(BluetoothService *pService) {
for (uint8_t i=0; i<BTD_NUMSERVICES; i++) { for (uint8_t i=0; i<BTD_NUMSERVICES; i++) {
if (!btService[i]) { if (!btService[i]) {
@ -170,69 +222,193 @@ public:
return -1; // ErrorregisterServiceClass return -1; // ErrorregisterServiceClass
}; };
bool l2capConnectionClaimed; // This is used by the service to know when to store the device information /** @name HCI Commands */
/**
* Used to send a HCI Command.
* @param data Data to send.
* @param nbytes Number of bytes to send.
*/
void HCI_Command(uint8_t* data, uint16_t nbytes);
/** Reset the Bluetooth dongle. */
void hci_reset();
/** Read the Bluetooth address of the dongle. */
void hci_read_bdaddr();
/** Read the HCI Version of the Bluetooth dongle. */
void hci_read_local_version_information();
/**
* Set the local name of the Bluetooth dongle.
* @param name Desired name.
*/
void hci_set_local_name(const char* name);
/** Enable visibility to other Bluetooth devices. */
void hci_write_scan_enable();
/** Disable visibility to other Bluetooth devices. */
void hci_write_scan_disable();
/** Read the remote devices name. */
void hci_remote_name();
/** Accept the connection with the Bluetooth device. */
void hci_accept_connection();
/**
* Disconnect the HCI connection.
* @param handle The HCI Handle for the connection.
*/
void hci_disconnect(uint16_t handle);
/**
* Respond with the pin for the connection.
* The pin is automatically set for the Wii library,
* but can be customized for the SPP library.
*/
void hci_pin_code_request_reply();
/** Respons when no pin was set. */
void hci_pin_code_negative_request_reply();
/**
* Command is used to reply to a Link Key Request event from the BR/EDR Controller
* if the Host does not have a stored Link Key for the connection.
*/
void hci_link_key_request_negative_reply();
/** Used to try to authenticate with the remote device. */
void hci_authentication_request();
/** Start a HCI inquiry. */
void hci_inquiry();
/** Cancel a HCI inquiry. */
void hci_inquiry_cancel();
/** Connect to a device. */
void hci_connect();
/**@}*/
/** @name L2CAP Commands */
/**
* Used to send L2CAP Commands.
* @param handle HCI Handle.
* @param data Data to send.
* @param nbytes Number of bytes to send.
* @param channelLow,channelHigh Low and high byte of channel to send to.
* If argument is omitted then the Standard L2CAP header: Channel ID (0x01) for ACL-U will be used.
*/
void L2CAP_Command(uint16_t handle, uint8_t* data, uint8_t nbytes, uint8_t channelLow = 0x01, uint8_t channelHigh = 0x00);
/**
* L2CAP Connection Request.
* @param handle HCI handle.
* @param rxid Identifier.
* @param scid Source Channel Identifier.
* @param psm Protocol/Service Multiplexer - see: https://www.bluetooth.org/Technical/AssignedNumbers/logical_link.htm.
*/
void l2cap_connection_request(uint16_t handle, uint8_t rxid, uint8_t* scid, uint16_t psm);
/**
* L2CAP Connection Response.
* @param handle HCI handle.
* @param rxid Identifier.
* @param dcid Destination Channel Identifier.
* @param scid Source Channel Identifier.
* @param result Result - First send ::PENDING and then ::SUCCESSFUL.
*/
void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid, uint8_t result);
/**
* L2CAP Config Request.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param dcid Destination Channel Identifier.
*/
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t* dcid);
/**
* L2CAP Config Response.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param scid Source Channel Identifier.
*/
void l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t* scid);
/**
* L2CAP Disconnection Request.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param dcid Device Channel Identifier.
* @param scid Source Channel Identifier.
*/
void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid);
/**
* L2CAP Disconnection Response.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param dcid Device Channel Identifier.
* @param scid Source Channel Identifier.
*/
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid);
/**
* L2CAP Information Response.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param infoTypeLow,infoTypeHigh Infotype.
*/
void l2cap_information_response(uint16_t handle, uint8_t rxid, uint8_t infoTypeLow, uint8_t infoTypeHigh);
/**@}*/
/** Use this to see if it is waiting for a incoming connection. */
bool watingForConnection;
/** This is used by the service to know when to store the device information. */
bool l2capConnectionClaimed;
/** This is used by the SPP library to claim the current SDP incoming request. */
bool sdpConnectionClaimed; bool sdpConnectionClaimed;
/** This is used by the SPP library to claim the current RFCOMM incoming request. */
bool rfcommConnectionClaimed; bool rfcommConnectionClaimed;
const char* btdName; // These are set by the SPP library /** The name you wish to make the dongle show up as. It is set automatically by the SPP library. */
const char* btdName;
/** The pin you wish to make the dongle use for authentication. It is set automatically by the SPP library. */
const char* btdPin; const char* btdPin;
uint8_t my_bdaddr[6]; // The bluetooth dongles Bluetooth address /** The bluetooth dongles Bluetooth address. */
uint16_t hci_handle; // HCI handle for the last connection uint8_t my_bdaddr[6];
uint8_t disc_bdaddr[6]; // Last incoming devices Bluetooth address /** HCI handle for the last connection. */
uint8_t remote_name[30]; // First 30 chars of last remote name uint16_t hci_handle;
/** Last incoming devices Bluetooth address. */
uint8_t disc_bdaddr[6];
/** First 30 chars of last remote name. */
uint8_t remote_name[30];
/**
* The supported HCI Version read from the Bluetooth dongle.
* Used by the PS3BT library to check the HCI Version of the Bluetooth dongle,
* it should be at least 3 to work properly with the library.
*/
uint8_t hci_version; uint8_t hci_version;
/** Used to only send the ACL data to the wiimote. */
bool connectToWii; // Used to only send the ACL data to the wiimote bool connectToWii;
/** True if a Wiimote is connecting. */
bool incomingWii; bool incomingWii;
/** True when it should pair with the incoming Wiimote. */
bool pairWithWii; bool pairWithWii;
bool motionPlusInside; // True if it's the new Wiimote with the Motion Plus Inside /** True if it's the new Wiimote with the Motion Plus Inside or a Wii U Pro Controller. */
bool wiiUProController; // True if it's a Wii U Pro Controller bool motionPlusInside;
/** True if it's a Wii U Pro Controller. */
/* HCI Commands */ bool wiiUProController;
void HCI_Command(uint8_t* data, uint16_t nbytes);
void hci_reset();
void hci_read_bdaddr();
void hci_read_local_version_information();
void hci_set_local_name(const char* name);
void hci_write_scan_enable();
void hci_remote_name();
void hci_accept_connection();
void hci_write_scan_disable();
void hci_disconnect(uint16_t handle);
void hci_pin_code_request_reply();
void hci_pin_code_negative_request_reply();
void hci_link_key_request_negative_reply();
void hci_authentication_request();
void hci_inquiry();
void hci_inquiry_cancel();
void hci_connect();
/* L2CAP Commands */
void L2CAP_Command(uint16_t handle, uint8_t* data, uint8_t nbytes, uint8_t channelLow = 0x01, uint8_t channelHigh = 0x00); // Standard L2CAP header: Channel ID (0x01) for ACL-U
void l2cap_connection_request(uint16_t handle, uint8_t rxid, uint8_t* scid, uint16_t psm);
void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid, uint8_t result);
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t* dcid);
void l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t* scid);
void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid);
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid);
void l2cap_information_response(uint16_t handle, uint8_t rxid, uint8_t infoTypeLow, uint8_t infoTypeHigh);
protected: protected:
/* Mandatory USB members */ /** Pointer to USB class instance. */
USB *pUsb; USB *pUsb;
uint8_t bAddress; // Device address /** Device address. */
EpInfo epInfo[BTD_MAX_ENDPOINTS]; // Endpoint info structure uint8_t bAddress;
/** Endpoint info structure. */
EpInfo epInfo[BTD_MAX_ENDPOINTS];
uint8_t bConfNum; // Configuration number /** Configuration number. */
uint8_t bNumEP; // Total number of endpoints in the configuration uint8_t bConfNum;
uint32_t qNextPollTime; // Next poll time /** Total number of endpoints in the configuration. */
uint8_t bNumEP;
/** Next poll time based on poll interval taken from the USB descriptor. */
uint32_t qNextPollTime;
#define BTD_CONTROL_PIPE 0 // Bluetooth dongles control endpoint /** Bluetooth dongle control endpoint. */
static const uint8_t BTD_EVENT_PIPE; // HCI event endpoint index static const uint8_t BTD_CONTROL_PIPE;
static const uint8_t BTD_DATAIN_PIPE; // ACL In endpoint index /** HCI event endpoint index. */
static const uint8_t BTD_DATAOUT_PIPE; // ACL Out endpoint index static const uint8_t BTD_EVENT_PIPE;
/** ACL In endpoint index. */
static const uint8_t BTD_DATAIN_PIPE;
/** ACL Out endpoint index. */
static const uint8_t BTD_DATAOUT_PIPE;
/**
* Used to print the USB Endpoint Descriptor.
* @param ep_ptr Pointer to USB Endpoint Descriptor.
*/
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr); void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
private: private:
@ -241,7 +417,7 @@ private:
bool bPollEnable; bool bPollEnable;
uint8_t pollInterval; uint8_t pollInterval;
/* variables used by high level HCI task */ /* Variables used by high level HCI task */
uint8_t hci_state; //current state of bluetooth hci connection uint8_t hci_state; //current state of bluetooth hci connection
uint16_t hci_counter; // counter used for bluetooth hci reset loops uint16_t hci_counter; // counter used for bluetooth hci reset loops
uint8_t hci_num_reset_loops; // this value indicate how many times it should read before trying to reset uint8_t hci_num_reset_loops; // this value indicate how many times it should read before trying to reset

137
PS3BT.h
View file

@ -57,52 +57,149 @@
#define l2cap_disconnect_response_control_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE) #define l2cap_disconnect_response_control_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE)
#define l2cap_disconnect_response_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE) #define l2cap_disconnect_response_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE)
/**
* This BluetoothService class implements support for all the official PS3 Controllers:
* Dualshock 3, Navigation or a Motion controller via Bluetooth.
*
* Information about the protocol can be found at the wiki: https://github.com/felis/USB_Host_Shield_2.0/wiki/PS3-Information.
*/
class PS3BT : public BluetoothService { class PS3BT : public BluetoothService {
public: public:
/**
* Constructor for the PS3BT class.
* @param pBtd Pointer to BTD class instance.
* @param btadr5,btadr4,btadr3,btadr2,btadr1,btadr0
* Pass your dongles Bluetooth address into the constructor,
* This will set BTD#my_bdaddr, so you don't have to plug in the dongle before pairing with your controller.
*/
PS3BT(BTD *pBtd, uint8_t btadr5=0, uint8_t btadr4=0, uint8_t btadr3=0, uint8_t btadr2=0, uint8_t btadr1=0, uint8_t btadr0=0); PS3BT(BTD *pBtd, uint8_t btadr5=0, uint8_t btadr4=0, uint8_t btadr3=0, uint8_t btadr2=0, uint8_t btadr1=0, uint8_t btadr0=0);
// BluetoothService implementation /** @name BluetoothService implementation */
virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services /**
virtual void Run(); // Used to run part of the state maschine * Used to pass acldata to the services.
virtual void Reset(); // Use this to reset the service * @param ACLData Incoming acldata.
virtual void disconnect(); // Use this void to disconnect any of the controllers */
virtual void ACLData(uint8_t* ACLData);
/** Used to run part of the state maschine. */
virtual void Run();
/** Use this to reset the service. */
virtual void Reset();
/** Used this to disconnect any of the controllers. */
virtual void disconnect();
/**@}*/
/* PS3 Controller Commands */ /** @name PS3 Controller functions */
/* /**
getButtonPress will return true as long as the button is held down * getButtonPress(Button b) will return true as long as the button is held down
While getButtonClick will only return it once * While getButtonClick(Button b) will only return it once
So you instance if you need to increase a variable once you would use getButtonClick, * So you instance if you need to increase a variable once you would use getButtonClick(Button b),
but if you need to drive a robot forward you would use getButtonPress * but if you need to drive a robot forward you would use getButtonPress(Button b).
*/ */
bool getButtonPress(Button b); bool getButtonPress(Button b);
bool getButtonClick(Button b); bool getButtonClick(Button b);
/**@}*/
/** @name PS3 Controller functions */
/**
* Used to get the analog value from button presses.
* @param a The ::Button to read.
* The supported buttons are:
* ::UP, ::RIGHT, ::DOWN, ::LEFT, ::L1, ::L2, ::R1, ::R2,
* ::TRIANGLE, ::CIRCLE, ::CROSS, ::SQUARE, and ::T.
* @return Analog value in the range of 0-255.
*/
uint8_t getAnalogButton(Button a); uint8_t getAnalogButton(Button a);
/**
* Used to read the analog joystick.
* @param a ::LeftHatX, ::LeftHatY, ::RightHatX, and ::RightHatY.
* @return Return the analog value in the range of 0-255.
*/
uint8_t getAnalogHat(AnalogHat a); uint8_t getAnalogHat(AnalogHat a);
/**
* Used to read the sensors inside the Dualshock 3 and Move controller.
* @param a
* The Dualshock 3 has a 3-axis accelerometer and a 1-axis gyro inside.
* The Move controller has a 3-axis accelerometer, a 3-axis gyro, a 3-axis magnetometer
* and a temperature sensor inside.
* @return Return the raw sensor value.
*/
int16_t getSensor(Sensor a); int16_t getSensor(Sensor a);
/**
* Use this to get ::Pitch and ::Roll calculated using the accelerometer.
* @param a Either ::Pitch or ::Roll.
* @return Return the angle in the range of 0-360.
*/
double getAngle(Angle a); double getAngle(Angle a);
/**
* Read the sensors inside the Move controller.
* @param a ::aXmove, ::aYmove, ::aZmove, ::gXmove, ::gYmove, ::gZmove, ::mXmove, ::mYmove, and ::mXmove.
* @return The value in SI units.
*/
double get9DOFValues(Sensor a); double get9DOFValues(Sensor a);
/**
* Get the ::Status from the controller.
* @param c The ::Status you want to read.
* @return True if correct and false if not.
*/
bool getStatus(Status c); bool getStatus(Status c);
/**
* Read all the available ::Status from the controller.
* @return One large string with all the information.
*/
String getStatusString(); String getStatusString();
/**
* Read the temperature from the Move controller.
* @return The temperature in degrees celsius.
*/
String getTemperature(); String getTemperature();
/* HID Commands */ /** Used to set all LEDs and ::Rumble off. */
/* Commands for Dualshock 3 and Navigation controller */
void setAllOff(); void setAllOff();
/** Turn off ::Rumble. */
void setRumbleOff(); void setRumbleOff();
/**
* Turn on ::Rumble.
* @param mode Either ::RumbleHigh or ::RumbleLow.
*/
void setRumbleOn(Rumble mode); void setRumbleOn(Rumble mode);
/**
* Turn the specific ::LED off.
* @param a The ::LED to turn off.
*/
void setLedOff(LED a); void setLedOff(LED a);
/**
* Turn the specific ::LED on.
* @param a The ::LED to turn on.
*/
void setLedOn(LED a); void setLedOn(LED a);
/**
* Toggle the specific ::LED.
* @param a The ::LED to toggle.
*/
void setLedToggle(LED a); void setLedToggle(LED a);
/* Commands for Motion controller only */ /**
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b); // Use this to set the Color using RGB values * Use this to set the Color using RGB values.
void moveSetBulb(Colors color); // Use this to set the Color using the predefined colors in "enum Colors" * @param r,g,b RGB value.
*/
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b);
/**
* Use this to set the color using the predefined colors in ::Colors.
* @param color The desired color.
*/
void moveSetBulb(Colors color);
/**
* Set the rumble value inside the Move controller.
* @param rumble The desired value in the range from 64-255.
*/
void moveSetRumble(uint8_t rumble); void moveSetRumble(uint8_t rumble);
/**@}*/
bool PS3Connected; // Variable used to indicate if the normal playstation controller is successfully connected /** Variable used to indicate if the normal playstation controller is successfully connected. */
bool PS3MoveConnected; // Variable used to indicate if the move controller is successfully connected bool PS3Connected;
bool PS3NavigationConnected; // Variable used to indicate if the navigation controller is successfully connected /** Variable used to indicate if the move controller is successfully connected. */
bool PS3MoveConnected;
/** Variable used to indicate if the navigation controller is successfully connected. */
bool PS3NavigationConnected;
private: private:
/* mandatory members */ /* mandatory members */

View file

@ -20,6 +20,7 @@
#include "controllerEnums.h" #include "controllerEnums.h"
/** Used to set the LEDs on the controllers */
const uint8_t LEDS[] PROGMEM = { const uint8_t LEDS[] PROGMEM = {
0x01, // LED1 0x01, // LED1
0x02, // LED2 0x02, // LED2
@ -33,6 +34,12 @@ const uint8_t LEDS[] PROGMEM = {
0x0E, // LED9 0x0E, // LED9
0x0F // LED10 0x0F // LED10
}; };
/**
* Buttons on the controllers
*
* <B>Note:</B> that the location is shiftet 9 when it's connected via USB.
*/
const uint32_t BUTTONS[] PROGMEM = { const uint32_t BUTTONS[] PROGMEM = {
0x10, // UP 0x10, // UP
0x20, // RIGHT 0x20, // RIGHT
@ -59,9 +66,12 @@ const uint32_t BUTTONS[] PROGMEM = {
0x100000 // T - covers 12 bits - we only need to read the top 8 0x100000 // T - covers 12 bits - we only need to read the top 8
}; };
/**
* Analog buttons on the controllers
*
* <B>Note:</B> that the location is shiftet 9 when it's connected via USB.
*/
const uint8_t ANALOGBUTTONS[] PROGMEM = { const uint8_t ANALOGBUTTONS[] PROGMEM = {
// Note that the location is shiftet 9 when it's connected via USB
// Sixaxis Dualshcock 3 & Navigation controller
23, // UP_ANALOG 23, // UP_ANALOG
24, // RIGHT_ANALOG 24, // RIGHT_ANALOG
25, // DOWN_ANALOG 25, // DOWN_ANALOG
@ -82,44 +92,69 @@ const uint8_t ANALOGBUTTONS[] PROGMEM = {
15 // T_ANALOG - Both at byte 14 (last reading) and byte 15 (current reading) 15 // T_ANALOG - Both at byte 14 (last reading) and byte 15 (current reading)
}; };
/** Used to set the colors of the move controller. */
enum Colors { enum Colors {
// Used to set the colors of the move controller /** r = 255, g = 0, b = 0 */
Red = 0xFF0000, // r = 255, g = 0, b = 0 Red = 0xFF0000,
Green = 0xFF00, // r = 0, g = 255, b = 0 /** r = 0, g = 255, b = 0 */
Blue = 0xFF, // r = 0, g = 0, b = 255 Green = 0xFF00,
/** r = 0, g = 0, b = 255 */
Blue = 0xFF,
Yellow = 0xFFEB04, // r = 255, g = 235, b = 4 /** r = 255, g = 235, b = 4 */
Lightblue = 0xFFFF, // r = 0, g = 255, b = 255 Yellow = 0xFFEB04,
Purble = 0xFF00FF, // r = 255, g = 0, b = 255 /** r = 0, g = 255, b = 255 */
Lightblue = 0xFFFF,
/** r = 255, g = 0, b = 255 */
Purble = 0xFF00FF,
White = 0xFFFFFF, // r = 255, g = 255, b = 255 /** r = 255, g = 255, b = 255 */
Off = 0x00, // r = 0, g = 0, b = 0 White = 0xFFFFFF,
/** r = 0, g = 0, b = 0 */
Off = 0x00,
}; };
/**
* Sensors inside the Sixaxis Dualshock 3 and Move controller.
*
* <B>Note:</B> that the location is shiftet 9 when it's connected via USB.
*/
enum Sensor { enum Sensor {
// Note that the location is shiftet 9 when it's connected via USB /** Accelerometer x-axis */
// Sensors inside the Sixaxis Dualshock 3 controller
aX = 50, aX = 50,
/** Accelerometer y-axis */
aY = 52, aY = 52,
/** Accelerometer z-axis */
aZ = 54, aZ = 54,
/** Gyro z-axis */
gZ = 56, gZ = 56,
// Sensors inside the Move Motion controller /** Accelerometer x-axis */
aXmove = 28, aXmove = 28,
/** Accelerometer z-axis */
aZmove = 30, aZmove = 30,
/** Accelerometer y-axis */
aYmove = 32, aYmove = 32,
/** Gyro x-axis */
gXmove = 40, gXmove = 40,
/** Gyro z-axis */
gZmove = 42, gZmove = 42,
/** Gyro y-axis */
gYmove = 44, gYmove = 44,
/** Temperature sensor */
tempMove = 46, tempMove = 46,
/** Magnetometer x-axis */
mXmove = 47, mXmove = 47,
/** Magnetometer z-axis */
mZmove = 49, mZmove = 49,
/** Magnetometer y-axis */
mYmove = 50, mYmove = 50,
}; };
/** Used to get the angle calculated using the accelerometer. */
enum Angle { enum Angle {
// Used to get the angle calculated using atan2
Pitch = 0x01, Pitch = 0x01,
Roll = 0x02, Roll = 0x02,
}; };

151
PS3USB.h
View file

@ -53,59 +53,174 @@
#define PS3_MAX_ENDPOINTS 3 #define PS3_MAX_ENDPOINTS 3
/**
* This class implements support for all the official PS3 Controllers:
* Dualshock 3, Navigation or a Motion controller via USB.
*
* One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB.
*
* Information about the protocol can be found at the wiki: https://github.com/felis/USB_Host_Shield_2.0/wiki/PS3-Information.
*/
class PS3USB : public USBDeviceConfig { class PS3USB : public USBDeviceConfig {
public: public:
/**
* Constructor for the PS3USB class.
* @param pUsb Pointer to USB class instance.
* @param btadr5,btadr4,btadr3,btadr2,btadr1,btadr0
* Pass your dongles Bluetooth address into the constructor,
* so you are able to pair the controller with a Bluetooth dongle.
*/
PS3USB(USB *pUsb, uint8_t btadr5=0, uint8_t btadr4=0, uint8_t btadr3=0, uint8_t btadr2=0, uint8_t btadr1=0, uint8_t btadr0=0); PS3USB(USB *pUsb, uint8_t btadr5=0, uint8_t btadr4=0, uint8_t btadr3=0, uint8_t btadr2=0, uint8_t btadr1=0, uint8_t btadr0=0);
// USBDeviceConfig implementation /** @name USBDeviceConfig implementation */
/**
* Initialize the PS3 Controller.
* @param parent Hub number.
* @param port Port number on the hub.
* @param lowspeed Speed of the device.
* @return 0 on success.
*/
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed); virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
/**
* Release the USB device.
* @return 0 on success.
*/
virtual uint8_t Release(); virtual uint8_t Release();
/**
* Poll the USB Input endpoins and run the state machines.
* @return 0 on success.
*/
virtual uint8_t Poll(); virtual uint8_t Poll();
/**
* Get the device address.
* @return The device address.
*/
virtual uint8_t GetAddress() { return bAddress; }; virtual uint8_t GetAddress() { return bAddress; };
/**
* Used to check if the controller has been initialized.
* @return True if it's ready.
*/
virtual bool isReady() { return bPollEnable; }; virtual bool isReady() { return bPollEnable; };
/**@}*/
/**
* Used to set the Bluetooth address inside the Dualshock 3 and Navigation controller.
* @param BDADDR Your dongles Bluetooth address.
*/
void setBdaddr(uint8_t* BDADDR); void setBdaddr(uint8_t* BDADDR);
/**
* Used to set the Bluetooth address inside the Move controller.
* @param BDADDR Your dongles Bluetooth address.
*/
void setMoveBdaddr(uint8_t* BDADDR); void setMoveBdaddr(uint8_t* BDADDR);
/* PS3 Controller Commands */ /** @name PS3 Controller functions */
/* /**
getButtonPress will return true as long as the button is held down * getButtonPress(Button b) will return true as long as the button is held down
While getButtonClick will only return it once * While getButtonClick(Button b) will only return it once
So you instance if you need to increase a variable once you would use getButtonClick, * So you instance if you need to increase a variable once you would use getButtonClick(Button b),
but if you need to drive a robot forward you would use getButtonPress * but if you need to drive a robot forward you would use getButtonPress(Button b).
*/ */
bool getButtonPress(Button b); bool getButtonPress(Button b);
bool getButtonClick(Button b); bool getButtonClick(Button b);
/**@}*/
/** @name PS3 Controller functions */
/**
* Used to get the analog value from button presses.
* @param a The ::Button to read.
* The supported buttons are:
* ::UP, ::RIGHT, ::DOWN, ::LEFT, ::L1, ::L2, ::R1, ::R2,
* ::TRIANGLE, ::CIRCLE, ::CROSS, ::SQUARE, and ::T.
* @return Analog value in the range of 0-255.
*/
uint8_t getAnalogButton(Button a); uint8_t getAnalogButton(Button a);
/**
* Used to read the analog joystick.
* @param a ::LeftHatX, ::LeftHatY, ::RightHatX, and ::RightHatY.
* @return Return the analog value in the range of 0-255.
*/
uint8_t getAnalogHat(AnalogHat a); uint8_t getAnalogHat(AnalogHat a);
/**
* Used to read the sensors inside the Dualshock 3 controller.
* @param a
* The Dualshock 3 has a 3-axis accelerometer and a 1-axis gyro inside.
* @return Return the raw sensor value.
*/
uint16_t getSensor(Sensor a); uint16_t getSensor(Sensor a);
/**
* Use this to get ::Pitch and ::Roll calculated using the accelerometer.
* @param a Either ::Pitch or ::Roll.
* @return Return the angle in the range of 0-360.
*/
double getAngle(Angle a); double getAngle(Angle a);
/**
* Get the ::Status from the controller.
* @param c The ::Status you want to read.
* @return True if correct and false if not.
*/
bool getStatus(Status c); bool getStatus(Status c);
/**
* Read all the available ::Status from the controller.
* @return One large string with all the information.
*/
String getStatusString(); String getStatusString();
/* Commands for Dualshock 3 and Navigation controller */ /** Used to set all LEDs and ::Rumble off. */
void setAllOff(); void setAllOff();
/** Turn off ::Rumble. */
void setRumbleOff(); void setRumbleOff();
/**
* Turn on ::Rumble.
* @param mode Either ::RumbleHigh or ::RumbleLow.
*/
void setRumbleOn(Rumble mode); void setRumbleOn(Rumble mode);
/**
* Turn the specific ::LED off.
* @param a The ::LED to turn off.
*/
void setLedOff(LED a); void setLedOff(LED a);
/**
* Turn the specific ::LED on.
* @param a The ::LED to turn on.
*/
void setLedOn(LED a); void setLedOn(LED a);
/**
* Toggle the specific ::LED.
* @param a The ::LED to toggle.
*/
void setLedToggle(LED a); void setLedToggle(LED a);
/* Commands for Motion controller only */ /**
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b);//Use this to set the Color using RGB values * Use this to set the Color using RGB values.
void moveSetBulb(Colors color);//Use this to set the Color using the predefined colors in "enum Colors" * @param r,g,b RGB value.
*/
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b);
/**
* Use this to set the color using the predefined colors in ::Colors.
* @param color The desired color.
*/
void moveSetBulb(Colors color);
/**
* Set the rumble value inside the Move controller.
* @param rumble The desired value in the range from 64-255.
*/
void moveSetRumble(uint8_t rumble); void moveSetRumble(uint8_t rumble);
/**@}*/
bool PS3Connected;// Variable used to indicate if the normal playstation controller is successfully connected /** Variable used to indicate if the normal playstation controller is successfully connected. */
bool PS3MoveConnected;// Variable used to indicate if the move controller is successfully connected bool PS3Connected;
bool PS3NavigationConnected;// Variable used to indicate if the navigation controller is successfully connected */ /** Variable used to indicate if the move controller is successfully connected. */
bool PS3MoveConnected;
/** Variable used to indicate if the navigation controller is successfully connected. */
bool PS3NavigationConnected;
protected: protected:
/* mandatory members */ /** Pointer to USB class instance. */
USB *pUsb; USB *pUsb;
uint8_t bAddress; // device address /** Device address. */
EpInfo epInfo[PS3_MAX_ENDPOINTS]; //endpoint info structure uint8_t bAddress;
/** Endpoint info structure. */
EpInfo epInfo[PS3_MAX_ENDPOINTS];
private: private:
bool bPollEnable; bool bPollEnable;

12
SPP.cpp
View file

@ -700,10 +700,10 @@ void SPP::print(const String &str) {
RFCOMM_Command(l2capoutbuf,length+4); RFCOMM_Command(l2capoutbuf,length+4);
} }
void SPP::print(const char* data) { void SPP::print(const char* str) {
if(!connected) if(!connected)
return; return;
uint8_t length = strlen(data); uint8_t length = strlen(str);
if(length > (sizeof(l2capoutbuf)-4)) if(length > (sizeof(l2capoutbuf)-4))
length = sizeof(l2capoutbuf)-4; length = sizeof(l2capoutbuf)-4;
l2capoutbuf[0] = rfcommChannelConnection | 0 | 0 | extendAddress;; // RFCOMM Address l2capoutbuf[0] = rfcommChannelConnection | 0 | 0 | extendAddress;; // RFCOMM Address
@ -711,7 +711,7 @@ void SPP::print(const char* data) {
l2capoutbuf[2] = length << 1 | 1; // Length l2capoutbuf[2] = length << 1 | 1; // Length
uint8_t i = 0; uint8_t i = 0;
for(; i < length; i++) for(; i < length; i++)
l2capoutbuf[i+3] = data[i]; l2capoutbuf[i+3] = str[i];
l2capoutbuf[i+3] = calcFcs(l2capoutbuf); l2capoutbuf[i+3] = calcFcs(l2capoutbuf);
RFCOMM_Command(l2capoutbuf,length+4); RFCOMM_Command(l2capoutbuf,length+4);
@ -754,9 +754,9 @@ void SPP::println(const String &str) {
String output = str + "\r\n"; String output = str + "\r\n";
print(output); print(output);
} }
void SPP::println(const char* data) { void SPP::println(const char* str) {
char output[strlen(data)+3]; char output[strlen(str)+3];
strcpy(output,data); strcpy(output,str);
strcat(output,"\r\n"); strcat(output,"\r\n");
print(output); print(output);
} }

147
SPP.h
View file

@ -89,42 +89,135 @@
#define BT_RFCOMM_NSC_RSP 0x11 #define BT_RFCOMM_NSC_RSP 0x11
*/ */
/** This BluetoothService class implements the Serial Port Protocol (SPP). */
class SPP : public BluetoothService { class SPP : public BluetoothService {
public: public:
/**
* Constructor for the SPP class.
* @param p Pointer to BTD class instance.
* @param name Set the name to BTD#btdName. If argument is omitted, then "Arduino" will be used.
* @param pin Write the pin to BTD#btdPin. If argument is omitted, then "1234" will be used.
*/
SPP(BTD *p, const char* name = "Arduino", const char* pin = "1234"); SPP(BTD *p, const char* name = "Arduino", const char* pin = "1234");
// BluetoothService implementation /** @name BluetoothService implementation */
virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services /**
virtual void Run(); // Used to establish the connection automatically * Used to pass acldata to the services.
virtual void Reset(); // Use this to reset the service * @param ACLData Incoming acldata.
virtual void disconnect(); // Used this void to disconnect the virtual serial port */
virtual void ACLData(uint8_t* ACLData);
/** Used to establish the connection automatically. */
virtual void Run();
/** Use this to reset the service. */
virtual void Reset();
/** Used this to disconnect the virtual serial port. */
virtual void disconnect();
/**@}*/
bool connected;// Variable used to indicate if the connection is established /** Variable used to indicate if the connection is established. */
bool connected;
/* Serial port profile (SPP) commands */ /** @name Serial port profile (SPP) Print functions */
void print(const String &); // Used to send strings /** Used to send Strings. */
void print(const char* data); // Used to send strings /**
void print(uint8_t data); // Used to send single bytes * Used to send Arduino String data type.
void print(uint8_t* array, uint8_t length); // Used to send arrays * @param str String to send.
void print(const __FlashStringHelper *); // Used to print strings stored in flash */
void print(const String &str);
/**
* Same as print(const String &str), but will include newline and carriage return.
* @param str String to send.
*/
void println(const String &str);
/**
* Used to send standard strings.
* @param str String to send.
*/
void print(const char* str);
/**
* Same as print(const char* data), but will include newline and carriage return.
* @param str String to send.
*/
void println(const char* str);
/**
* Used to send single bytes.
* @param data Data to send.
*/
void print(uint8_t data);
/**
* Same as print(uint8_t data), but will include newline and carriage return.
* @param data Data to send.
*/
void println(uint8_t data);
/**
* Used to send arrays.
* @param array Array to send.
* @param length Number of bytes to send.
*/
void print(uint8_t* array, uint8_t length);
/**
* Same as print(uint8_t* array, uint8_t length), but will include newline and carriage return.
* @param array Array to send.
* @param length Number of bytes to send.
*/
void println(uint8_t* array, uint8_t length);
/**
* Used to print strings stored in flash.
* @param ifsh String to send - see: http://playground.arduino.cc/Learning/Memory.
*/
void print(const __FlashStringHelper *ifsh);
/**
* Same as print(const __FlashStringHelper *ifsh), but will include newline and carriage return.
* @param ifsh String to send - see: http://playground.arduino.cc/Learning/Memory.
*/
void println(const __FlashStringHelper *ifsh);
/** Use this to print newline and carriage return. */
void println(void);
void println(const String &); // Include newline and carriage return /**
void println(const char* data); // Include newline and carriage return * Used to print integers.
void println(uint8_t data); // Include newline and carriage return * @param n Integers to send.
void println(uint8_t* array, uint8_t length); // Include newline and carriage return */
void println(const __FlashStringHelper *); // Include newline and carriage return void printNumber(int32_t n);
void println(void); // Use this to print newline and carriage return /**
* Same as printNumber(int32_t n), but will include newline and carriage return.
* @param n Integers to send.
*/
void printNumberln(int32_t n);
/**
* Used to print floating-point numbers.
* @param n Floating-point number to print.
* @param digits Number of digits to send. If argument is omitted, then 2 digits will be used.
*/
void printNumber(double n, uint8_t digits = 2);
/**
* Same as printNumber(double n, uint8_t digits), but will include newline and carriage return.
* @param n Floating-point number to print.
* @param digits Number of digits to send. If argument is omitted, then 2 digits will be used.
*/
void printNumberln(double n, uint8_t digits = 2);
void printNumber(int32_t n); // These must be used to print numbers /**
void printNumberln(int32_t n); // This will include newline and carriage return * Helper function to convert from double to string.
void printNumber(double n, uint8_t digits = 2); // These must be used to print floating-point numbers * @param input Floating-point number to convert.
void printNumberln(double n, uint8_t digits = 2); // This will include newline and carriage return * @param output Output buffer.
* @param digits Number of digits to convert. If argument is omitted, then 2 digits will be used.
*/
void doubleToString(double input, char* output, uint8_t digits = 2);
void doubleToString(double input, char* output, uint8_t digits = 2); // Helper function to convert from double to string /**
* Get number of bytes waiting to be read.
uint8_t available() { return rfcommAvailable; }; // Get the bytes waiting to be read * @return Return the number of bytes ready to be read.
uint8_t read(); // Used to read the buffer */
void flush() { rfcommAvailable = 0; }; // Discard all the bytes in the buffer uint8_t available() { return rfcommAvailable; };
/**
* Used to read the buffer.
* @return Return the byte. Will return 0 if no byte is available.
*/
uint8_t read();
/** Discard all the bytes in the buffer. */
void flush() { rfcommAvailable = 0; };
/**@}*/
private: private:
/* Bluetooth dongle library pointer */ /* Bluetooth dongle library pointer */

28
Wii.cpp
View file

@ -292,8 +292,8 @@ void WII::ACLData(uint8_t* l2capinbuf) {
accX = ((l2capinbuf[12] << 2) | (l2capinbuf[10] & 0x60 >> 5))-500; accX = ((l2capinbuf[12] << 2) | (l2capinbuf[10] & 0x60 >> 5))-500;
accY = ((l2capinbuf[13] << 2) | (l2capinbuf[11] & 0x20 >> 4))-500; accY = ((l2capinbuf[13] << 2) | (l2capinbuf[11] & 0x20 >> 4))-500;
accZ = ((l2capinbuf[14] << 2) | (l2capinbuf[11] & 0x40 >> 5))-500; accZ = ((l2capinbuf[14] << 2) | (l2capinbuf[11] & 0x40 >> 5))-500;
wiiMotePitch = (atan2(accY,accZ)+PI)*RAD_TO_DEG; wiimotePitch = (atan2(accY,accZ)+PI)*RAD_TO_DEG;
wiiMoteRoll = (atan2(accX,accZ)+PI)*RAD_TO_DEG; wiimoteRoll = (atan2(accX,accZ)+PI)*RAD_TO_DEG;
} }
switch (l2capinbuf[9]) { switch (l2capinbuf[9]) {
case 0x20: // Status Information - (a1) 20 BB BB LF 00 00 VV case 0x20: // Status Information - (a1) 20 BB BB LF 00 00 VV
@ -410,13 +410,13 @@ void WII::ACLData(uint8_t* l2capinbuf) {
case 0x30: // Core buttons - (a1) 30 BB BB case 0x30: // Core buttons - (a1) 30 BB BB
break; break;
case 0x31: // Core Buttons and Accelerometer - (a1) 31 BB BB AA AA AA case 0x31: // Core Buttons and Accelerometer - (a1) 31 BB BB AA AA AA
pitch = wiiMotePitch; // The pitch is just equal to the angle calculated from the wiimote as there is no Motion Plus connected pitch = wiimotePitch; // The pitch is just equal to the angle calculated from the wiimote as there is no Motion Plus connected
roll = wiiMoteRoll; roll = wiimoteRoll;
break; break;
case 0x32: // Core Buttons with 8 Extension bytes - (a1) 32 BB BB EE EE EE EE EE EE EE EE case 0x32: // Core Buttons with 8 Extension bytes - (a1) 32 BB BB EE EE EE EE EE EE EE EE
case 0x33: // Core Buttons with Accelerometer and 12 IR bytes - (a1) 33 BB BB AA AA AA II II II II II II II II II II II II case 0x33: // Core Buttons with Accelerometer and 12 IR bytes - (a1) 33 BB BB AA AA AA II II II II II II II II II II II II
pitch = wiiMotePitch; // The pitch is just equal to the angle calculated from the wiimote as there is no Motion Plus data available pitch = wiimotePitch; // The pitch is just equal to the angle calculated from the wiimote as there is no Motion Plus data available
roll = wiiMoteRoll; roll = wiimoteRoll;
#ifdef WIICAMERA #ifdef WIICAMERA
// Read the IR data // Read the IR data
IR_object_x1 = (l2capinbuf[15] | ((uint16_t)(l2capinbuf[17] & 0x30) << 4)); // x position IR_object_x1 = (l2capinbuf[15] | ((uint16_t)(l2capinbuf[17] & 0x30) << 4)); // x position
@ -479,8 +479,8 @@ void WII::ACLData(uint8_t* l2capinbuf) {
if(!(l2capinbuf[19] & 0x02)) // Check if fast more is used if(!(l2capinbuf[19] & 0x02)) // Check if fast more is used
rollGyroSpeed *= 4.545; rollGyroSpeed *= 4.545;
pitch = (0.93*(pitch+(pitchGyroSpeed*(double)(micros()-timer)/1000000)))+(0.07*wiiMotePitch); // Use a complimentary filter to calculate the angle pitch = (0.93*(pitch+(pitchGyroSpeed*(double)(micros()-timer)/1000000)))+(0.07*wiimotePitch); // Use a complimentary filter to calculate the angle
roll = (0.93*(roll+(rollGyroSpeed*(double)(micros()-timer)/1000000)))+(0.07*wiiMoteRoll); roll = (0.93*(roll+(rollGyroSpeed*(double)(micros()-timer)/1000000)))+(0.07*wiimoteRoll);
gyroYaw += (yawGyroSpeed*((double)(micros()-timer)/1000000)); gyroYaw += (yawGyroSpeed*((double)(micros()-timer)/1000000));
gyroRoll += (rollGyroSpeed*((double)(micros()-timer)/1000000)); gyroRoll += (rollGyroSpeed*((double)(micros()-timer)/1000000));
@ -496,10 +496,10 @@ void WII::ACLData(uint8_t* l2capinbuf) {
Serial.print(gyroPitch); Serial.print(gyroPitch);
*/ */
/* /*
Serial.print("\twiiMoteRoll: "); Serial.print("\twiimoteRoll: ");
Serial.print(wiiMoteRoll); Serial.print(wiimoteRoll);
Serial.print("\twiiMotePitch: "); Serial.print("\twiimotePitch: ");
Serial.print(wiiMotePitch); Serial.print(wiimotePitch);
*/ */
} else { } else {
if((micros() - timer) > 1000000) { // Loop for 1 sec before resetting the values if((micros() - timer) > 1000000) { // Loop for 1 sec before resetting the values
@ -563,8 +563,8 @@ void WII::ACLData(uint8_t* l2capinbuf) {
nunchuckPitch = (atan2(accY,accZ)+PI)*RAD_TO_DEG; nunchuckPitch = (atan2(accY,accZ)+PI)*RAD_TO_DEG;
nunchuckRoll = (atan2(accX,accZ)+PI)*RAD_TO_DEG; nunchuckRoll = (atan2(accX,accZ)+PI)*RAD_TO_DEG;
pitch = wiiMotePitch; // The pitch is just equal to the angle calculated from the wiimote as there is no Motion Plus connected pitch = wiimotePitch; // The pitch is just equal to the angle calculated from the wiimote as there is no Motion Plus connected
roll = wiiMoteRoll; roll = wiimoteRoll;
} else if(wiiUProControllerConnected) { } else if(wiiUProControllerConnected) {
hatValues[LeftHatX] = (l2capinbuf[15] | l2capinbuf[16] << 8); hatValues[LeftHatX] = (l2capinbuf[15] | l2capinbuf[16] << 8);
hatValues[RightHatX] = (l2capinbuf[17] | l2capinbuf[18] << 8); hatValues[RightHatX] = (l2capinbuf[17] | l2capinbuf[18] << 8);

224
Wii.h
View file

@ -25,7 +25,8 @@
#include "BTD.h" #include "BTD.h"
#include "controllerEnums.h" #include "controllerEnums.h"
//#define WIICAMERA //uncomment to enable IR camera /** You will have to uncomment this to use the IR camera */
//#define WIICAMERA
/* Bluetooth L2CAP states for L2CAP_task() */ /* Bluetooth L2CAP states for L2CAP_task() */
#define L2CAP_WAIT 0 #define L2CAP_WAIT 0
@ -79,107 +80,242 @@
#define PAIR 1 #define PAIR 1
/** Enum used to read the joystick on the Nunchuck. */
enum Hat { enum Hat {
/** Read the x-axis on the Nunchuck joystick. */
HatX = 0, HatX = 0,
/** Read the y-axis on the Nunchuck joystick. */
HatY = 1, HatY = 1,
}; };
/**
* This BluetoothService class implements support for the Wiimote including the Nunchuck and Motion Plus extension.
*
* It also support the Wii U Pro Controller.
*/
class WII : public BluetoothService { class WII : public BluetoothService {
public: public:
/**
* Constructor for the WII class.
* @param p Pointer to BTD class instance.
* @param pair Set this true to pair with the Wiimote. If the argument is omitted then it won't pair with it.
* One can use ::PAIR to set it to true.
*/
WII(BTD *p, bool pair=false); WII(BTD *p, bool pair=false);
// BluetoothService implementation /** @name BluetoothService implementation */
virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services /**
virtual void Run(); // Used to run part of the state maschine * Used to pass acldata to the services.
virtual void Reset(); // Use this to reset the service * @param ACLData Incoming acldata.
virtual void disconnect(); // Use this void to disconnect any of the controllers
/*
getButtonPress will return true as long as the button is held down
While getButtonClick will only return it once
So you instance if you need to increase a variable once you would use getButtonClick,
but if you need to drive a robot forward you would use getButtonPress
*/ */
bool getButtonPress(Button b); // This will read true as long as the button is held down virtual void ACLData(uint8_t* ACLData);
bool getButtonClick(Button b); // This will only be true when the button is clicked the first time /** Used to run part of the state maschine. */
virtual void Run();
/** Use this to reset the service. */
virtual void Reset();
/** Used this to disconnect any of the controllers. */
virtual void disconnect();
/**@}*/
uint8_t getAnalogHat(Hat a); // Used to read the joystick of the Nunchuck /** @name Wii Controller functions */
uint16_t getAnalogHat(AnalogHat a); // Used to read the joystick of the Wii U Pro Controller /**
* getButtonPress(Button b) will return true as long as the button is held down
* While getButtonClick(Button b) will only return it once
* So you instance if you need to increase a variable once you would use getButtonClick(Button b),
* but if you need to drive a robot forward you would use getButtonPress(Button b).
*/
bool getButtonPress(Button b);
bool getButtonClick(Button b);
/**@}*/
double getPitch() { return pitch; }; // Fusioned angle using a complimentary filter if the Motion Plus is connected /** @name Wii Controller functions */
double getRoll() { return roll; }; // Fusioned angle using a complimentary filter if the Motion Plus is connected /**
double getYaw() { return gyroYaw; }; // This is the yaw calculated by the gyro * Used to read the joystick of the Nunchuck.
* @param a Either ::HatX or ::HatY.
* @return Return the analog value in the range from approximately 25-230.
*/
uint8_t getAnalogHat(Hat a);
/**
* Used to read the joystick of the Wii U Pro Controller.
* @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
* @return Return the analog value in the range from approximately 800-3200.
*/
uint16_t getAnalogHat(AnalogHat a);
void setAllOff(); // Turn both rumble and all LEDs off /**
* Pitch calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected.
* @return Pitch in the range from 0-360.
*/
double getPitch() { return pitch; };
/**
* Roll calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected.
* @return Roll in the range from 0-360.
*/
double getRoll() { return roll; };
/**
* This is the yaw calculated by the gyro.
*
* <B>NOTE:</B> This angle will drift a lot and is only available if the Motion Plus extension is connected.
* @return The angle calculated using the gyro.
*/
double getYaw() { return gyroYaw; };
/** Used to set all LEDs and rumble off. */
void setAllOff();
/** Turn off rumble. */
void setRumbleOff(); void setRumbleOff();
/** Turn on rumble. */
void setRumbleOn(); void setRumbleOn();
/** Toggle rumble. */
void setRumbleToggle(); void setRumbleToggle();
/**
* Turn the specific ::LED off.
* @param a The ::LED to turn off.
*/
void setLedOff(LED a); void setLedOff(LED a);
/**
* Turn the specific ::LED on.
* @param a The ::LED to turn on.
*/
void setLedOn(LED a); void setLedOn(LED a);
/**
* Toggle the specific ::LED.
* @param a The ::LED to toggle.
*/
void setLedToggle(LED a); void setLedToggle(LED a);
void setLedStatus(); // This will set the LEDs, so the user can see which connections are active /**
* This will set the LEDs, so the user can see which connections are active.
*
* The first ::LED indicate that the Wiimote is connected,
*
* the second ::LED indicate indicate that a Motion Plus is also connected
*
* the third ::LED will indicate that a Nunchuck controller is also connected.
*/
void setLedStatus();
uint8_t getBatteryLevel() { return batteryLevel; }; // Return the battery level /**
uint8_t getWiiState() { return wiiState; }; // Return the wii state, see: http://wiibrew.org/wiki/Wiimote#0x20:_Status * Return the battery level of the Wiimote.
* @return The barrey level in the range form 0-255.
*/
uint8_t getBatteryLevel() { return batteryLevel; };
/**
* Return the Wiimote state.
* @return See: http://wiibrew.org/wiki/Wiimote#0x20:_Status.
*/
uint8_t getWiiState() { return wiiState; };
/**@}*/
bool wiimoteConnected; // Variable used to indicate if a Wiimote is connected /**@{*/
bool nunchuckConnected; // Variable used to indicate if a Nunchuck controller is connected /** Variable used to indicate if a Wiimote is connected. */
bool motionPlusConnected; // Variable used to indicate if a Nunchuck controller is connected bool wiimoteConnected;
bool wiiUProControllerConnected; // Variable used to indicate if a Wii U Pro controller is connected /** Variable used to indicate if a Nunchuck controller is connected. */
bool nunchuckConnected;
/** Variable used to indicate if a Nunchuck controller is connected. */
bool motionPlusConnected;
/** Variable used to indicate if a Wii U Pro controller is connected. */
bool wiiUProControllerConnected;
/**@}*/
/* IMU Data, might be usefull if you need to do something more advanced than just calculating the angle */ /* IMU Data, might be usefull if you need to do something more advanced than just calculating the angle */
double wiiMotePitch; // Pitch and roll calculated from the accelerometer inside the Wiimote /**@{*/
double wiiMoteRoll; /** Pitch and roll calculated from the accelerometer inside the Wiimote. */
double nunchuckPitch; // Pitch and roll calculated from the accelerometer inside the Nunchuck double wiimotePitch;
double nunchuckRoll; double wiimoteRoll;
/**@}*/
int16_t accX; // Accelerometer values used to calculate pitch and roll /**@{*/
/** Pitch and roll calculated from the accelerometer inside the Nunchuck. */
double nunchuckPitch;
double nunchuckRoll;
/**@}*/
/**@{*/
/** Accelerometer values used to calculate pitch and roll. */
int16_t accX;
int16_t accY; int16_t accY;
int16_t accZ; int16_t accZ;
/**@}*/
/* Variables for the gyro inside the Motion Plus */ /* Variables for the gyro inside the Motion Plus */
double gyroPitch; // This is the pitch calculated by the gyro - use this to tune pitchGyroScale /** This is the pitch calculated by the gyro - use this to tune WII#pitchGyroScale. */
double gyroRoll; // This is the roll calculated by the gyro - use this to tune rollGyroScale double gyroPitch;
double gyroYaw; // This is the yaw calculated by the gyro - use this to tune yawGyroScale /** This is the roll calculated by the gyro - use this to tune WII#rollGyroScale. */
double gyroRoll;
/** This is the yaw calculated by the gyro - use this to tune WII#yawGyroScale. */
double gyroYaw;
double pitchGyroSpeed; // The speed in deg/s from the gyro /**@{*/
/** The speed in deg/s from the gyro. */
double pitchGyroSpeed;
double rollGyroSpeed; double rollGyroSpeed;
double yawGyroSpeed; double yawGyroSpeed;
/**@}*/
uint16_t pitchGyroScale; // You might need to fine-tune these values /**@{*/
/** You might need to fine-tune these values. */
uint16_t pitchGyroScale;
uint16_t rollGyroScale; uint16_t rollGyroScale;
uint16_t yawGyroScale; uint16_t yawGyroScale;
/**@}*/
int16_t gyroYawRaw; // Raw value read directly from the Motion Plus /**@{*/
/** Raw value read directly from the Motion Plus. */
int16_t gyroYawRaw;
int16_t gyroRollRaw; int16_t gyroRollRaw;
int16_t gyroPitchRaw; int16_t gyroPitchRaw;
/**@}*/
int16_t gyroYawZero; // These values are set when the controller is first initialized /**@{*/
/** These values are set when the controller is first initialized. */
int16_t gyroYawZero;
int16_t gyroRollZero; int16_t gyroRollZero;
int16_t gyroPitchZero; int16_t gyroPitchZero;
/**@}*/
#ifdef WIICAMERA #ifdef WIICAMERA
/* These are functions for the IR camera */ /** @name Wiimote IR camera functions
void IRinitialize(); // Initialises the camera as per the steps from http://wiibrew.org/wiki/Wiimote#IR_Camera * You will have to uncomment #WIICAMERA in Wii.h to use the IR camera.
*/
/** Initialises the camera as per the steps from: http://wiibrew.org/wiki/Wiimote#IR_Camera */
void IRinitialize();
uint16_t getIRx1() { return IR_object_x1; }; // IR object 1 x position (0-1023) /** IR object 1 x position (0-1023). */
uint16_t getIRy1() { return IR_object_y1; }; // IR object 1 y position (0-767) uint16_t getIRx1() { return IR_object_x1; };
uint8_t getIRs1() { return IR_object_s1; }; // IR object 1 size (0-15) /** IR object 1 y position (0-767). */
uint16_t getIRy1() { return IR_object_y1; };
/** IR object 1 size (0-15). */
uint8_t getIRs1() { return IR_object_s1; };
/** IR object 2 x position (0-1023). */
uint16_t getIRx2() { return IR_object_x2; }; uint16_t getIRx2() { return IR_object_x2; };
/** IR object 2 y position (0-767). */
uint16_t getIRy2() { return IR_object_y2; }; uint16_t getIRy2() { return IR_object_y2; };
/** IR object 2 size (0-15). */
uint8_t getIRs2() { return IR_object_s2; }; uint8_t getIRs2() { return IR_object_s2; };
/** IR object 3 x position (0-1023). */
uint16_t getIRx3() { return IR_object_x3; }; uint16_t getIRx3() { return IR_object_x3; };
/** IR object 3 y position (0-767). */
uint16_t getIRy3() { return IR_object_y3; }; uint16_t getIRy3() { return IR_object_y3; };
/** IR object 3 size (0-15). */
uint8_t getIRs3() { return IR_object_s3; }; uint8_t getIRs3() { return IR_object_s3; };
/** IR object 4 x position (0-1023). */
uint16_t getIRx4() { return IR_object_x4; }; uint16_t getIRx4() { return IR_object_x4; };
/** IR object 4 y position (0-767). */
uint16_t getIRy4() { return IR_object_y4; }; uint16_t getIRy4() { return IR_object_y4; };
/** IR object 4 size (0-15). */
uint8_t getIRs4() { return IR_object_s4; }; uint8_t getIRs4() { return IR_object_s4; };
/**
* Use this to check if the camera is enabled or not.
* If not call WII#IRinitialize to initialize the IR camera.
* @return True if it's enabled, false if not.
*/
bool isIRCameraEnabled() { return (wiiState & 0x08); }; bool isIRCameraEnabled() { return (wiiState & 0x08); };
/**@}*/
#endif #endif
private: private:

View file

@ -55,6 +55,7 @@
#define XBOX_MAX_ENDPOINTS 9 #define XBOX_MAX_ENDPOINTS 9
/** Enum used to set special LED modes supported by the Xbox controller. */
enum LEDMode { enum LEDMode {
ROTATING = 0x0A, ROTATING = 0x0A,
FASTBLINK = 0x0B, FASTBLINK = 0x0B,
@ -62,48 +63,147 @@ enum LEDMode {
ALTERNATING = 0x0D, ALTERNATING = 0x0D,
}; };
/**
* This class implements support for a Xbox Wirless receiver.
*
* Up to four controllers can connect to one receiver, if more is needed one can use a second receiver via the USBHub class.
*/
class XBOXRECV : public USBDeviceConfig { class XBOXRECV : public USBDeviceConfig {
public: public:
/**
* Constructor for the XBOXRECV class.
* @param pUsb Pointer to USB class instance.
*/
XBOXRECV(USB *pUsb); XBOXRECV(USB *pUsb);
// USBDeviceConfig implementation /** @name USBDeviceConfig implementation */
/**
* Initialize the Xbox Controller.
* @param parent Hub number.
* @param port Port number on the hub.
* @param lowspeed Speed of the device.
* @return 0 on success.
*/
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed); virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
/**
* Release the USB device.
* @return 0 on success.
*/
virtual uint8_t Release(); virtual uint8_t Release();
/**
* Poll the USB Input endpoins and run the state machines.
* @return 0 on success.
*/
virtual uint8_t Poll(); virtual uint8_t Poll();
/**
* Get the device address.
* @return The device address.
*/
virtual uint8_t GetAddress() { return bAddress; }; virtual uint8_t GetAddress() { return bAddress; };
/**
* Used to check if the controller has been initialized.
* @return True if it's ready.
*/
virtual bool isReady() { return bPollEnable; }; virtual bool isReady() { return bPollEnable; };
/**@}*/
/* /** @name Xbox Controller functions */
Xbox Controller Readings. /**
getButtonPress will return true as long as the button is held down * getButtonPress(uint8_t controller, Button b) will return true as long as the button is held down
While getButtonClick will only return it once * While getButtonClick(uint8_t controller, Button b) will only return it once
So for instance if you need to increase a variable once you would use getButtonClick, * So you instance if you need to increase a variable once you would use getButtonClick(uint8_t controller, Button b),
but if you need to drive a robot forward you would use getButtonPress * but if you need to drive a robot forward you would use getButtonPress(uint8_t controller, Button b).
* @param controller The controller to read from.
* @param b ::Button to read.
* @return getButtonClick(uint8_t controller, Button b) will return a bool, but getButtonPress(uint8_t controller, Button b)
* will return a byte if reading ::L2 or ::R2.
*/ */
uint8_t getButtonPress(uint8_t controller, Button b); uint8_t getButtonPress(uint8_t controller, Button b);
bool getButtonClick(uint8_t controller, Button b); bool getButtonClick(uint8_t controller, Button b);
/**@}*/
/** @name Xbox Controller functions */
/**
* Return the analog value from the joysticks on the controller.
* @param controller The controller to read from.
* @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
* @return Returns a signed 16-bit integer.
*/
int16_t getAnalogHat(uint8_t controller, AnalogHat a); int16_t getAnalogHat(uint8_t controller, AnalogHat a);
/**
/* Xbox Controller Command */ * Turn rumble off and all the LEDs on the specific controller.
* @param controller The controller to write to.
*/
void setAllOff(uint8_t controller) { setRumbleOn(controller,0,0); setLedOff(controller); }; void setAllOff(uint8_t controller) { setRumbleOn(controller,0,0); setLedOff(controller); };
/**
* Turn rumble off the specific controller.
* @param controller The controller to write to.
*/
void setRumbleOff(uint8_t controller) { setRumbleOn(controller,0,0); }; void setRumbleOff(uint8_t controller) { setRumbleOn(controller,0,0); };
/**
* Turn rumble on.
* @param controller The controller to write to.
* @param lValue Left motor (big weight) inside the controller.
* @param rValue Right motor (small weight) inside the controller.
*/
void setRumbleOn(uint8_t controller, uint8_t lValue, uint8_t rValue); void setRumbleOn(uint8_t controller, uint8_t lValue, uint8_t rValue);
/**
* Set LED value. Without using the ::LED or ::LEDMode enum.
* @param controller The controller to write to.
* @param value See:
* setLedOff(uint8_t controller), setLedOn(uint8_t controller, LED l),
* setLedBlink(uint8_t controller, LED l), and setLedMode(uint8_t controller, LEDMode lm).
*/
void setLedRaw(uint8_t controller, uint8_t value); void setLedRaw(uint8_t controller, uint8_t value);
/**
* Turn all LEDs off the specific controller.
* @param controller The controller to write to.
*/
void setLedOff(uint8_t controller) { setLedRaw(controller,0); }; void setLedOff(uint8_t controller) { setLedRaw(controller,0); };
/**
* Turn on a LED by using the ::LED enum.
* @param controller The controller to write to.
* @param l ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
*/
void setLedOn(uint8_t controller, LED l); void setLedOn(uint8_t controller, LED l);
/**
* Turn on a LED by using the ::LED enum.
* @param controller The controller to write to.
* @param l ::ALL, ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
*/
void setLedBlink(uint8_t controller, LED l); void setLedBlink(uint8_t controller, LED l);
/**
* Used to set special LED modes supported by the Xbox controller.
* @param controller The controller to write to.
* @param lm See ::LEDMode.
*/
void setLedMode(uint8_t controller, LEDMode lm); void setLedMode(uint8_t controller, LEDMode lm);
uint8_t getBatteryLevel(uint8_t controller); // Returns the battery level in percentage in 33% steps /**
* Used to get the battery level from the controller.
* @param controller The controller to read from.
* @return Returns the battery level in percentage in 33% steps.
*/
uint8_t getBatteryLevel(uint8_t controller);
/**
* Used to check if a button has changed.
* @param controller The controller to read from.
* @return True if a button has changed.
*/
bool buttonChanged(uint8_t controller); bool buttonChanged(uint8_t controller);
/**@}*/
bool XboxReceiverConnected; // True if a wireless receiver is connected /** True if a wireless receiver is connected. */
uint8_t Xbox360Connected[4]; // Variable used to indicate if the XBOX 360 controller is successfully connected bool XboxReceiverConnected;
/** Variable used to indicate if the XBOX 360 controller is successfully connected. */
uint8_t Xbox360Connected[4];
protected: protected:
/* Mandatory members */ /** Pointer to USB class instance. */
USB *pUsb; USB *pUsb;
uint8_t bAddress; // device address /** Device address. */
EpInfo epInfo[XBOX_MAX_ENDPOINTS]; //endpoint info structure uint8_t bAddress;
/** Endpoint info structure. */
EpInfo epInfo[XBOX_MAX_ENDPOINTS];
private: private:
bool bPollEnable; bool bPollEnable;

View file

@ -23,8 +23,8 @@
This is necessary so all the different libraries can be used at once This is necessary so all the different libraries can be used at once
*/ */
/** Enum used to turn on the LEDs on the different controllers. */
enum LED { enum LED {
/* Enum used to turn on the LEDs on the different controllers */
LED1 = 0, LED1 = 0,
LED2 = 1, LED2 = 1,
LED3 = 2, LED3 = 2,
@ -36,15 +36,21 @@ enum LED {
LED8 = 7, LED8 = 7,
LED9 = 8, LED9 = 8,
LED10 = 9, LED10 = 9,
ALL = 4, // Used to blink all LEDs on the Xbox controller /** Used to blink all LEDs on the Xbox controller */
ALL = 4,
}; };
/** This enum is used to read all the different buttons on the different controllers */
enum Button { enum Button {
/**@{*/
/** These buttons are available on all the the controllers */
UP = 0, UP = 0,
RIGHT = 1, RIGHT = 1,
DOWN = 2, DOWN = 2,
LEFT = 3, LEFT = 3,
/**@}*/
/* Wii buttons */ /**@{*/
/** Wii buttons */
PLUS = 5, PLUS = 5,
TWO = 6, TWO = 6,
ONE = 7, ONE = 7,
@ -54,13 +60,18 @@ enum Button {
C = 11, C = 11,
B = 12, B = 12,
A = 13, A = 13,
/* These are only available on the Wii U Pro Controller */ /**@}*/
/**@{*/
/** These are only available on the Wii U Pro Controller */
L = 16, L = 16,
R = 17, R = 17,
ZL = 18, ZL = 18,
ZR = 19, ZR = 19,
/**@}*/
/* PS3 controllers buttons */ /**@{*/
/** PS3 controllers buttons */
SELECT = 4, SELECT = 4,
START = 5, START = 5,
L3 = 6, L3 = 6,
@ -77,21 +88,28 @@ enum Button {
PS = 16, PS = 16,
MOVE = 17, // covers 12 bits - we only need to read the top 8 MOVE = 17, // Covers 12 bits - we only need to read the top 8
T = 18, // covers 12 bits - we only need to read the top 8 T = 18, // Covers 12 bits - we only need to read the top 8
/**@}*/
/* Xbox buttons */ /**@{*/
/** Xbox buttons */
BACK = 4, BACK = 4,
X = 14, X = 14,
Y = 15, Y = 15,
XBOX = 16, XBOX = 16,
SYNC = 17, SYNC = 17,
/**@}*/
}; };
/** Joysticks on the PS3 and Xbox controllers. */
enum AnalogHat { enum AnalogHat {
/* Joysticks on the PS3 and Xbox controllers */ /** Left joystick x-axis */
LeftHatX = 0, LeftHatX = 0,
/** Left joystick y-axis */
LeftHatY = 1, LeftHatY = 1,
/** Right joystick x-axis */
RightHatX = 2, RightHatX = 2,
/** Right joystick y-axis */
RightHatY = 3, RightHatY = 3,
}; };