Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Wii.h
00001 /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved. 00002 00003 This software may be distributed and modified under the terms of the GNU 00004 General Public License version 2 (GPL2) as published by the Free Software 00005 Foundation and appearing in the file GPL2.TXT included in the packaging of 00006 this file. Please note that GPL2 Section 2[b] requires that all works based 00007 on this software must also be made publicly available under the terms of 00008 the GPL2 ("Copyleft"). 00009 00010 Contact information 00011 ------------------- 00012 00013 Kristian Lauszus, TKJ Electronics 00014 Web : http://www.tkjelectronics.com 00015 e-mail : kristianl@tkjelectronics.com 00016 00017 IR camera support added by Allan Glover (adglover9.81@gmail.com) and Kristian Lauszus 00018 */ 00019 00020 #ifndef _wii_h_ 00021 #define _wii_h_ 00022 00023 #include "BTD.h" 00024 #include "controllerEnums.h" 00025 00026 /* Wii event flags */ 00027 #define WII_FLAG_MOTION_PLUS_CONNECTED (1 << 0) 00028 #define WII_FLAG_NUNCHUCK_CONNECTED (1 << 1) 00029 #define WII_FLAG_CALIBRATE_BALANCE_BOARD (1 << 2) 00030 00031 #define wii_check_flag(flag) (wii_event_flag & (flag)) 00032 #define wii_set_flag(flag) (wii_event_flag |= (flag)) 00033 #define wii_clear_flag(flag) (wii_event_flag &= ~(flag)) 00034 00035 /** Enum used to read the joystick on the Nunchuck. */ 00036 enum HatEnum { 00037 /** Read the x-axis on the Nunchuck joystick. */ 00038 HatX = 0, 00039 /** Read the y-axis on the Nunchuck joystick. */ 00040 HatY = 1, 00041 }; 00042 00043 /** Enum used to read the weight on Wii Balance Board. */ 00044 enum BalanceBoardEnum { 00045 TopRight = 0, 00046 BotRight = 1, 00047 TopLeft = 2, 00048 BotLeft = 3, 00049 }; 00050 00051 /** 00052 * This BluetoothService class implements support for the Wiimote including the Nunchuck and Motion Plus extension. 00053 * 00054 * It also support the Wii U Pro Controller. 00055 */ 00056 class WII : public BluetoothService { 00057 public: 00058 /** 00059 * Constructor for the WII class. 00060 * @param p Pointer to BTD class instance. 00061 * @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. 00062 * One can use ::PAIR to set it to true. 00063 */ 00064 WII(BTD *p, bool pair = false); 00065 00066 /** @name BluetoothService implementation */ 00067 /** Used this to disconnect any of the controllers. */ 00068 void disconnect(); 00069 /**@}*/ 00070 00071 /** @name Wii Controller functions */ 00072 /** 00073 * getButtonPress(Button b) will return true as long as the button is held down. 00074 * 00075 * While getButtonClick(Button b) will only return it once. 00076 * 00077 * So you instance if you need to increase a variable once you would use getButtonClick(Button b), 00078 * but if you need to drive a robot forward you would use getButtonPress(Button b). 00079 * @param b ::ButtonEnum to read. 00080 * @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. 00081 */ 00082 bool getButtonPress(ButtonEnum b); 00083 bool getButtonClick(ButtonEnum b); 00084 /**@}*/ 00085 00086 /** @name Wii Controller functions */ 00087 00088 /** Call this to start the pairing sequence with a controller */ 00089 void pair(void) { 00090 if(pBtd) 00091 pBtd->pairWithWiimote(); 00092 }; 00093 /** 00094 * Used to read the joystick of the Nunchuck. 00095 * @param a Either ::HatX or ::HatY. 00096 * @return Return the analog value in the range from approximately 25-230. 00097 */ 00098 uint8_t getAnalogHat(HatEnum a); 00099 /** 00100 * Used to read the joystick of the Wii U Pro Controller. 00101 * @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY. 00102 * @return Return the analog value in the range from approximately 800-3200. 00103 */ 00104 uint16_t getAnalogHat(AnalogHatEnum a); 00105 00106 /** 00107 * Pitch calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected. 00108 * @return Pitch in the range from 0-360. 00109 */ 00110 float getPitch() { 00111 if(motionPlusConnected) 00112 return compPitch; 00113 return getWiimotePitch(); 00114 }; 00115 00116 /** 00117 * Roll calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected. 00118 * @return Roll in the range from 0-360. 00119 */ 00120 float getRoll() { 00121 if(motionPlusConnected) 00122 return compRoll; 00123 return getWiimoteRoll(); 00124 }; 00125 00126 /** 00127 * This is the yaw calculated by the gyro. 00128 * 00129 * <B>NOTE:</B> This angle will drift a lot and is only available if the Motion Plus extension is connected. 00130 * @return The angle calculated using the gyro. 00131 */ 00132 float getYaw() { 00133 return gyroYaw; 00134 }; 00135 00136 /** Used to set all LEDs and rumble off. */ 00137 void setAllOff(); 00138 /** Turn off rumble. */ 00139 void setRumbleOff(); 00140 /** Turn on rumble. */ 00141 void setRumbleOn(); 00142 /** Toggle rumble. */ 00143 void setRumbleToggle(); 00144 00145 /** 00146 * Set LED value without using the ::LEDEnum. 00147 * @param value See: ::LEDEnum. 00148 */ 00149 void setLedRaw(uint8_t value); 00150 00151 /** Turn all LEDs off. */ 00152 void setLedOff() { 00153 setLedRaw(0); 00154 }; 00155 /** 00156 * Turn the specific ::LEDEnum off. 00157 * @param a The ::LEDEnum to turn off. 00158 */ 00159 void setLedOff(LEDEnum a); 00160 /** 00161 * Turn the specific ::LEDEnum on. 00162 * @param a The ::LEDEnum to turn on. 00163 */ 00164 void setLedOn(LEDEnum a); 00165 /** 00166 * Toggle the specific ::LEDEnum. 00167 * @param a The ::LEDEnum to toggle. 00168 */ 00169 void setLedToggle(LEDEnum a); 00170 /** 00171 * This will set the LEDs, so the user can see which connections are active. 00172 * 00173 * The first ::LEDEnum indicate that the Wiimote is connected, 00174 * the second ::LEDEnum indicate indicate that a Motion Plus is also connected 00175 * the third ::LEDEnum will indicate that a Nunchuck controller is also connected. 00176 */ 00177 void setLedStatus(); 00178 00179 /** 00180 * Return the battery level of the Wiimote. 00181 * @return The battery level in the range 0-255. 00182 */ 00183 uint8_t getBatteryLevel(); 00184 00185 /** 00186 * Return the Wiimote state. 00187 * @return See: http://wiibrew.org/wiki/Wiimote#0x20:_Status. 00188 */ 00189 uint8_t getWiiState() { 00190 return wiiState; 00191 }; 00192 /**@}*/ 00193 00194 /**@{*/ 00195 /** Variable used to indicate if a Wiimote is connected. */ 00196 bool wiimoteConnected; 00197 /** Variable used to indicate if a Nunchuck controller is connected. */ 00198 bool nunchuckConnected; 00199 /** Variable used to indicate if a Nunchuck controller is connected. */ 00200 bool motionPlusConnected; 00201 /** Variable used to indicate if a Wii U Pro controller is connected. */ 00202 bool wiiUProControllerConnected; 00203 /** Variable used to indicate if a Wii Balance Board is connected. */ 00204 bool wiiBalanceBoardConnected; 00205 /**@}*/ 00206 00207 /* IMU Data, might be usefull if you need to do something more advanced than just calculating the angle */ 00208 00209 /**@{*/ 00210 00211 /** Pitch and roll calculated from the accelerometer inside the Wiimote. */ 00212 float getWiimotePitch() { 00213 return (atan2f(accYwiimote, accZwiimote) + PI) * RAD_TO_DEG; 00214 }; 00215 00216 float getWiimoteRoll() { 00217 return (atan2f(accXwiimote, accZwiimote) + PI) * RAD_TO_DEG; 00218 }; 00219 /**@}*/ 00220 00221 /**@{*/ 00222 00223 /** Pitch and roll calculated from the accelerometer inside the Nunchuck. */ 00224 float getNunchuckPitch() { 00225 return (atan2f(accYnunchuck, accZnunchuck) + PI) * RAD_TO_DEG; 00226 }; 00227 00228 float getNunchuckRoll() { 00229 return (atan2f(accXnunchuck, accZnunchuck) + PI) * RAD_TO_DEG; 00230 }; 00231 /**@}*/ 00232 00233 /**@{*/ 00234 /** Accelerometer values used to calculate pitch and roll. */ 00235 int16_t accXwiimote, accYwiimote, accZwiimote; 00236 int16_t accXnunchuck, accYnunchuck, accZnunchuck; 00237 /**@}*/ 00238 00239 /* Variables for the gyro inside the Motion Plus */ 00240 /** This is the pitch calculated by the gyro - use this to tune WII#pitchGyroScale. */ 00241 float gyroPitch; 00242 /** This is the roll calculated by the gyro - use this to tune WII#rollGyroScale. */ 00243 float gyroRoll; 00244 /** This is the yaw calculated by the gyro - use this to tune WII#yawGyroScale. */ 00245 float gyroYaw; 00246 00247 /**@{*/ 00248 /** The speed in deg/s from the gyro. */ 00249 float pitchGyroSpeed; 00250 float rollGyroSpeed; 00251 float yawGyroSpeed; 00252 /**@}*/ 00253 00254 /**@{*/ 00255 /** You might need to fine-tune these values. */ 00256 uint16_t pitchGyroScale; 00257 uint16_t rollGyroScale; 00258 uint16_t yawGyroScale; 00259 /**@}*/ 00260 00261 /**@{*/ 00262 /** Raw value read directly from the Motion Plus. */ 00263 int16_t gyroYawRaw; 00264 int16_t gyroRollRaw; 00265 int16_t gyroPitchRaw; 00266 /**@}*/ 00267 00268 /**@{*/ 00269 /** These values are set when the controller is first initialized. */ 00270 int16_t gyroYawZero; 00271 int16_t gyroRollZero; 00272 int16_t gyroPitchZero; 00273 /**@}*/ 00274 00275 /** @name Wii Balance Board functions */ 00276 00277 /** 00278 * Used to get the weight at the specific position on the Wii Balance Board. 00279 * @param pos ::BalanceBoardEnum to read from. 00280 * @return Returns the weight in kg. 00281 */ 00282 float getWeight(BalanceBoardEnum pos); 00283 00284 /** 00285 * Used to get total weight on the Wii Balance Board. 00286 * @return Returns the weight in kg. 00287 */ 00288 float getTotalWeight(); 00289 00290 /** 00291 * Used to get the raw reading at the specific position on the Wii Balance Board. 00292 * @param pos ::BalanceBoardEnum to read from. 00293 * @return Returns the raw reading. 00294 */ 00295 uint16_t getWeightRaw(BalanceBoardEnum pos) { 00296 return wiiBalanceBoardRaw[pos]; 00297 }; 00298 /**@}*/ 00299 00300 #ifdef WIICAMERA 00301 /** @name Wiimote IR camera functions 00302 * You will have to set ::ENABLE_WII_IR_CAMERA in settings.h to 1 in order use the IR camera. 00303 */ 00304 /** Initialises the camera as per the steps from: http://wiibrew.org/wiki/Wiimote#IR_Camera */ 00305 void IRinitialize(); 00306 00307 /** 00308 * IR object 1 x-position read from the Wii IR camera. 00309 * @return The x-position of the object in the range 0-1023. 00310 */ 00311 uint16_t getIRx1() { 00312 return IR_object_x1; 00313 }; 00314 00315 /** 00316 * IR object 1 y-position read from the Wii IR camera. 00317 * @return The y-position of the object in the range 0-767. 00318 */ 00319 uint16_t getIRy1() { 00320 return IR_object_y1; 00321 }; 00322 00323 /** 00324 * IR object 1 size read from the Wii IR camera. 00325 * @return The size of the object in the range 0-15. 00326 */ 00327 uint8_t getIRs1() { 00328 return IR_object_s1; 00329 }; 00330 00331 /** 00332 * IR object 2 x-position read from the Wii IR camera. 00333 * @return The x-position of the object in the range 0-1023. 00334 */ 00335 uint16_t getIRx2() { 00336 return IR_object_x2; 00337 }; 00338 00339 /** 00340 * IR object 2 y-position read from the Wii IR camera. 00341 * @return The y-position of the object in the range 0-767. 00342 */ 00343 uint16_t getIRy2() { 00344 return IR_object_y2; 00345 }; 00346 00347 /** 00348 * IR object 2 size read from the Wii IR camera. 00349 * @return The size of the object in the range 0-15. 00350 */ 00351 uint8_t getIRs2() { 00352 return IR_object_s2; 00353 }; 00354 00355 /** 00356 * IR object 3 x-position read from the Wii IR camera. 00357 * @return The x-position of the object in the range 0-1023. 00358 */ 00359 uint16_t getIRx3() { 00360 return IR_object_x3; 00361 }; 00362 00363 /** 00364 * IR object 3 y-position read from the Wii IR camera. 00365 * @return The y-position of the object in the range 0-767. 00366 */ 00367 uint16_t getIRy3() { 00368 return IR_object_y3; 00369 }; 00370 00371 /** 00372 * IR object 3 size read from the Wii IR camera. 00373 * @return The size of the object in the range 0-15. 00374 */ 00375 uint8_t getIRs3() { 00376 return IR_object_s3; 00377 }; 00378 00379 /** 00380 * IR object 4 x-position read from the Wii IR camera. 00381 * @return The x-position of the object in the range 0-1023. 00382 */ 00383 uint16_t getIRx4() { 00384 return IR_object_x4; 00385 }; 00386 00387 /** 00388 * IR object 4 y-position read from the Wii IR camera. 00389 * @return The y-position of the object in the range 0-767. 00390 */ 00391 uint16_t getIRy4() { 00392 return IR_object_y4; 00393 }; 00394 00395 /** 00396 * IR object 4 size read from the Wii IR camera. 00397 * @return The size of the object in the range 0-15. 00398 */ 00399 uint8_t getIRs4() { 00400 return IR_object_s4; 00401 }; 00402 00403 /** 00404 * Use this to check if the camera is enabled or not. 00405 * If not call WII#IRinitialize to initialize the IR camera. 00406 * @return True if it's enabled, false if not. 00407 */ 00408 bool isIRCameraEnabled() { 00409 return (wiiState & 0x08); 00410 }; 00411 /**@}*/ 00412 #endif 00413 00414 protected: 00415 /** @name BluetoothService implementation */ 00416 /** 00417 * Used to pass acldata to the services. 00418 * @param ACLData Incoming acldata. 00419 */ 00420 void ACLData(uint8_t* ACLData); 00421 /** Used to run part of the state machine. */ 00422 void Run(); 00423 /** Use this to reset the service. */ 00424 void Reset(); 00425 /** 00426 * Called when the controller is successfully initialized. 00427 * Use attachOnInit(void (*funcOnInit)(void)) to call your own function. 00428 * This is useful for instance if you want to set the LEDs in a specific way. 00429 */ 00430 void onInit(); 00431 /**@}*/ 00432 00433 private: 00434 00435 void L2CAP_task(); // L2CAP state machine 00436 00437 /* Variables filled from HCI event management */ 00438 bool activeConnection; // Used to indicate if it's already has established a connection 00439 00440 /* Variables used by high level L2CAP task */ 00441 uint8_t l2cap_state; 00442 uint8_t wii_event_flag; // Used for Wii flags 00443 00444 uint32_t ButtonState; 00445 uint32_t OldButtonState; 00446 uint32_t ButtonClickState; 00447 uint16_t hatValues[4]; 00448 00449 uint8_t HIDBuffer[3]; // Used to store HID commands 00450 00451 uint16_t stateCounter; 00452 bool unknownExtensionConnected; 00453 bool extensionConnected; 00454 bool checkBatteryLevel; // Set to true when getBatteryLevel() is called otherwise if should be false 00455 bool motionPlusInside; // True if it's a new Wiimote with the Motion Plus extension build into it 00456 00457 /* L2CAP Channels */ 00458 uint8_t control_scid[2]; // L2CAP source CID for HID_Control 00459 uint8_t control_dcid[2]; // 0x0060 00460 uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt 00461 uint8_t interrupt_dcid[2]; // 0x0061 00462 00463 /* HID Commands */ 00464 void HID_Command(uint8_t* data, uint8_t nbytes); 00465 void setReportMode(bool continuous, uint8_t mode); 00466 00467 void writeData(uint32_t offset, uint8_t size, uint8_t* data); 00468 void initExtension1(); 00469 void initExtension2(); 00470 00471 void statusRequest(); // Used to update the Wiimote state and battery level 00472 00473 void readData(uint32_t offset, uint16_t size, bool EEPROM); 00474 void readExtensionType(); 00475 void readCalData(); 00476 void readWiiBalanceBoardCalibration(); // Used by the library to read the Wii Balance Board calibration values 00477 00478 void checkMotionPresent(); // Used to see if a Motion Plus is connected to the Wiimote 00479 void initMotionPlus(); 00480 void activateMotionPlus(); 00481 00482 uint16_t wiiBalanceBoardRaw[4]; // Wii Balance Board raw values 00483 uint16_t wiiBalanceBoardCal[3][4]; // Wii Balance Board calibration values 00484 00485 float compPitch; // Fusioned angle using a complimentary filter if the Motion Plus is connected 00486 float compRoll; // Fusioned angle using a complimentary filter if the Motion Plus is connected 00487 00488 bool activateNunchuck; 00489 bool motionValuesReset; // This bool is true when the gyro values has been reset 00490 uint32_t timer; 00491 00492 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) 00493 uint8_t batteryLevel; 00494 00495 #ifdef WIICAMERA 00496 /* Private function and variables for the readings from the IR Camera */ 00497 void enableIRCamera1(); // Sets bit 2 of output report 13 00498 void enableIRCamera2(); // Sets bit 2 of output report 1A 00499 void writeSensitivityBlock1(); 00500 void writeSensitivityBlock2(); 00501 void write0x08Value(); 00502 void setWiiModeNumber(uint8_t mode_number); 00503 00504 uint16_t IR_object_x1; // IR x position 10 bits 00505 uint16_t IR_object_y1; // IR y position 10 bits 00506 uint8_t IR_object_s1; // IR size value 00507 uint16_t IR_object_x2; 00508 uint16_t IR_object_y2; 00509 uint8_t IR_object_s2; 00510 uint16_t IR_object_x3; // IR x position 10 bits 00511 uint16_t IR_object_y3; // IR y position 10 bits 00512 uint8_t IR_object_s3; // IR size value 00513 uint16_t IR_object_x4; 00514 uint16_t IR_object_y4; 00515 uint8_t IR_object_s4; 00516 #endif 00517 }; 00518 #endif 00519
Generated on Thu Jul 14 2022 08:33:41 by
1.7.2