2012-08-21 14:31:11 +02:00
/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
2013-03-28 09:46:43 +01:00
2012-08-21 14:31:11 +02:00
This software may be distributed and modified under the terms of the GNU
General Public License version 2 ( GPL2 ) as published by the Free Software
Foundation and appearing in the file GPL2 . TXT included in the packaging of
this file . Please note that GPL2 Section 2 [ b ] requires that all works based
on this software must also be made publicly available under the terms of
the GPL2 ( " Copyleft " ) .
2013-03-28 09:46:43 +01:00
2012-08-21 14:31:11 +02:00
Contact information
- - - - - - - - - - - - - - - - - - -
2013-03-28 09:46:43 +01:00
2012-08-21 14:31:11 +02:00
Kristian Lauszus , TKJ Electronics
Web : http : //www.tkjelectronics.com
e - mail : kristianl @ tkjelectronics . com
2013-01-17 00:07:56 +01:00
2013-07-18 19:43:21 +02:00
IR camera support added by Allan Glover ( adglover9 .81 @ gmail . com ) and Kristian Lauszus
2012-08-21 14:31:11 +02:00
*/
# ifndef _wii_h_
# define _wii_h_
# include "BTD.h"
2013-01-27 21:25:50 +01:00
# include "controllerEnums.h"
2012-08-21 14:31:11 +02:00
2012-08-23 23:10:12 +02:00
/* Wii event flags */
2015-04-20 23:39:57 +02:00
# define WII_FLAG_MOTION_PLUS_CONNECTED (1 << 0)
# define WII_FLAG_NUNCHUCK_CONNECTED (1 << 1)
# define WII_FLAG_CALIBRATE_BALANCE_BOARD (1 << 2)
2012-08-23 23:10:12 +02:00
2013-12-13 11:27:05 +01:00
# define wii_check_flag(flag) (wii_event_flag & (flag))
# define wii_set_flag(flag) (wii_event_flag |= (flag))
# define wii_clear_flag(flag) (wii_event_flag &= ~(flag))
2012-08-23 23:10:12 +02:00
2013-02-05 19:51:45 +01:00
/** Enum used to read the joystick on the Nunchuck. */
2014-01-04 13:43:49 +01:00
enum HatEnum {
2013-03-28 09:46:43 +01:00
/** Read the x-axis on the Nunchuck joystick. */
HatX = 0 ,
/** Read the y-axis on the Nunchuck joystick. */
HatY = 1 ,
2012-08-21 14:31:11 +02:00
} ;
2015-04-16 16:55:35 +02:00
/** Enum used to read the weight on Wii Balance Board. */
enum BalanceBoardEnum {
TopRight = 0 ,
BotRight = 1 ,
TopLeft = 2 ,
BotLeft = 3 ,
} ;
2013-02-05 19:51:45 +01:00
/**
* This BluetoothService class implements support for the Wiimote including the Nunchuck and Motion Plus extension .
*
* It also support the Wii U Pro Controller .
*/
2012-08-21 14:31:11 +02:00
class WII : public BluetoothService {
public :
2013-03-28 09:46:43 +01:00
/**
* Constructor for the WII class .
* @ param p Pointer to BTD class instance .
* @ param pair Set this to true in order 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 ) ;
/** @name BluetoothService implementation */
/** Used this to disconnect any of the controllers. */
2014-11-10 07:35:13 +01:00
void disconnect ( ) ;
2013-03-28 09:46:43 +01:00
/**@}*/
/** @name Wii Controller functions */
/**
* 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 ) .
2014-01-04 13:43:49 +01:00
* @ param b : : ButtonEnum to read .
* @ return getButtonPress ( ButtonEnum b ) will return a true as long as a button is held down , while getButtonClick ( ButtonEnum b ) will return true once for each button press .
2013-03-28 09:46:43 +01:00
*/
2014-01-04 13:43:49 +01:00
bool getButtonPress ( ButtonEnum b ) ;
bool getButtonClick ( ButtonEnum b ) ;
2013-03-28 09:46:43 +01:00
/**@}*/
/** @name Wii Controller functions */
2013-12-25 11:09:57 +01:00
2016-04-19 11:48:51 +02:00
/** Call this to start the pairing sequence with a controller */
2013-05-06 23:32:00 +02:00
void pair ( void ) {
if ( pBtd )
pBtd - > pairWithWiimote ( ) ;
2013-12-30 16:05:50 +01:00
} ;
2013-03-28 09:46:43 +01:00
/**
* 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.
*/
2014-01-04 13:43:49 +01:00
uint8_t getAnalogHat ( HatEnum a ) ;
2013-03-28 09:46:43 +01:00
/**
* 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.
*/
2014-01-04 13:43:49 +01:00
uint16_t getAnalogHat ( AnalogHatEnum a ) ;
2013-03-28 09:46:43 +01:00
/**
* Pitch calculated from the Wiimote . A complimentary filter is used if the Motion Plus is connected .
* @ return Pitch in the range from 0 - 360.
*/
2015-10-12 13:20:48 +02:00
float getPitch ( ) {
2013-12-25 11:09:57 +01:00
if ( motionPlusConnected )
2013-10-21 18:41:47 +02:00
return compPitch ;
return getWiimotePitch ( ) ;
2013-03-28 09:46:43 +01:00
} ;
/**
* Roll calculated from the Wiimote . A complimentary filter is used if the Motion Plus is connected .
* @ return Roll in the range from 0 - 360.
*/
2015-10-12 13:20:48 +02:00
float getRoll ( ) {
2013-12-25 11:09:57 +01:00
if ( motionPlusConnected )
2013-10-21 18:41:47 +02:00
return compRoll ;
return getWiimoteRoll ( ) ;
2013-03-28 09:46:43 +01:00
} ;
/**
* 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 .
*/
2015-10-12 13:20:48 +02:00
float getYaw ( ) {
2013-03-28 09:46:43 +01:00
return gyroYaw ;
} ;
/** Used to set all LEDs and rumble off. */
void setAllOff ( ) ;
/** Turn off rumble. */
void setRumbleOff ( ) ;
/** Turn on rumble. */
void setRumbleOn ( ) ;
/** Toggle rumble. */
void setRumbleToggle ( ) ;
2013-04-01 15:38:15 +02:00
/**
2014-01-04 13:43:49 +01:00
* Set LED value without using the : : LEDEnum .
* @ param value See : : : LEDEnum .
2013-04-01 15:38:15 +02:00
*/
void setLedRaw ( uint8_t value ) ;
2013-12-25 11:09:57 +01:00
2013-11-15 23:19:10 +01:00
/** Turn all LEDs off. */
void setLedOff ( ) {
setLedRaw ( 0 ) ;
2013-12-30 16:05:50 +01:00
} ;
2013-03-28 09:46:43 +01:00
/**
2014-01-04 13:43:49 +01:00
* Turn the specific : : LEDEnum off .
* @ param a The : : LEDEnum to turn off .
2013-03-28 09:46:43 +01:00
*/
2014-01-04 13:43:49 +01:00
void setLedOff ( LEDEnum a ) ;
2013-03-28 09:46:43 +01:00
/**
2014-01-04 13:43:49 +01:00
* Turn the specific : : LEDEnum on .
* @ param a The : : LEDEnum to turn on .
2013-03-28 09:46:43 +01:00
*/
2014-01-04 13:43:49 +01:00
void setLedOn ( LEDEnum a ) ;
2013-03-28 09:46:43 +01:00
/**
2014-01-04 13:43:49 +01:00
* Toggle the specific : : LEDEnum .
* @ param a The : : LEDEnum to toggle .
2013-03-28 09:46:43 +01:00
*/
2014-01-04 13:43:49 +01:00
void setLedToggle ( LEDEnum a ) ;
2013-03-28 09:46:43 +01:00
/**
* This will set the LEDs , so the user can see which connections are active .
*
2014-01-04 13:43:49 +01:00
* The first : : LEDEnum indicate that the Wiimote is connected ,
* the second : : LEDEnum indicate indicate that a Motion Plus is also connected
* the third : : LEDEnum will indicate that a Nunchuck controller is also connected .
2013-03-28 09:46:43 +01:00
*/
void setLedStatus ( ) ;
/**
* Return the battery level of the Wiimote .
* @ return The battery level in the range 0 - 255.
*/
2013-07-18 19:43:21 +02:00
uint8_t getBatteryLevel ( ) ;
2013-12-25 11:09:57 +01:00
2013-03-28 09:46:43 +01:00
/**
* Return the Wiimote state .
* @ return See : http : //wiibrew.org/wiki/Wiimote#0x20:_Status.
*/
uint8_t getWiiState ( ) {
return wiiState ;
} ;
/**@}*/
/**@{*/
/** Variable used to indicate if a Wiimote is connected. */
bool wiimoteConnected ;
/** 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 ;
2015-04-16 01:57:00 +02:00
/** Variable used to indicate if a Wii Balance Board is connected. */
bool wiiBalanceBoardConnected ;
2013-03-28 09:46:43 +01:00
/**@}*/
/* IMU Data, might be usefull if you need to do something more advanced than just calculating the angle */
/**@{*/
2013-12-25 11:09:57 +01:00
2013-03-28 09:46:43 +01:00
/** Pitch and roll calculated from the accelerometer inside the Wiimote. */
2015-10-12 13:20:48 +02:00
float getWiimotePitch ( ) {
return ( atan2f ( accYwiimote , accZwiimote ) + PI ) * RAD_TO_DEG ;
2013-10-21 18:41:47 +02:00
} ;
2013-12-25 11:09:57 +01:00
2015-10-12 13:20:48 +02:00
float getWiimoteRoll ( ) {
return ( atan2f ( accXwiimote , accZwiimote ) + PI ) * RAD_TO_DEG ;
2013-10-21 18:41:47 +02:00
} ;
2013-03-28 09:46:43 +01:00
/**@}*/
/**@{*/
2013-12-25 11:09:57 +01:00
2013-03-28 09:46:43 +01:00
/** Pitch and roll calculated from the accelerometer inside the Nunchuck. */
2015-10-12 13:20:48 +02:00
float getNunchuckPitch ( ) {
return ( atan2f ( accYnunchuck , accZnunchuck ) + PI ) * RAD_TO_DEG ;
2013-10-21 18:41:47 +02:00
} ;
2013-12-25 11:09:57 +01:00
2015-10-12 13:20:48 +02:00
float getNunchuckRoll ( ) {
return ( atan2f ( accXnunchuck , accZnunchuck ) + PI ) * RAD_TO_DEG ;
2013-10-21 18:41:47 +02:00
} ;
2013-03-28 09:46:43 +01:00
/**@}*/
/**@{*/
/** Accelerometer values used to calculate pitch and roll. */
2013-10-21 18:41:47 +02:00
int16_t accXwiimote , accYwiimote , accZwiimote ;
int16_t accXnunchuck , accYnunchuck , accZnunchuck ;
2013-03-28 09:46:43 +01:00
/**@}*/
/* Variables for the gyro inside the Motion Plus */
/** This is the pitch calculated by the gyro - use this to tune WII#pitchGyroScale. */
2015-10-12 13:20:48 +02:00
float gyroPitch ;
2013-03-28 09:46:43 +01:00
/** This is the roll calculated by the gyro - use this to tune WII#rollGyroScale. */
2015-10-12 13:20:48 +02:00
float gyroRoll ;
2013-03-28 09:46:43 +01:00
/** This is the yaw calculated by the gyro - use this to tune WII#yawGyroScale. */
2015-10-12 13:20:48 +02:00
float gyroYaw ;
2013-03-28 09:46:43 +01:00
/**@{*/
/** The speed in deg/s from the gyro. */
2015-10-12 13:20:48 +02:00
float pitchGyroSpeed ;
float rollGyroSpeed ;
float yawGyroSpeed ;
2013-03-28 09:46:43 +01:00
/**@}*/
/**@{*/
/** You might need to fine-tune these values. */
uint16_t pitchGyroScale ;
uint16_t rollGyroScale ;
uint16_t yawGyroScale ;
/**@}*/
/**@{*/
/** Raw value read directly from the Motion Plus. */
int16_t gyroYawRaw ;
int16_t gyroRollRaw ;
int16_t gyroPitchRaw ;
/**@}*/
/**@{*/
/** These values are set when the controller is first initialized. */
int16_t gyroYawZero ;
int16_t gyroRollZero ;
int16_t gyroPitchZero ;
/**@}*/
2013-01-17 00:07:56 +01:00
2015-04-16 16:55:35 +02:00
/** @name Wii Balance Board functions */
/**
* Used to get the weight at the specific position on the Wii Balance Board .
2016-04-19 18:10:01 +02:00
* @ param pos : : BalanceBoardEnum to read from .
* @ return Returns the weight in kg .
2015-04-16 16:55:35 +02:00
*/
2015-04-16 17:00:07 +02:00
float getWeight ( BalanceBoardEnum pos ) ;
2015-04-16 16:55:35 +02:00
/**
* Used to get total weight on the Wii Balance Board .
2016-04-19 18:10:01 +02:00
* @ return Returns the weight in kg .
2015-04-16 16:55:35 +02:00
*/
2015-04-16 17:00:07 +02:00
float getTotalWeight ( ) ;
2015-04-16 16:55:35 +02:00
/**
* Used to get the raw reading at the specific position on the Wii Balance Board .
2016-04-19 18:10:01 +02:00
* @ param pos : : BalanceBoardEnum to read from .
* @ return Returns the raw reading .
2015-04-16 16:55:35 +02:00
*/
uint16_t getWeightRaw ( BalanceBoardEnum pos ) {
2015-04-16 19:45:03 +02:00
return wiiBalanceBoardRaw [ pos ] ;
2015-04-16 16:55:35 +02:00
} ;
2015-04-16 02:26:18 +02:00
/**@}*/
2013-01-17 00:07:56 +01:00
# ifdef WIICAMERA
2013-03-28 09:46:43 +01:00
/** @name Wiimote IR camera functions
2014-01-19 17:14:09 +01:00
* You will have to set : : ENABLE_WII_IR_CAMERA in settings . h to 1 in order use the IR camera .
2013-03-28 09:46:43 +01:00
*/
/** Initialises the camera as per the steps from: http://wiibrew.org/wiki/Wiimote#IR_Camera */
void IRinitialize ( ) ;
/**
* IR object 1 x - position read from the Wii IR camera .
* @ return The x - position of the object in the range 0 - 1023.
*/
uint16_t getIRx1 ( ) {
return IR_object_x1 ;
} ;
/**
* IR object 1 y - position read from the Wii IR camera .
* @ return The y - position of the object in the range 0 - 767.
*/
uint16_t getIRy1 ( ) {
return IR_object_y1 ;
} ;
/**
* IR object 1 size read from the Wii IR camera .
* @ return The size of the object in the range 0 - 15.
*/
uint8_t getIRs1 ( ) {
return IR_object_s1 ;
} ;
/**
* IR object 2 x - position read from the Wii IR camera .
* @ return The x - position of the object in the range 0 - 1023.
*/
uint16_t getIRx2 ( ) {
return IR_object_x2 ;
} ;
/**
* IR object 2 y - position read from the Wii IR camera .
* @ return The y - position of the object in the range 0 - 767.
*/
uint16_t getIRy2 ( ) {
return IR_object_y2 ;
} ;
/**
* IR object 2 size read from the Wii IR camera .
* @ return The size of the object in the range 0 - 15.
*/
uint8_t getIRs2 ( ) {
return IR_object_s2 ;
} ;
/**
* IR object 3 x - position read from the Wii IR camera .
* @ return The x - position of the object in the range 0 - 1023.
*/
uint16_t getIRx3 ( ) {
return IR_object_x3 ;
} ;
/**
* IR object 3 y - position read from the Wii IR camera .
* @ return The y - position of the object in the range 0 - 767.
*/
uint16_t getIRy3 ( ) {
return IR_object_y3 ;
} ;
/**
* IR object 3 size read from the Wii IR camera .
* @ return The size of the object in the range 0 - 15.
*/
uint8_t getIRs3 ( ) {
return IR_object_s3 ;
} ;
/**
* IR object 4 x - position read from the Wii IR camera .
* @ return The x - position of the object in the range 0 - 1023.
*/
uint16_t getIRx4 ( ) {
return IR_object_x4 ;
} ;
/**
* IR object 4 y - position read from the Wii IR camera .
* @ return The y - position of the object in the range 0 - 767.
*/
uint16_t getIRy4 ( ) {
return IR_object_y4 ;
} ;
/**
* IR object 4 size read from the Wii IR camera .
* @ return The size of the object in the range 0 - 15.
*/
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 ( ) {
2013-12-25 11:09:57 +01:00
return ( wiiState & 0x08 ) ;
2013-03-28 09:46:43 +01:00
} ;
/**@}*/
2013-01-17 00:07:56 +01:00
# endif
2013-03-28 09:46:43 +01:00
2014-09-02 11:02:17 +02:00
protected :
/** @name BluetoothService implementation */
/**
* Used to pass acldata to the services .
* @ param ACLData Incoming acldata .
*/
2015-02-24 01:28:28 +01:00
void ACLData ( uint8_t * ACLData ) ;
2014-09-02 11:02:17 +02:00
/** Used to run part of the state machine. */
2015-02-24 01:28:28 +01:00
void Run ( ) ;
2014-09-02 11:02:17 +02:00
/** Use this to reset the service. */
2015-02-24 01:28:28 +01:00
void Reset ( ) ;
2013-07-14 00:43:35 +02:00
/**
* Called when the controller is successfully initialized .
* Use attachOnInit ( void ( * funcOnInit ) ( void ) ) to call your own function .
* This is useful for instance if you want to set the LEDs in a specific way .
*/
void onInit ( ) ;
2014-09-02 11:02:17 +02:00
/**@}*/
private :
2021-03-25 21:18:36 +01:00
static int8_t getButtonIndex ( ButtonEnum b ) ;
static int8_t getButtonIndexPro ( ButtonEnum b ) ;
2013-03-28 09:46:43 +01:00
void L2CAP_task ( ) ; // L2CAP state machine
/* Variables filled from HCI event management */
bool activeConnection ; // Used to indicate if it's already has established a connection
2013-07-14 00:43:35 +02:00
/* Variables used by high level L2CAP task */
2013-03-28 09:46:43 +01:00
uint8_t l2cap_state ;
2013-12-11 09:29:38 +01:00
uint8_t wii_event_flag ; // Used for Wii flags
2013-03-28 09:46:43 +01:00
uint32_t ButtonState ;
uint32_t OldButtonState ;
uint32_t ButtonClickState ;
uint16_t hatValues [ 4 ] ;
uint8_t HIDBuffer [ 3 ] ; // Used to store HID commands
uint16_t stateCounter ;
bool unknownExtensionConnected ;
bool extensionConnected ;
2015-04-16 16:50:08 +02:00
bool checkBatteryLevel ; // Set to true when getBatteryLevel() is called otherwise if should be false
2013-07-18 19:43:21 +02:00
bool motionPlusInside ; // True if it's a new Wiimote with the Motion Plus extension build into it
2013-03-28 09:46:43 +01:00
/* L2CAP Channels */
uint8_t control_scid [ 2 ] ; // L2CAP source CID for HID_Control
uint8_t control_dcid [ 2 ] ; // 0x0060
uint8_t interrupt_scid [ 2 ] ; // L2CAP source CID for HID_Interrupt
uint8_t interrupt_dcid [ 2 ] ; // 0x0061
/* HID Commands */
void HID_Command ( uint8_t * data , uint8_t nbytes ) ;
void setReportMode ( bool continuous , uint8_t mode ) ;
void writeData ( uint32_t offset , uint8_t size , uint8_t * data ) ;
void initExtension1 ( ) ;
void initExtension2 ( ) ;
2013-07-18 19:43:21 +02:00
void statusRequest ( ) ; // Used to update the Wiimote state and battery level
2013-03-28 09:46:43 +01:00
void readData ( uint32_t offset , uint16_t size , bool EEPROM ) ;
void readExtensionType ( ) ;
void readCalData ( ) ;
2015-04-16 20:19:33 +02:00
void readWiiBalanceBoardCalibration ( ) ; // Used by the library to read the Wii Balance Board calibration values
2013-03-28 09:46:43 +01:00
void checkMotionPresent ( ) ; // Used to see if a Motion Plus is connected to the Wiimote
void initMotionPlus ( ) ;
void activateMotionPlus ( ) ;
2015-04-16 16:55:35 +02:00
2015-04-16 19:45:03 +02:00
uint16_t wiiBalanceBoardRaw [ 4 ] ; // Wii Balance Board raw values
uint16_t wiiBalanceBoardCal [ 3 ] [ 4 ] ; // Wii Balance Board calibration values
2013-03-28 09:46:43 +01:00
2015-10-12 13:20:48 +02:00
float compPitch ; // Fusioned angle using a complimentary filter if the Motion Plus is connected
float compRoll ; // Fusioned angle using a complimentary filter if the Motion Plus is connected
2013-03-28 09:46:43 +01:00
bool activateNunchuck ;
bool motionValuesReset ; // This bool is true when the gyro values has been reset
2014-09-02 11:02:17 +02:00
uint32_t timer ;
2013-03-28 09:46:43 +01:00
uint8_t wiiState ; // Stores the value in l2capinbuf[12] - (0x01: Battery is nearly empty), (0x02: An Extension Controller is connected), (0x04: Speaker enabled), (0x08: IR enabled), (0x10: LED1, 0x20: LED2, 0x40: LED3, 0x80: LED4)
uint8_t batteryLevel ;
2013-01-17 00:47:19 +01:00
# ifdef WIICAMERA
2013-07-18 19:43:21 +02:00
/* Private function and variables for the readings from the IR Camera */
2013-03-28 09:46:43 +01:00
void enableIRCamera1 ( ) ; // Sets bit 2 of output report 13
void enableIRCamera2 ( ) ; // Sets bit 2 of output report 1A
void writeSensitivityBlock1 ( ) ;
void writeSensitivityBlock2 ( ) ;
void write0x08Value ( ) ;
void setWiiModeNumber ( uint8_t mode_number ) ;
uint16_t IR_object_x1 ; // IR x position 10 bits
uint16_t IR_object_y1 ; // IR y position 10 bits
uint8_t IR_object_s1 ; // IR size value
uint16_t IR_object_x2 ;
uint16_t IR_object_y2 ;
uint8_t IR_object_s2 ;
uint16_t IR_object_x3 ; // IR x position 10 bits
uint16_t IR_object_y3 ; // IR y position 10 bits
uint8_t IR_object_s3 ; // IR size value
uint16_t IR_object_x4 ;
uint16_t IR_object_y4 ;
uint8_t IR_object_s4 ;
2013-01-17 00:47:19 +01:00
# endif
2012-08-21 14:31:11 +02:00
} ;
2013-12-25 11:09:57 +01:00
# endif