From b1902b2a5509a5149fbe9b7d64002da6e380327f Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Thu, 16 Apr 2015 01:57:00 +0200 Subject: [PATCH 01/14] Initial support for Wii Balance Board Still need to convert readings into something meaningful --- BTD.cpp | 55 ++++++++++--------- BTD.h | 2 + README.md | 6 +- Wii.cpp | 35 +++++++++++- Wii.h | 2 + .../WiiBalanceBoard/WiiBalanceBoard.ino | 44 +++++++++++++++ keywords.txt | 1 + 7 files changed, 113 insertions(+), 32 deletions(-) create mode 100644 examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino diff --git a/BTD.cpp b/BTD.cpp index 42cf3d62..5c470bab 100755 --- a/BTD.cpp +++ b/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 (classOfDevice[2], 0x80); + Notify(PSTR(" "), 0x80); + D_PrintHex (classOfDevice[1], 0x80); + Notify(PSTR(" "), 0x80); + D_PrintHex (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 (classOfDevice[2], 0x80); - Notify(PSTR(" "), 0x80); - D_PrintHex (classOfDevice[1], 0x80); - Notify(PSTR(" "), 0x80); - D_PrintHex (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 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 diff --git a/BTD.h b/BTD.h index b7683f65..312e45f7 100755 --- a/BTD.h +++ b/BTD.h @@ -535,6 +535,8 @@ private: uint8_t pollInterval; bool bPollEnable; + bool pairWiiUsingSync; // True if paring was done using the 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 diff --git a/README.md b/README.md index 3efcfb03..60877437 100644 --- a/README.md +++ b/README.md @@ -245,7 +245,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: @@ -253,7 +253,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: @@ -273,13 +273,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: * * * * +* * The old library created by _Tomoyuki Tanaka_: also helped a lot. ### [PS Buzz Library](PSBuzz.cpp) diff --git a/Wii.cpp b/Wii.cpp index 008e5329..a0aa9d53 100755 --- a/Wii.cpp +++ b/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; } @@ -380,6 +381,12 @@ 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 + wiiBalanceBoardConnected = true; } #ifdef DEBUG_USB_HOST else { @@ -414,8 +421,32 @@ void WII::ACLData(uint8_t* l2capinbuf) { break; 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 - break; + case 0x32: { // Core Buttons with 8 Extension bytes - (a1) 32 BB BB EE EE EE EE EE EE EE EE +#if 1 + uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); + Notify(PSTR("\r\nLength: "), 0x80); + D_PrintHex (length - 2, 0x80); + Notify(PSTR("\tData: "), 0x80); + for(uint8_t i = 0; i < length - 2; i++) { + D_PrintHex (l2capinbuf[10 + i], 0x80); + Notify(PSTR(" "), 0x80); + } + + uint16_t topRight = (l2capinbuf[13] | l2capinbuf[12] << 8); + uint16_t botRight = (l2capinbuf[15] | l2capinbuf[14] << 8); + uint16_t topLeft = (l2capinbuf[17] | l2capinbuf[16] << 8); + uint16_t botleft = (l2capinbuf[19] | l2capinbuf[18] << 8); + + Notify(PSTR("\ttopRight: "), 0x80); + Notify(topRight, 0x80); + Notify(PSTR("\tbotRight: "), 0x80); + Notify(botRight, 0x80); + Notify(PSTR("\ttopLeft: "), 0x80); + Notify(topLeft, 0x80); + Notify(PSTR("\tbotleft: "), 0x80); + Notify(botleft, 0x80); +#endif + } 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 diff --git a/Wii.h b/Wii.h index 13ba8d50..c8a477aa 100755 --- a/Wii.h +++ b/Wii.h @@ -191,6 +191,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 */ diff --git a/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino b/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino new file mode 100644 index 00000000..af8a78bf --- /dev/null +++ b/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino @@ -0,0 +1,44 @@ +/* + 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 +#include + +// Satisfy the IDE, which needs to see the include statment in the ino too. +#ifdef dobogusinclude +#include +#include +#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) { + if (Wii.getButtonClick(A)) { + Serial.print(F("\r\nA")); + Wii.setLedToggle(LED1); + //Wii.disconnect(); + } + } +} diff --git a/keywords.txt b/keywords.txt index bbbfb03e..ade71b28 100644 --- a/keywords.txt +++ b/keywords.txt @@ -269,6 +269,7 @@ wiimoteConnected KEYWORD2 nunchuckConnected KEYWORD2 motionPlusConnected KEYWORD2 wiiUProControllerConnected KEYWORD2 +wiiBalanceBoardConnected KEYWORD2 setRumbleToggle KEYWORD2 getPitch KEYWORD2 getRoll KEYWORD2 From 03e0ec5d6d558aa859fb425732182aa63b3cd047 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Thu, 16 Apr 2015 02:15:52 +0200 Subject: [PATCH 02/14] Print values properly --- Wii.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Wii.cpp b/Wii.cpp index a0aa9d53..bb5935d6 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -438,13 +438,13 @@ void WII::ACLData(uint8_t* l2capinbuf) { uint16_t botleft = (l2capinbuf[19] | l2capinbuf[18] << 8); Notify(PSTR("\ttopRight: "), 0x80); - Notify(topRight, 0x80); + Serial.print(topRight); Notify(PSTR("\tbotRight: "), 0x80); - Notify(botRight, 0x80); + Serial.print(botRight); Notify(PSTR("\ttopLeft: "), 0x80); - Notify(topLeft, 0x80); + Serial.print(topLeft); Notify(PSTR("\tbotleft: "), 0x80); - Notify(botleft, 0x80); + Serial.print(botleft); #endif } 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 @@ -452,7 +452,7 @@ void WII::ACLData(uint8_t* l2capinbuf) { // 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)); From e555195e42d85d31d53f1ebdfd3c8667c43b7919 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Thu, 16 Apr 2015 02:26:18 +0200 Subject: [PATCH 03/14] Print raw Wii Balance Board values in example --- Wii.cpp | 33 ++++--------------- Wii.h | 5 +++ .../WiiBalanceBoard/WiiBalanceBoard.ino | 9 +++++ 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/Wii.cpp b/Wii.cpp index bb5935d6..bfb91175 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -421,32 +421,13 @@ void WII::ACLData(uint8_t* l2capinbuf) { break; 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 -#if 1 - uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); - Notify(PSTR("\r\nLength: "), 0x80); - D_PrintHex (length - 2, 0x80); - Notify(PSTR("\tData: "), 0x80); - for(uint8_t i = 0; i < length - 2; i++) { - D_PrintHex (l2capinbuf[10 + i], 0x80); - Notify(PSTR(" "), 0x80); - } - - uint16_t topRight = (l2capinbuf[13] | l2capinbuf[12] << 8); - uint16_t botRight = (l2capinbuf[15] | l2capinbuf[14] << 8); - uint16_t topLeft = (l2capinbuf[17] | l2capinbuf[16] << 8); - uint16_t botleft = (l2capinbuf[19] | l2capinbuf[18] << 8); - - Notify(PSTR("\ttopRight: "), 0x80); - Serial.print(topRight); - Notify(PSTR("\tbotRight: "), 0x80); - Serial.print(botRight); - Notify(PSTR("\ttopLeft: "), 0x80); - Serial.print(topLeft); - Notify(PSTR("\tbotleft: "), 0x80); - Serial.print(botleft); -#endif - } 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 + topRight = l2capinbuf[13] | l2capinbuf[12] << 8; + botRight = l2capinbuf[15] | l2capinbuf[14] << 8; + topLeft = l2capinbuf[17] | l2capinbuf[16] << 8; + botleft = l2capinbuf[19] | l2capinbuf[18] << 8; + 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 diff --git a/Wii.h b/Wii.h index c8a477aa..1578e5b8 100755 --- a/Wii.h +++ b/Wii.h @@ -263,6 +263,11 @@ public: int16_t gyroPitchZero; /**@}*/ + /**@{*/ + /** Wii Balance Board raw values. */ + uint16_t topRight, botRight, topLeft, botleft; + /**@}*/ + #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. diff --git a/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino b/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino index af8a78bf..11459519 100644 --- a/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino +++ b/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino @@ -35,6 +35,15 @@ void setup() { void loop() { Usb.Task(); if (Wii.wiiBalanceBoardConnected) { + Serial.print(F("\r\ntopRight: ")); + Serial.print(Wii.topRight); + Serial.print(F("\tbotRight: ")); + Serial.print(Wii.botRight); + Serial.print(F("\ttopLeft: ")); + Serial.print(Wii.topLeft); + Serial.print(F("\tbotleft: ")); + Serial.print(Wii.botleft); + if (Wii.getButtonClick(A)) { Serial.print(F("\r\nA")); Wii.setLedToggle(LED1); From a3fbffb42c6e2f5efe6106403acb6858b43bc2e3 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Thu, 16 Apr 2015 02:34:27 +0200 Subject: [PATCH 04/14] Updated some comments --- BTD.cpp | 2 +- BTD.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BTD.cpp b/BTD.cpp index 5c470bab..bcfba14b 100755 --- a/BTD.cpp +++ b/BTD.cpp @@ -701,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 the SYNC button if you are using a Wii U Pro Controller or Wii Balance Board"), 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 diff --git a/BTD.h b/BTD.h index 312e45f7..6549c30c 100755 --- a/BTD.h +++ b/BTD.h @@ -535,7 +535,7 @@ private: uint8_t pollInterval; bool bPollEnable; - bool pairWiiUsingSync; // True if paring was done using the SYNC button. + 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 From 9cb31799a8f14e5036ad35f06ff5502ba7dcc4b6 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Thu, 16 Apr 2015 16:50:08 +0200 Subject: [PATCH 05/14] Fix initialisation of extension bug in status report. The first status report were missed because checkExtension had to be true. Should fix bug reported here: http://blog.tkjelectronics.dk/2012/08/wiimote-added-to-usb-host-library/#comment-500635 --- Wii.cpp | 21 +++++++++++++-------- Wii.h | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Wii.cpp b/Wii.cpp index bfb91175..902a4301 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -296,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) @@ -334,8 +331,16 @@ 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 + } +#ifdef DEBUG_USB_HOST + else + Notify(PSTR("\r\nChecking battery level"), 0x80); + + if(l2capinbuf[12] & 0x01) + Notify(PSTR("\r\nWARNING: Battery is nearly empty"), 0x80); +#endif + + checkBatteryLevel = false; // Check for extensions by default break; case 0x21: // Read Memory Data if((l2capinbuf[12] & 0x0F) == 0) { // No error @@ -926,7 +931,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; }; diff --git a/Wii.h b/Wii.h index 1578e5b8..f2e52947 100755 --- a/Wii.h +++ b/Wii.h @@ -422,7 +422,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 */ From 7acf598a59d01113140022a0cf94637bea116307 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Thu, 16 Apr 2015 16:55:35 +0200 Subject: [PATCH 06/14] Convert Wii Balance Board readings into kg --- Wii.cpp | 40 +++++++++++-- Wii.h | 57 ++++++++++++++++++- .../WiiBalanceBoard/WiiBalanceBoard.ino | 22 ++++--- keywords.txt | 7 +++ 4 files changed, 105 insertions(+), 21 deletions(-) diff --git a/Wii.cpp b/Wii.cpp index 902a4301..d7b0b8c0 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -344,6 +344,7 @@ void WII::ACLData(uint8_t* l2capinbuf) { 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 @@ -391,15 +392,30 @@ void WII::ACLData(uint8_t* l2capinbuf) { Notify(PSTR("\r\nWii Balance Board connected"), 0x80); #endif setReportMode(false, 0x32); // Read the Wii Balance Board extension + wiiBalanceBoardCalibrationComplete = false; wiiBalanceBoardConnected = true; } + // 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++) + balanceBoardCal[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++) + balanceBoardCal[2][j] = l2capinbuf[16 + 2 * j] | l2capinbuf[15 + 2 * j] << 8; +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nWii Balance Board calibrated successfully"), 0x80); +#endif + wiiBalanceBoardCalibrationComplete = true; + } #ifdef DEBUG_USB_HOST else { Notify(PSTR("\r\nUnknown Device: "), 0x80); D_PrintHex (l2capinbuf[13], 0x80); D_PrintHex (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 (l2capinbuf[15 + i], 0x80); Notify(PSTR(" "), 0x80); } @@ -428,10 +444,10 @@ void WII::ACLData(uint8_t* l2capinbuf) { 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 - topRight = l2capinbuf[13] | l2capinbuf[12] << 8; - botRight = l2capinbuf[15] | l2capinbuf[14] << 8; - topLeft = l2capinbuf[17] | l2capinbuf[16] << 8; - botleft = l2capinbuf[19] | l2capinbuf[18] << 8; + balanceBoardRaw[TopRight] = l2capinbuf[13] | l2capinbuf[12] << 8; // Top right + balanceBoardRaw[BotRight] = l2capinbuf[15] | l2capinbuf[14] << 8; // Bottom right + balanceBoardRaw[TopLeft] = l2capinbuf[17] | l2capinbuf[16] << 8; // Top left + balanceBoardRaw[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 @@ -768,13 +784,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(wiiBalanceBoardConnected) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nCalibrating Wii Balance Board"), 0x80); +#endif + calibrateWiiBalanceBoard(); + } else + stateCounter = 499; + } else if(stateCounter == 500) { stateCounter = 0; l2cap_state = TURN_ON_LED; } @@ -1047,6 +1071,10 @@ void WII::checkMotionPresent() { readData(0xA600FA, 6, false); } +void WII::calibrateWiiBalanceBoard() { + readData(0xA40024, 24, false); +} + /************************************************************/ /* WII Commands */ diff --git a/Wii.h b/Wii.h index f2e52947..91026469 100755 --- a/Wii.h +++ b/Wii.h @@ -39,6 +39,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. * @@ -263,9 +271,48 @@ public: int16_t gyroPitchZero; /**@}*/ - /**@{*/ - /** Wii Balance Board raw values. */ - uint16_t topRight, botRight, topLeft, botleft; + /** @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) { + // Based on: https://github.com/skorokithakis/gr8w8upd8m8/blob/master/gr8w8upd8m8.py + // calibration[pos][0] is calibration values for 0 kg + // calibration[pos][1] is calibration values for 17 kg + // calibration[pos][2] is calibration values for 34 kg + float val = 0; + if(balanceBoardRaw[pos] < balanceBoardCal[0][pos]) + return val; + else if(balanceBoardRaw[pos] < balanceBoardCal[1][pos]) + val = 17 * ((balanceBoardRaw[pos] - balanceBoardCal[0][pos]) / float((balanceBoardCal[1][pos] - balanceBoardCal[0][pos]))); + else if(balanceBoardRaw[pos] > balanceBoardCal[1][pos]) + val = 17 + 17 * ((balanceBoardRaw[pos] - balanceBoardCal[1][pos]) / float((balanceBoardCal[2][pos] - balanceBoardCal[1][pos]))); + + return val; + }; + + /** + * Used to get total weight on the Wii Balance Board. + * @returnReturns the weight in kg. + */ + float getTotalWeight() { + return getWeight(TopRight) + getWeight(BotRight) + getWeight(TopLeft) + getWeight(BotLeft); + }; + + /** + * 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 balanceBoardRaw[pos]; + }; + + /** Indicates when the calibration of the Wii Balance Board is done. */ + bool wiiBalanceBoardCalibrationComplete; /**@}*/ #ifdef WIICAMERA @@ -448,6 +495,10 @@ private: void checkMotionPresent(); // Used to see if a Motion Plus is connected to the Wiimote void initMotionPlus(); void activateMotionPlus(); + void calibrateWiiBalanceBoard(); + + uint16_t balanceBoardRaw[4]; // Wii Balance Board raw values + uint16_t balanceBoardCal[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 diff --git a/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino b/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino index 11459519..6186a179 100644 --- a/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino +++ b/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino @@ -34,20 +34,18 @@ void setup() { } void loop() { Usb.Task(); - if (Wii.wiiBalanceBoardConnected) { - Serial.print(F("\r\ntopRight: ")); - Serial.print(Wii.topRight); - Serial.print(F("\tbotRight: ")); - Serial.print(Wii.botRight); - Serial.print(F("\ttopLeft: ")); - Serial.print(Wii.topLeft); - Serial.print(F("\tbotleft: ")); - Serial.print(Wii.botleft); - + if (Wii.wiiBalanceBoardConnected && Wii.wiiBalanceBoardCalibrationComplete) { + 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); - //Wii.disconnect(); + //Wii.setLedToggle(LED1); // The Wii Balance Board has one LED as well + Wii.disconnect(); } } } diff --git a/keywords.txt b/keywords.txt index ade71b28..f4e19cd1 100644 --- a/keywords.txt +++ b/keywords.txt @@ -282,6 +282,9 @@ PAIR KEYWORD2 statusRequest KEYWORD2 getBatteryLevel KEYWORD2 getWiiState KEYWORD2 +getWeight KEYWORD2 +getTotalWeight KEYWORD2 +getWeightRaw KEYWORD2 #################################################### # Constants and enums (LITERAL1) @@ -300,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 From d2511df4a190d5c9b43d761a01ac4a6fa4ba54d1 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Thu, 16 Apr 2015 17:00:07 +0200 Subject: [PATCH 07/14] Move functions into .cpp file --- Wii.cpp | 29 ++++++++++++++++++++++++++--- Wii.h | 20 ++------------------ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/Wii.cpp b/Wii.cpp index d7b0b8c0..72c26113 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -880,8 +880,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 @@ -982,8 +982,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) @@ -1077,7 +1077,6 @@ void WII::calibrateWiiBalanceBoard() { /************************************************************/ /* WII Commands */ - /************************************************************/ bool WII::getButtonPress(ButtonEnum b) { // Return true when a button is pressed @@ -1129,6 +1128,30 @@ void WII::onInit() { setLedStatus(); } +/************************************************************/ +/* Wii Balance Board Commands */ +/************************************************************/ + +float WII::getWeight(BalanceBoardEnum pos) { + // Based on: https://github.com/skorokithakis/gr8w8upd8m8/blob/master/gr8w8upd8m8.py + // calibration[pos][0] is calibration values for 0 kg + // calibration[pos][1] is calibration values for 17 kg + // calibration[pos][2] is calibration values for 34 kg + float val = 0; + if(balanceBoardRaw[pos] < balanceBoardCal[0][pos]) + return val; + else if(balanceBoardRaw[pos] < balanceBoardCal[1][pos]) + val = 17 * ((balanceBoardRaw[pos] - balanceBoardCal[0][pos]) / float((balanceBoardCal[1][pos] - balanceBoardCal[0][pos]))); + else if(balanceBoardRaw[pos] > balanceBoardCal[1][pos]) + val = 17 + 17 * ((balanceBoardRaw[pos] - balanceBoardCal[1][pos]) / float((balanceBoardCal[2][pos] - balanceBoardCal[1][pos]))); + + return val; +}; + +float WII::getTotalWeight() { + return getWeight(TopRight) + getWeight(BotRight) + getWeight(TopLeft) + getWeight(BotLeft); +}; + /************************************************************/ /* The following functions are for the IR camera */ /************************************************************/ diff --git a/Wii.h b/Wii.h index 91026469..3922aca8 100755 --- a/Wii.h +++ b/Wii.h @@ -278,29 +278,13 @@ public: * @param ::BalanceBoardEnum to read from. * @return Returns the weight in kg. */ - float getWeight(BalanceBoardEnum pos) { - // Based on: https://github.com/skorokithakis/gr8w8upd8m8/blob/master/gr8w8upd8m8.py - // calibration[pos][0] is calibration values for 0 kg - // calibration[pos][1] is calibration values for 17 kg - // calibration[pos][2] is calibration values for 34 kg - float val = 0; - if(balanceBoardRaw[pos] < balanceBoardCal[0][pos]) - return val; - else if(balanceBoardRaw[pos] < balanceBoardCal[1][pos]) - val = 17 * ((balanceBoardRaw[pos] - balanceBoardCal[0][pos]) / float((balanceBoardCal[1][pos] - balanceBoardCal[0][pos]))); - else if(balanceBoardRaw[pos] > balanceBoardCal[1][pos]) - val = 17 + 17 * ((balanceBoardRaw[pos] - balanceBoardCal[1][pos]) / float((balanceBoardCal[2][pos] - balanceBoardCal[1][pos]))); - - return val; - }; + float getWeight(BalanceBoardEnum pos); /** * Used to get total weight on the Wii Balance Board. * @returnReturns the weight in kg. */ - float getTotalWeight() { - return getWeight(TopRight) + getWeight(BotRight) + getWeight(TopLeft) + getWeight(BotLeft); - }; + float getTotalWeight(); /** * Used to get the raw reading at the specific position on the Wii Balance Board. From 7334f7e9a4667e35327342f6fe32989f08392b7e Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Thu, 16 Apr 2015 19:45:03 +0200 Subject: [PATCH 08/14] Changed some variable names and simplified the way the weight is calculated There was actually a bug, as it will return 0 if wiiBalanceBoardRaw[pos] is exactly the same as wiiBalanceBoardCal[1][pos] --- Wii.cpp | 35 ++++++++++++++++------------------- Wii.h | 6 +++--- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/Wii.cpp b/Wii.cpp index 72c26113..f8d7186d 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -399,11 +399,11 @@ void WII::ACLData(uint8_t* l2capinbuf) { 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++) - balanceBoardCal[i][j] = l2capinbuf[16 + 8 * i + 2 * j] | l2capinbuf[15 + 8 * i + 2 * j] << 8; + 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++) - balanceBoardCal[2][j] = l2capinbuf[16 + 2 * j] | l2capinbuf[15 + 2 * j] << 8; + wiiBalanceBoardCal[2][j] = l2capinbuf[16 + 2 * j] | l2capinbuf[15 + 2 * j] << 8; #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nWii Balance Board calibrated successfully"), 0x80); #endif @@ -444,10 +444,10 @@ void WII::ACLData(uint8_t* l2capinbuf) { 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 - balanceBoardRaw[TopRight] = l2capinbuf[13] | l2capinbuf[12] << 8; // Top right - balanceBoardRaw[BotRight] = l2capinbuf[15] | l2capinbuf[14] << 8; // Bottom right - balanceBoardRaw[TopLeft] = l2capinbuf[17] | l2capinbuf[16] << 8; // Top left - balanceBoardRaw[BotLeft] = l2capinbuf[19] | l2capinbuf[18] << 8; // Bottom left + 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 @@ -1133,19 +1133,16 @@ void WII::onInit() { /************************************************************/ float WII::getWeight(BalanceBoardEnum pos) { - // Based on: https://github.com/skorokithakis/gr8w8upd8m8/blob/master/gr8w8upd8m8.py - // calibration[pos][0] is calibration values for 0 kg - // calibration[pos][1] is calibration values for 17 kg - // calibration[pos][2] is calibration values for 34 kg - float val = 0; - if(balanceBoardRaw[pos] < balanceBoardCal[0][pos]) - return val; - else if(balanceBoardRaw[pos] < balanceBoardCal[1][pos]) - val = 17 * ((balanceBoardRaw[pos] - balanceBoardCal[0][pos]) / float((balanceBoardCal[1][pos] - balanceBoardCal[0][pos]))); - else if(balanceBoardRaw[pos] > balanceBoardCal[1][pos]) - val = 17 + 17 * ((balanceBoardRaw[pos] - balanceBoardCal[1][pos]) / float((balanceBoardCal[2][pos] - balanceBoardCal[1][pos]))); - - return val; + // 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() { diff --git a/Wii.h b/Wii.h index 3922aca8..3cf4edc0 100755 --- a/Wii.h +++ b/Wii.h @@ -292,7 +292,7 @@ public: * @return Returns the raw reading. */ uint16_t getWeightRaw(BalanceBoardEnum pos) { - return balanceBoardRaw[pos]; + return wiiBalanceBoardRaw[pos]; }; /** Indicates when the calibration of the Wii Balance Board is done. */ @@ -481,8 +481,8 @@ private: void activateMotionPlus(); void calibrateWiiBalanceBoard(); - uint16_t balanceBoardRaw[4]; // Wii Balance Board raw values - uint16_t balanceBoardCal[3][4]; // Wii Balance Board calibration values + 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 From 9426e4192d2dc89801f7f5a0c25cd527dc435db6 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Thu, 16 Apr 2015 20:19:33 +0200 Subject: [PATCH 09/14] Updated some variables names and updated some debug messages --- Wii.cpp | 15 ++++++++------- Wii.h | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Wii.cpp b/Wii.cpp index f8d7186d..189bdcd3 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -264,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)); @@ -332,10 +332,11 @@ void WII::ACLData(uint8_t* l2capinbuf) { setReportMode(false, 0x31); // If there is no extension connected we will read the buttons and accelerometer } } -#ifdef DEBUG_USB_HOST +#ifdef EXTRADEBUG else Notify(PSTR("\r\nChecking battery level"), 0x80); - +#endif +#ifdef DEBUG_USB_HOST if(l2capinbuf[12] & 0x01) Notify(PSTR("\r\nWARNING: Battery is nearly empty"), 0x80); #endif @@ -405,7 +406,7 @@ void WII::ACLData(uint8_t* l2capinbuf) { 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 calibrated successfully"), 0x80); + Notify(PSTR("\r\nWii Balance Board calibration values read successfully"), 0x80); #endif wiiBalanceBoardCalibrationComplete = true; } @@ -793,9 +794,9 @@ void WII::Run() { } else if(stateCounter == 400) { if(wiiBalanceBoardConnected) { #ifdef DEBUG_USB_HOST - Notify(PSTR("\r\nCalibrating Wii Balance Board"), 0x80); + Notify(PSTR("\r\nReading Wii Balance Board calibration values"), 0x80); #endif - calibrateWiiBalanceBoard(); + readWiiBalanceBoardCalibration(); } else stateCounter = 499; } else if(stateCounter == 500) { @@ -1071,7 +1072,7 @@ void WII::checkMotionPresent() { readData(0xA600FA, 6, false); } -void WII::calibrateWiiBalanceBoard() { +void WII::readWiiBalanceBoardCalibration() { readData(0xA40024, 24, false); } diff --git a/Wii.h b/Wii.h index 3cf4edc0..2a3b5a3e 100755 --- a/Wii.h +++ b/Wii.h @@ -475,11 +475,11 @@ 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(); - void calibrateWiiBalanceBoard(); uint16_t wiiBalanceBoardRaw[4]; // Wii Balance Board raw values uint16_t wiiBalanceBoardCal[3][4]; // Wii Balance Board calibration values From 2ebc8129a748ce1f48c26ccede0418775117188a Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Thu, 16 Apr 2015 20:20:27 +0200 Subject: [PATCH 10/14] Show users how to easily save a lot of program space if extensions are not used --- Wii.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Wii.cpp b/Wii.cpp index 189bdcd3..d4b36381 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -494,6 +494,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 @@ -597,6 +598,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: From c44a80534b0dc0f2ba5a979c921a88a77dd7f455 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Thu, 16 Apr 2015 20:31:23 +0200 Subject: [PATCH 11/14] Added missing keyword --- keywords.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/keywords.txt b/keywords.txt index f4e19cd1..dff01c2a 100644 --- a/keywords.txt +++ b/keywords.txt @@ -270,6 +270,7 @@ nunchuckConnected KEYWORD2 motionPlusConnected KEYWORD2 wiiUProControllerConnected KEYWORD2 wiiBalanceBoardConnected KEYWORD2 +wiiBalanceBoardCalibrationComplete KEYWORD2 setRumbleToggle KEYWORD2 getPitch KEYWORD2 getRoll KEYWORD2 From 11f80275a5e7abedf6f2d3eadbd4bc65bca1d3c6 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Thu, 16 Apr 2015 22:08:33 +0200 Subject: [PATCH 12/14] Added information about Arduino Library Manager --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 60877437..864516e9 100644 --- a/README.md +++ b/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: . + +### Manual installation + First download the library by clicking on the following link: . 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. From e4c581c99153d7ef6af49577ba903ed00e60942a Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Mon, 20 Apr 2015 23:39:57 +0200 Subject: [PATCH 13/14] The is no need for Wii calibration flag to have its own variable --- Wii.cpp | 8 ++++---- Wii.h | 8 +++----- examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino | 2 +- keywords.txt | 1 - 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/Wii.cpp b/Wii.cpp index d4b36381..aef7613a 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -393,8 +393,7 @@ void WII::ACLData(uint8_t* l2capinbuf) { Notify(PSTR("\r\nWii Balance Board connected"), 0x80); #endif setReportMode(false, 0x32); // Read the Wii Balance Board extension - wiiBalanceBoardCalibrationComplete = false; - wiiBalanceBoardConnected = true; + 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 @@ -408,7 +407,8 @@ void WII::ACLData(uint8_t* l2capinbuf) { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nWii Balance Board calibration values read successfully"), 0x80); #endif - wiiBalanceBoardCalibrationComplete = true; + wii_clear_flag(WII_FLAG_CALIBRATE_BALANCE_BOARD); + wiiBalanceBoardConnected = true; } #ifdef DEBUG_USB_HOST else { @@ -794,7 +794,7 @@ void WII::Run() { readExtensionType(); unknownExtensionConnected = false; } else if(stateCounter == 400) { - if(wiiBalanceBoardConnected) { + if(wii_check_flag(WII_FLAG_CALIBRATE_BALANCE_BOARD)) { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nReading Wii Balance Board calibration values"), 0x80); #endif diff --git a/Wii.h b/Wii.h index 2a3b5a3e..960f2273 100755 --- a/Wii.h +++ b/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)) @@ -294,9 +295,6 @@ public: uint16_t getWeightRaw(BalanceBoardEnum pos) { return wiiBalanceBoardRaw[pos]; }; - - /** Indicates when the calibration of the Wii Balance Board is done. */ - bool wiiBalanceBoardCalibrationComplete; /**@}*/ #ifdef WIICAMERA diff --git a/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino b/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino index 6186a179..18c5b411 100644 --- a/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino +++ b/examples/Bluetooth/WiiBalanceBoard/WiiBalanceBoard.ino @@ -34,7 +34,7 @@ void setup() { } void loop() { Usb.Task(); - if (Wii.wiiBalanceBoardConnected && Wii.wiiBalanceBoardCalibrationComplete) { + if (Wii.wiiBalanceBoardConnected) { Serial.print(F("\r\nWeight: ")); for (uint8_t i = 0; i < 4; i++) { Serial.print(Wii.getWeight((BalanceBoardEnum)i)); diff --git a/keywords.txt b/keywords.txt index dff01c2a..f4e19cd1 100644 --- a/keywords.txt +++ b/keywords.txt @@ -270,7 +270,6 @@ nunchuckConnected KEYWORD2 motionPlusConnected KEYWORD2 wiiUProControllerConnected KEYWORD2 wiiBalanceBoardConnected KEYWORD2 -wiiBalanceBoardCalibrationComplete KEYWORD2 setRumbleToggle KEYWORD2 getPitch KEYWORD2 getRoll KEYWORD2 From b3303d14fc9594efa3b2d538c29ce38da9bb1056 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Mon, 20 Apr 2015 23:40:34 +0200 Subject: [PATCH 14/14] Set checkBatteryLevel false only when it was actually true --- Wii.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Wii.cpp b/Wii.cpp index aef7613a..4bbf4c91 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -332,16 +332,17 @@ void WII::ACLData(uint8_t* l2capinbuf) { setReportMode(false, 0x31); // If there is no extension connected we will read the buttons and accelerometer } } + else { #ifdef EXTRADEBUG - else 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 - checkBatteryLevel = false; // Check for extensions by default break; case 0x21: // Read Memory Data if((l2capinbuf[12] & 0x0F) == 0) { // No error