mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Merge pull request #146 from felis/WiiBalanceBoard
Added support for Wii balance board
This commit is contained in:
commit
7095b58896
7 changed files with 230 additions and 49 deletions
55
BTD.cpp
55
BTD.cpp
|
@ -445,11 +445,17 @@ void BTD::HCI_event_task() {
|
|||
for(uint8_t j = 0; j < 3; j++)
|
||||
classOfDevice[j] = hcibuf[j + 4 + offset];
|
||||
|
||||
#ifdef EXTRADEBUG
|
||||
Notify(PSTR("\r\nClass of device: "), 0x80);
|
||||
D_PrintHex<uint8_t > (classOfDevice[2], 0x80);
|
||||
Notify(PSTR(" "), 0x80);
|
||||
D_PrintHex<uint8_t > (classOfDevice[1], 0x80);
|
||||
Notify(PSTR(" "), 0x80);
|
||||
D_PrintHex<uint8_t > (classOfDevice[0], 0x80);
|
||||
#endif
|
||||
|
||||
if(pairWithWii && classOfDevice[2] == 0x00 && (classOfDevice[1] & 0x05) && (classOfDevice[0] & 0x0C)) { // See http://wiibrew.org/wiki/Wiimote#SDP_information
|
||||
if(classOfDevice[0] & 0x08) // Check if it's the new Wiimote with motion plus inside that was detected
|
||||
motionPlusInside = true;
|
||||
else
|
||||
motionPlusInside = false;
|
||||
checkRemoteName = true; // Check remote name to distinguish between the different controllers
|
||||
|
||||
for(uint8_t j = 0; j < 6; j++)
|
||||
disc_bdaddr[j] = hcibuf[j + 3 + 6 * i];
|
||||
|
@ -472,16 +478,6 @@ void BTD::HCI_event_task() {
|
|||
hci_set_flag(HCI_FLAG_DEVICE_FOUND);
|
||||
break;
|
||||
}
|
||||
#ifdef EXTRADEBUG
|
||||
else {
|
||||
Notify(PSTR("\r\nClass of device: "), 0x80);
|
||||
D_PrintHex<uint8_t > (classOfDevice[2], 0x80);
|
||||
Notify(PSTR(" "), 0x80);
|
||||
D_PrintHex<uint8_t > (classOfDevice[1], 0x80);
|
||||
Notify(PSTR(" "), 0x80);
|
||||
D_PrintHex<uint8_t > (classOfDevice[0], 0x80);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -555,7 +551,7 @@ void BTD::HCI_event_task() {
|
|||
case EV_PIN_CODE_REQUEST:
|
||||
if(pairWithWii) {
|
||||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nPairing with wiimote"), 0x80);
|
||||
Notify(PSTR("\r\nPairing with Wiimote"), 0x80);
|
||||
#endif
|
||||
hci_pin_code_request_reply();
|
||||
} else if(btdPin != NULL) {
|
||||
|
@ -705,7 +701,7 @@ void BTD::HCI_task() {
|
|||
if(pairWithHIDDevice || pairWithWii) { // Check if it should try to connect to a Wiimote
|
||||
#ifdef DEBUG_USB_HOST
|
||||
if(pairWithWii)
|
||||
Notify(PSTR("\r\nStarting inquiry\r\nPress 1 & 2 on the Wiimote\r\nOr press sync if you are using a Wii U Pro Controller"), 0x80);
|
||||
Notify(PSTR("\r\nStarting inquiry\r\nPress 1 & 2 on the Wiimote\r\nOr press the SYNC button if you are using a Wii U Pro Controller or a Wii Balance Board"), 0x80);
|
||||
else
|
||||
Notify(PSTR("\r\nPlease enable discovery of your device"), 0x80);
|
||||
#endif
|
||||
|
@ -736,8 +732,8 @@ void BTD::HCI_task() {
|
|||
else
|
||||
Notify(PSTR("device"), 0x80);
|
||||
#endif
|
||||
if(motionPlusInside) {
|
||||
hci_remote_name(); // We need to know the name to distinguish between a Wiimote and a Wii U Pro Controller
|
||||
if(checkRemoteName) {
|
||||
hci_remote_name(); // We need to know the name to distinguish between the Wiimote, the new Wiimote with Motion Plus inside, a Wii U Pro Controller and a Wii Balance Board
|
||||
hci_state = HCI_REMOTE_NAME_STATE;
|
||||
} else
|
||||
hci_state = HCI_CONNECT_DEVICE_STATE;
|
||||
|
@ -752,6 +748,7 @@ void BTD::HCI_task() {
|
|||
else
|
||||
Notify(PSTR("\r\nConnecting to HID device"), 0x80);
|
||||
#endif
|
||||
checkRemoteName = false;
|
||||
hci_connect();
|
||||
hci_state = HCI_CONNECTED_DEVICE_STATE;
|
||||
}
|
||||
|
@ -809,6 +806,9 @@ void BTD::HCI_task() {
|
|||
#endif
|
||||
if(strncmp((const char*)remote_name, "Nintendo", 8) == 0) {
|
||||
incomingWii = true;
|
||||
motionPlusInside = false;
|
||||
wiiUProController = false;
|
||||
pairWiiUsingSync = false;
|
||||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nWiimote is connecting"), 0x80);
|
||||
#endif
|
||||
|
@ -821,11 +821,12 @@ void BTD::HCI_task() {
|
|||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR(" - Wii U Pro Controller"), 0x80);
|
||||
#endif
|
||||
motionPlusInside = true;
|
||||
wiiUProController = true;
|
||||
} else {
|
||||
motionPlusInside = false;
|
||||
wiiUProController = false;
|
||||
wiiUProController = motionPlusInside = pairWiiUsingSync = true;
|
||||
} else if(strncmp((const char*)remote_name, "Nintendo RVL-WBC-01", 19) == 0) {
|
||||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR(" - Wii Balance Board"), 0x80);
|
||||
#endif
|
||||
pairWiiUsingSync = true;
|
||||
}
|
||||
}
|
||||
if(classOfDevice[2] == 0 && classOfDevice[1] == 0x25 && classOfDevice[0] == 0x08 && strncmp((const char*)remote_name, "Wireless Controller", 19) == 0) {
|
||||
|
@ -834,7 +835,7 @@ void BTD::HCI_task() {
|
|||
#endif
|
||||
incomingPS4 = true;
|
||||
}
|
||||
if(pairWithWii && motionPlusInside)
|
||||
if(pairWithWii && checkRemoteName)
|
||||
hci_state = HCI_CONNECT_DEVICE_STATE;
|
||||
else {
|
||||
hci_accept_connection();
|
||||
|
@ -886,7 +887,7 @@ void BTD::HCI_task() {
|
|||
memset(l2capinbuf, 0, BULK_MAXPKTSIZE);
|
||||
|
||||
connectToWii = incomingWii = pairWithWii = false;
|
||||
connectToHIDDevice = incomingHIDDevice = pairWithHIDDevice = false;
|
||||
connectToHIDDevice = incomingHIDDevice = pairWithHIDDevice = checkRemoteName = false;
|
||||
incomingPS4 = false;
|
||||
|
||||
hci_state = HCI_SCANNING_STATE;
|
||||
|
@ -1085,9 +1086,9 @@ void BTD::hci_pin_code_request_reply() {
|
|||
hcibuf[8] = disc_bdaddr[5];
|
||||
if(pairWithWii) {
|
||||
hcibuf[9] = 6; // Pin length is the length of the Bluetooth address
|
||||
if(wiiUProController) {
|
||||
if(pairWiiUsingSync) {
|
||||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nParing with Wii U Pro Controller"), 0x80);
|
||||
Notify(PSTR("\r\nParing with Wii controller via SYNC"), 0x80);
|
||||
#endif
|
||||
for(uint8_t i = 0; i < 6; i++)
|
||||
hcibuf[10 + i] = my_bdaddr[i]; // The pin is the Bluetooth dongles Bluetooth address backwards
|
||||
|
|
2
BTD.h
2
BTD.h
|
@ -535,6 +535,8 @@ private:
|
|||
uint8_t pollInterval;
|
||||
bool bPollEnable;
|
||||
|
||||
bool pairWiiUsingSync; // True if paring was done using the Wii SYNC button.
|
||||
bool checkRemoteName; // Used to check remote device's name before connecting.
|
||||
bool incomingPS4; // True if a PS4 controller is connecting
|
||||
uint8_t classOfDevice[3]; // Class of device of last device
|
||||
|
||||
|
|
16
README.md
16
README.md
|
@ -37,6 +37,8 @@ Help yourself by helping us support you! Many thousands of hours have been spent
|
|||
# Table of Contents
|
||||
|
||||
* [How to include the library](#how-to-include-the-library)
|
||||
* [Arduino Library Manager](#arduino-library-manager)
|
||||
* [Manual installation](#manual-installation)
|
||||
* [How to use the library](#how-to-use-the-library)
|
||||
* [Documentation](#documentation)
|
||||
* [Enable debugging](#enable-debugging)
|
||||
|
@ -57,6 +59,14 @@ Help yourself by helping us support you! Many thousands of hours have been spent
|
|||
|
||||
# How to include the library
|
||||
|
||||
### Arduino Library Manager
|
||||
|
||||
First install Arduino IDE version 1.6.2 or newer, then simply use the Arduino Library Manager to install the library.
|
||||
|
||||
Please see the following page for instructions: <http://www.arduino.cc/en/Guide/Libraries#toc3>.
|
||||
|
||||
### Manual installation
|
||||
|
||||
First download the library by clicking on the following link: <https://github.com/felis/USB_Host_Shield_2.0/archive/master.zip>.
|
||||
|
||||
Then uncompress the zip folder and rename the directory to "USB\_Host\_Shield\_20", as any special characters are not supported by the Arduino IDE.
|
||||
|
@ -243,7 +253,7 @@ An Xbox ONE controller is supported via USB in the [XBOXONE](XBOXONE.cpp) class.
|
|||
|
||||
### [Wii library](Wii.cpp)
|
||||
|
||||
The [Wii](Wii.cpp) library support the Wiimote, but also the Nunchuch and Motion Plus extensions via Bluetooth. The Wii U Pro Controller is also supported via Bluetooth.
|
||||
The [Wii](Wii.cpp) library support the Wiimote, but also the Nunchuch and Motion Plus extensions via Bluetooth. The Wii U Pro Controller and Wii Balance Board are also supported via Bluetooth.
|
||||
|
||||
First you have to pair with the controller, this is done automatically by the library if you create the instance like so:
|
||||
|
||||
|
@ -251,7 +261,7 @@ First you have to pair with the controller, this is done automatically by the li
|
|||
WII Wii(&Btd, PAIR);
|
||||
```
|
||||
|
||||
And then press 1 & 2 at once on the Wiimote or press sync if you are using a Wii U Pro Controller.
|
||||
And then press 1 & 2 at once on the Wiimote or the SYNC buttons if you are using a Wii U Pro Controller or a Wii Balance Board.
|
||||
|
||||
After that you can simply create the instance like so:
|
||||
|
||||
|
@ -271,13 +281,13 @@ The Wii IR camera can also be used, but you will have to activate the code for i
|
|||
|
||||
The [WiiIRCamera.ino](examples/Bluetooth/WiiIRCamera/WiiIRCamera.ino) example shows how it can be used.
|
||||
|
||||
|
||||
All the information about the Wii controllers are from these sites:
|
||||
|
||||
* <http://wiibrew.org/wiki/Wiimote>
|
||||
* <http://wiibrew.org/wiki/Wiimote/Extension_Controllers>
|
||||
* <http://wiibrew.org/wiki/Wiimote/Extension_Controllers/Nunchuck>
|
||||
* <http://wiibrew.org/wiki/Wiimote/Extension_Controllers/Wii_Motion_Plus>
|
||||
* <http://wiibrew.org/wiki/Wii_Balance_Board>
|
||||
* The old library created by _Tomoyuki Tanaka_: <https://github.com/moyuchin/WiiRemote_on_Arduino> also helped a lot.
|
||||
|
||||
### [PS Buzz Library](PSBuzz.cpp)
|
||||
|
|
99
Wii.cpp
99
Wii.cpp
|
@ -108,6 +108,7 @@ void WII::Reset() {
|
|||
motionPlusInside = false;
|
||||
pBtd->wiiUProController = false;
|
||||
wiiUProControllerConnected = false;
|
||||
wiiBalanceBoardConnected = false;
|
||||
l2cap_event_flag = 0; // Reset flags
|
||||
l2cap_state = L2CAP_WAIT;
|
||||
}
|
||||
|
@ -263,7 +264,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
|||
else if(wiiUProControllerConnected)
|
||||
ButtonState = (uint32_t)(((~l2capinbuf[23]) & 0xFE) | ((uint16_t)(~l2capinbuf[24]) << 8) | ((uint32_t)((~l2capinbuf[25]) & 0x03) << 16));
|
||||
else if(motionPlusConnected) {
|
||||
if(l2capinbuf[20] & 0x02) // Only update the wiimote buttons, since the extension bytes are from the Motion Plus
|
||||
if(l2capinbuf[20] & 0x02) // Only update the Wiimote buttons, since the extension bytes are from the Motion Plus
|
||||
ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)(ButtonState & 0xFFFF0000)));
|
||||
else if(nunchuckConnected) // Update if it's a report from the Nunchuck
|
||||
ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)((~l2capinbuf[20]) & 0x0C) << 14));
|
||||
|
@ -295,11 +296,8 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
|||
#endif
|
||||
wiiState = 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)
|
||||
batteryLevel = l2capinbuf[15]; // Update battery level
|
||||
#ifdef DEBUG_USB_HOST
|
||||
if(l2capinbuf[12] & 0x01)
|
||||
Notify(PSTR("\r\nWARNING: Battery is nearly empty"), 0x80);
|
||||
#endif
|
||||
if(checkExtension) { // If this is false it means that the user must have called getBatteryLevel()
|
||||
|
||||
if(!checkBatteryLevel) { // If this is true it means that the user must have called getBatteryLevel()
|
||||
if(l2capinbuf[12] & 0x02) { // Check if a extension is connected
|
||||
#ifdef DEBUG_USB_HOST
|
||||
if(!unknownExtensionConnected)
|
||||
|
@ -333,11 +331,22 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
|||
} else
|
||||
setReportMode(false, 0x31); // If there is no extension connected we will read the buttons and accelerometer
|
||||
}
|
||||
} else
|
||||
checkExtension = true; // Check for extensions by default
|
||||
}
|
||||
else {
|
||||
#ifdef EXTRADEBUG
|
||||
Notify(PSTR("\r\nChecking battery level"), 0x80);
|
||||
#endif
|
||||
checkBatteryLevel = false; // Check for extensions by default
|
||||
}
|
||||
#ifdef DEBUG_USB_HOST
|
||||
if(l2capinbuf[12] & 0x01)
|
||||
Notify(PSTR("\r\nWARNING: Battery is nearly empty"), 0x80);
|
||||
#endif
|
||||
|
||||
break;
|
||||
case 0x21: // Read Memory Data
|
||||
if((l2capinbuf[12] & 0x0F) == 0) { // No error
|
||||
uint8_t reportLength = (l2capinbuf[12] >> 4) + 1; // // Bit 4-7 is the length - 1
|
||||
// See: http://wiibrew.org/wiki/Wiimote/Extension_Controllers
|
||||
if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x00) {
|
||||
#ifdef DEBUG_USB_HOST
|
||||
|
@ -380,6 +389,27 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
|||
Notify(PSTR("\r\nWii U Pro Controller connected"), 0x80);
|
||||
#endif
|
||||
wiiUProControllerConnected = true;
|
||||
} else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x04 && l2capinbuf[20] == 0x02) {
|
||||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nWii Balance Board connected"), 0x80);
|
||||
#endif
|
||||
setReportMode(false, 0x32); // Read the Wii Balance Board extension
|
||||
wii_set_flag(WII_FLAG_CALIBRATE_BALANCE_BOARD);
|
||||
}
|
||||
// Wii Balance Board calibration reports (24 bits in total)
|
||||
else if(l2capinbuf[13] == 0x00 && l2capinbuf[14] == 0x24 && reportLength == 16) { // First 16-bit
|
||||
for(uint8_t i = 0; i < 2; i++) {
|
||||
for(uint8_t j = 0; j < 4; j++)
|
||||
wiiBalanceBoardCal[i][j] = l2capinbuf[16 + 8 * i + 2 * j] | l2capinbuf[15 + 8 * i + 2 * j] << 8;
|
||||
}
|
||||
} else if(l2capinbuf[13] == 0x00 && l2capinbuf[14] == 0x34 && reportLength == 8) { // Last 8-bit
|
||||
for(uint8_t j = 0; j < 4; j++)
|
||||
wiiBalanceBoardCal[2][j] = l2capinbuf[16 + 2 * j] | l2capinbuf[15 + 2 * j] << 8;
|
||||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nWii Balance Board calibration values read successfully"), 0x80);
|
||||
#endif
|
||||
wii_clear_flag(WII_FLAG_CALIBRATE_BALANCE_BOARD);
|
||||
wiiBalanceBoardConnected = true;
|
||||
}
|
||||
#ifdef DEBUG_USB_HOST
|
||||
else {
|
||||
|
@ -387,7 +417,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
|||
D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
|
||||
D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
|
||||
Notify(PSTR("\r\nData: "), 0x80);
|
||||
for(uint8_t i = 0; i < ((l2capinbuf[12] >> 4) + 1); i++) { // bit 4-7 is the length-1
|
||||
for(uint8_t i = 0; i < reportLength; i++) {
|
||||
D_PrintHex<uint8_t > (l2capinbuf[15 + i], 0x80);
|
||||
Notify(PSTR(" "), 0x80);
|
||||
}
|
||||
|
@ -415,13 +445,18 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
|||
case 0x31: // Core Buttons and Accelerometer - (a1) 31 BB BB AA AA AA
|
||||
break;
|
||||
case 0x32: // Core Buttons with 8 Extension bytes - (a1) 32 BB BB EE EE EE EE EE EE EE EE
|
||||
// See: http://wiibrew.org/wiki/Wii_Balance_Board#Data_Format
|
||||
wiiBalanceBoardRaw[TopRight] = l2capinbuf[13] | l2capinbuf[12] << 8; // Top right
|
||||
wiiBalanceBoardRaw[BotRight] = l2capinbuf[15] | l2capinbuf[14] << 8; // Bottom right
|
||||
wiiBalanceBoardRaw[TopLeft] = l2capinbuf[17] | l2capinbuf[16] << 8; // Top left
|
||||
wiiBalanceBoardRaw[BotLeft] = l2capinbuf[19] | l2capinbuf[18] << 8; // Bottom left
|
||||
break;
|
||||
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
|
||||
#ifdef WIICAMERA
|
||||
// Read the IR data
|
||||
IR_object_x1 = (l2capinbuf[15] | ((uint16_t)(l2capinbuf[17] & 0x30) << 4)); // x position
|
||||
IR_object_y1 = (l2capinbuf[16] | ((uint16_t)(l2capinbuf[17] & 0xC0) << 2)); // y position
|
||||
IR_object_s1 = (l2capinbuf[17] & 0x0F); // size value, 0-15
|
||||
IR_object_s1 = (l2capinbuf[17] & 0x0F); // Size value, 0-15
|
||||
|
||||
IR_object_x2 = (l2capinbuf[18] | ((uint16_t)(l2capinbuf[20] & 0x30) << 4));
|
||||
IR_object_y2 = (l2capinbuf[19] | ((uint16_t)(l2capinbuf[20] & 0xC0) << 2));
|
||||
|
@ -460,6 +495,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
|||
break;
|
||||
case 0x35: // Core Buttons and Accelerometer with 16 Extension Bytes
|
||||
// (a1) 35 BB BB AA AA AA EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
|
||||
#if 1 // Set this to 0 if you don't want to use an extension, this reduceds the size of the library a lot!
|
||||
if(motionPlusConnected) {
|
||||
if(l2capinbuf[20] & 0x02) { // Check if it's a report from the Motion controller or the extension
|
||||
if(motionValuesReset) { // We will only use the values when the gyro value has been set
|
||||
|
@ -563,6 +599,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
|
|||
hatValues[LeftHatY] = (l2capinbuf[19] | l2capinbuf[20] << 8);
|
||||
hatValues[RightHatY] = (l2capinbuf[21] | l2capinbuf[22] << 8);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#ifdef DEBUG_USB_HOST
|
||||
default:
|
||||
|
@ -751,13 +788,21 @@ void WII::Run() {
|
|||
if(unknownExtensionConnected) // Check if there is a extension is connected to the port
|
||||
initExtension1();
|
||||
else
|
||||
stateCounter = 399;
|
||||
stateCounter = 499;
|
||||
} else if(stateCounter == 200)
|
||||
initExtension2();
|
||||
else if(stateCounter == 300) {
|
||||
readExtensionType();
|
||||
unknownExtensionConnected = false;
|
||||
} else if(stateCounter == 400) {
|
||||
if(wii_check_flag(WII_FLAG_CALIBRATE_BALANCE_BOARD)) {
|
||||
#ifdef DEBUG_USB_HOST
|
||||
Notify(PSTR("\r\nReading Wii Balance Board calibration values"), 0x80);
|
||||
#endif
|
||||
readWiiBalanceBoardCalibration();
|
||||
} else
|
||||
stateCounter = 499;
|
||||
} else if(stateCounter == 500) {
|
||||
stateCounter = 0;
|
||||
l2cap_state = TURN_ON_LED;
|
||||
}
|
||||
|
@ -839,8 +884,8 @@ void WII::Run() {
|
|||
|
||||
/************************************************************/
|
||||
/* HID Commands */
|
||||
|
||||
/************************************************************/
|
||||
|
||||
void WII::HID_Command(uint8_t* data, uint8_t nbytes) {
|
||||
if(motionPlusInside)
|
||||
pBtd->L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]); // It's the new Wiimote with the Motion Plus Inside or Wii U Pro controller
|
||||
|
@ -914,7 +959,7 @@ void WII::setLedStatus() {
|
|||
}
|
||||
|
||||
uint8_t WII::getBatteryLevel() {
|
||||
checkExtension = false; // This is needed so the library knows that the status response is a response to this function
|
||||
checkBatteryLevel = true; // This is needed so the library knows that the status response is a response to this function
|
||||
statusRequest(); // This will update the battery level
|
||||
return batteryLevel;
|
||||
};
|
||||
|
@ -941,8 +986,8 @@ void WII::statusRequest() {
|
|||
|
||||
/************************************************************/
|
||||
/* Memmory Commands */
|
||||
|
||||
/************************************************************/
|
||||
|
||||
void WII::writeData(uint32_t offset, uint8_t size, uint8_t* data) {
|
||||
uint8_t cmd_buf[23];
|
||||
cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
|
||||
|
@ -1030,9 +1075,12 @@ void WII::checkMotionPresent() {
|
|||
readData(0xA600FA, 6, false);
|
||||
}
|
||||
|
||||
void WII::readWiiBalanceBoardCalibration() {
|
||||
readData(0xA40024, 24, false);
|
||||
}
|
||||
|
||||
/************************************************************/
|
||||
/* WII Commands */
|
||||
|
||||
/************************************************************/
|
||||
|
||||
bool WII::getButtonPress(ButtonEnum b) { // Return true when a button is pressed
|
||||
|
@ -1084,6 +1132,27 @@ void WII::onInit() {
|
|||
setLedStatus();
|
||||
}
|
||||
|
||||
/************************************************************/
|
||||
/* Wii Balance Board Commands */
|
||||
/************************************************************/
|
||||
|
||||
float WII::getWeight(BalanceBoardEnum pos) {
|
||||
// Use interpolating between two points - based on: https://github.com/skorokithakis/gr8w8upd8m8/blob/master/gr8w8upd8m8.py
|
||||
// wiiBalanceBoardCal[pos][0] is calibration values for 0 kg
|
||||
// wiiBalanceBoardCal[pos][1] is calibration values for 17 kg
|
||||
// wiiBalanceBoardCal[pos][2] is calibration values for 34 kg
|
||||
if(wiiBalanceBoardRaw[pos] < wiiBalanceBoardCal[0][pos])
|
||||
return 0.0f; // Below 0 kg
|
||||
else if(wiiBalanceBoardRaw[pos] < wiiBalanceBoardCal[1][pos]) // Between 0 and 17 kg
|
||||
return 17.0f * (float)(wiiBalanceBoardRaw[pos] - wiiBalanceBoardCal[0][pos]) / (float)(wiiBalanceBoardCal[1][pos] - wiiBalanceBoardCal[0][pos]);
|
||||
else // More than 17 kg
|
||||
return 17.0f + 17.0f * (float)(wiiBalanceBoardRaw[pos] - wiiBalanceBoardCal[1][pos]) / (float)(wiiBalanceBoardCal[2][pos] - wiiBalanceBoardCal[1][pos]);
|
||||
};
|
||||
|
||||
float WII::getTotalWeight() {
|
||||
return getWeight(TopRight) + getWeight(BotRight) + getWeight(TopLeft) + getWeight(BotLeft);
|
||||
};
|
||||
|
||||
/************************************************************/
|
||||
/* The following functions are for the IR camera */
|
||||
/************************************************************/
|
||||
|
|
46
Wii.h
46
Wii.h
|
@ -24,8 +24,9 @@
|
|||
#include "controllerEnums.h"
|
||||
|
||||
/* Wii event flags */
|
||||
#define WII_FLAG_MOTION_PLUS_CONNECTED 0x01
|
||||
#define WII_FLAG_NUNCHUCK_CONNECTED 0x02
|
||||
#define WII_FLAG_MOTION_PLUS_CONNECTED (1 << 0)
|
||||
#define WII_FLAG_NUNCHUCK_CONNECTED (1 << 1)
|
||||
#define WII_FLAG_CALIBRATE_BALANCE_BOARD (1 << 2)
|
||||
|
||||
#define wii_check_flag(flag) (wii_event_flag & (flag))
|
||||
#define wii_set_flag(flag) (wii_event_flag |= (flag))
|
||||
|
@ -39,6 +40,14 @@ enum HatEnum {
|
|||
HatY = 1,
|
||||
};
|
||||
|
||||
/** Enum used to read the weight on Wii Balance Board. */
|
||||
enum BalanceBoardEnum {
|
||||
TopRight = 0,
|
||||
BotRight = 1,
|
||||
TopLeft = 2,
|
||||
BotLeft = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* This BluetoothService class implements support for the Wiimote including the Nunchuck and Motion Plus extension.
|
||||
*
|
||||
|
@ -191,6 +200,8 @@ public:
|
|||
bool motionPlusConnected;
|
||||
/** Variable used to indicate if a Wii U Pro controller is connected. */
|
||||
bool wiiUProControllerConnected;
|
||||
/** Variable used to indicate if a Wii Balance Board is connected. */
|
||||
bool wiiBalanceBoardConnected;
|
||||
/**@}*/
|
||||
|
||||
/* IMU Data, might be usefull if you need to do something more advanced than just calculating the angle */
|
||||
|
@ -261,6 +272,31 @@ public:
|
|||
int16_t gyroPitchZero;
|
||||
/**@}*/
|
||||
|
||||
/** @name Wii Balance Board functions */
|
||||
|
||||
/**
|
||||
* Used to get the weight at the specific position on the Wii Balance Board.
|
||||
* @param ::BalanceBoardEnum to read from.
|
||||
* @return Returns the weight in kg.
|
||||
*/
|
||||
float getWeight(BalanceBoardEnum pos);
|
||||
|
||||
/**
|
||||
* Used to get total weight on the Wii Balance Board.
|
||||
* @returnReturns the weight in kg.
|
||||
*/
|
||||
float getTotalWeight();
|
||||
|
||||
/**
|
||||
* Used to get the raw reading at the specific position on the Wii Balance Board.
|
||||
* @param ::BalanceBoardEnum to read from.
|
||||
* @return Returns the raw reading.
|
||||
*/
|
||||
uint16_t getWeightRaw(BalanceBoardEnum pos) {
|
||||
return wiiBalanceBoardRaw[pos];
|
||||
};
|
||||
/**@}*/
|
||||
|
||||
#ifdef WIICAMERA
|
||||
/** @name Wiimote IR camera functions
|
||||
* You will have to set ::ENABLE_WII_IR_CAMERA in settings.h to 1 in order use the IR camera.
|
||||
|
@ -415,7 +451,7 @@ private:
|
|||
uint16_t stateCounter;
|
||||
bool unknownExtensionConnected;
|
||||
bool extensionConnected;
|
||||
bool checkExtension; // Set to false when getBatteryLevel() is called otherwise if should be true
|
||||
bool checkBatteryLevel; // Set to true when getBatteryLevel() is called otherwise if should be false
|
||||
bool motionPlusInside; // True if it's a new Wiimote with the Motion Plus extension build into it
|
||||
|
||||
/* L2CAP Channels */
|
||||
|
@ -437,11 +473,15 @@ private:
|
|||
void readData(uint32_t offset, uint16_t size, bool EEPROM);
|
||||
void readExtensionType();
|
||||
void readCalData();
|
||||
void readWiiBalanceBoardCalibration(); // Used by the library to read the Wii Balance Board calibration values
|
||||
|
||||
void checkMotionPresent(); // Used to see if a Motion Plus is connected to the Wiimote
|
||||
void initMotionPlus();
|
||||
void activateMotionPlus();
|
||||
|
||||
uint16_t wiiBalanceBoardRaw[4]; // Wii Balance Board raw values
|
||||
uint16_t wiiBalanceBoardCal[3][4]; // Wii Balance Board calibration values
|
||||
|
||||
double compPitch; // Fusioned angle using a complimentary filter if the Motion Plus is connected
|
||||
double compRoll; // Fusioned angle using a complimentary filter if the Motion Plus is connected
|
||||
|
||||
|
|
51
examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino
Normal file
51
examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Example sketch for the Wii Balance Board Bluetooth library - developed by Kristian Lauszus
|
||||
For more information visit my blog: http://blog.tkjelectronics.dk/ or
|
||||
send me an e-mail: kristianl@tkjelectronics.com
|
||||
*/
|
||||
|
||||
#include <Wii.h>
|
||||
#include <usbhub.h>
|
||||
|
||||
// Satisfy the IDE, which needs to see the include statment in the ino too.
|
||||
#ifdef dobogusinclude
|
||||
#include <spi4teensy3.h>
|
||||
#include <SPI.h>
|
||||
#endif
|
||||
|
||||
USB Usb;
|
||||
//USBHub Hub1(&Usb); // Some dongles have a hub inside
|
||||
|
||||
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
|
||||
/* You can create the instance of the class in two ways */
|
||||
WII Wii(&Btd, PAIR); // This will start an inquiry and then pair with your Wii Balance Board - you only have to do this once
|
||||
//WII Wii(&Btd); // After that you can simply create the instance like so and then press the power button on the Wii Balance Board
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
#if !defined(__MIPSEL__)
|
||||
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
|
||||
#endif
|
||||
if (Usb.Init() == -1) {
|
||||
Serial.print(F("\r\nOSC did not start"));
|
||||
while (1); //halt
|
||||
}
|
||||
Serial.print(F("\r\nWii Balance Board Bluetooth Library Started"));
|
||||
}
|
||||
void loop() {
|
||||
Usb.Task();
|
||||
if (Wii.wiiBalanceBoardConnected) {
|
||||
Serial.print(F("\r\nWeight: "));
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
Serial.print(Wii.getWeight((BalanceBoardEnum)i));
|
||||
Serial.print(F("\t"));
|
||||
}
|
||||
Serial.print(F("Total Weight: "));
|
||||
Serial.print(Wii.getTotalWeight());
|
||||
if (Wii.getButtonClick(A)) {
|
||||
Serial.print(F("\r\nA"));
|
||||
//Wii.setLedToggle(LED1); // The Wii Balance Board has one LED as well
|
||||
Wii.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -269,6 +269,7 @@ wiimoteConnected KEYWORD2
|
|||
nunchuckConnected KEYWORD2
|
||||
motionPlusConnected KEYWORD2
|
||||
wiiUProControllerConnected KEYWORD2
|
||||
wiiBalanceBoardConnected KEYWORD2
|
||||
setRumbleToggle KEYWORD2
|
||||
getPitch KEYWORD2
|
||||
getRoll KEYWORD2
|
||||
|
@ -281,6 +282,9 @@ PAIR KEYWORD2
|
|||
statusRequest KEYWORD2
|
||||
getBatteryLevel KEYWORD2
|
||||
getWiiState KEYWORD2
|
||||
getWeight KEYWORD2
|
||||
getTotalWeight KEYWORD2
|
||||
getWeightRaw KEYWORD2
|
||||
|
||||
####################################################
|
||||
# Constants and enums (LITERAL1)
|
||||
|
@ -299,6 +303,10 @@ ZL LITERAL1
|
|||
ZR LITERAL1
|
||||
HatX LITERAL1
|
||||
HatY LITERAL1
|
||||
TopRight LITERAL1
|
||||
BotRight LITERAL1
|
||||
TopLeft LITERAL1
|
||||
BotLeft LITERAL1
|
||||
|
||||
####################################################
|
||||
# Methods and Functions for the IR Camera
|
||||
|
|
Loading…
Reference in a new issue