Added support for the Nunchuck controller

This commit is contained in:
Kristian Lauszus 2012-08-22 23:41:38 +02:00
parent d4d196b65a
commit c138bf0492
5 changed files with 337 additions and 182 deletions

240
Wii.cpp
View file

@ -18,7 +18,7 @@
#include "Wii.h" #include "Wii.h"
#define DEBUG // Uncomment to print data for debugging #define DEBUG // Uncomment to print data for debugging
//#define EXTRADEBUG // Uncomment to get even more debugging data //#define EXTRADEBUG // Uncomment to get even more debugging data
//#define PRINTREPORT // Uncomment to print the report send by the Wiimote //#define PRINTREPORT // Uncomment to print the report send by the Wii controllers
WII::WII(BTD *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0): WII::WII(BTD *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0):
pBtd(p) // pointer to USB class instance - mandatory pBtd(p) // pointer to USB class instance - mandatory
@ -44,7 +44,8 @@ pBtd(p) // pointer to USB class instance - mandatory
Reset(); Reset();
} }
void WII::Reset() { void WII::Reset() {
connected = false; wiimoteConnected = false;
nunchuckConnected = false;
l2cap_event_flag = 0; // Reset flags l2cap_event_flag = 0; // Reset flags
l2cap_state = L2CAP_WAIT; l2cap_state = L2CAP_WAIT;
} }
@ -122,7 +123,8 @@ void WII::ACLData(uint8_t* l2capinbuf) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nDisconnect Request: Control Channel")); Notify(PSTR("\r\nDisconnect Request: Control Channel"));
#endif #endif
connected = false; wiimoteConnected = false;
nunchuckConnected = false;
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
pBtd->l2cap_disconnection_response(hci_handle,identifier,control_dcid,control_scid); pBtd->l2cap_disconnection_response(hci_handle,identifier,control_dcid,control_scid);
Reset(); Reset();
@ -131,7 +133,8 @@ void WII::ACLData(uint8_t* l2capinbuf) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nDisconnect Request: Interrupt Channel")); Notify(PSTR("\r\nDisconnect Request: Interrupt Channel"));
#endif #endif
connected = false; wiimoteConnected = false;
nunchuckConnected = false;
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
pBtd->l2cap_disconnection_response(hci_handle,identifier,interrupt_dcid,interrupt_scid); pBtd->l2cap_disconnection_response(hci_handle,identifier,interrupt_dcid,interrupt_scid);
Reset(); Reset();
@ -158,38 +161,26 @@ void WII::ACLData(uint8_t* l2capinbuf) {
#endif #endif
} else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) { // l2cap_interrupt } else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) { // l2cap_interrupt
//Serial.print("\r\nL2CAP Interrupt"); //Serial.print("\r\nL2CAP Interrupt");
if(connected) { if(wiimoteConnected) {
/* Read Report */
if(l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT if(l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
if(l2capinbuf[9] >= 0x30 && l2capinbuf[9] <= 0x37) { // These reports include the buttons if(l2capinbuf[9] >= 0x30 && l2capinbuf[9] <= 0x37) { // These reports include the buttons
ButtonState = (uint16_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8)); if(nunchuckConnected)
ButtonClickState = ButtonState; // Update click state variable ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)(l2capinbuf[20] & 0x03) << 16));
else
ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8));
#ifdef PRINTREPORT #ifdef PRINTREPORT
Notify(PSTR("ButtonState: ")); Notify(PSTR("ButtonState: "));
PrintHex<uint16_t>(ButtonState); PrintHex<uint32_t>(ButtonState);
Notify(PSTR("\r\n")); Notify(PSTR("\r\n"));
#endif #endif
if(ButtonState != OldButtonState) { if(ButtonState != OldButtonState)
buttonChanged = true; ButtonClickState = ButtonState; // Update click state variable
if(ButtonState != 0x0000) {
buttonPressed = true;
buttonReleased = false;
} else {
buttonPressed = false;
buttonReleased = true;
}
}
else {
buttonChanged = false;
buttonPressed = false;
buttonReleased = false;
}
OldButtonState = ButtonState; OldButtonState = ButtonState;
} }
if(l2capinbuf[9] == 0x31 || l2capinbuf[9] == 0x35) { // Read the accelerometer if(l2capinbuf[9] == 0x31 || l2capinbuf[9] == 0x35) { // Read the accelerometer
int16_t accX = ((l2capinbuf[12] << 2) | (l2capinbuf[10] & 0x60 >> 5))-500; accX = ((l2capinbuf[12] << 2) | (l2capinbuf[10] & 0x60 >> 5))-500;
int16_t accY = ((l2capinbuf[13] << 2) | (l2capinbuf[11] & 0x20 >> 4))-500; accY = ((l2capinbuf[13] << 2) | (l2capinbuf[11] & 0x20 >> 4))-500;
int16_t accZ = ((l2capinbuf[14] << 2) | (l2capinbuf[11] & 0x40 >> 5))-500; accZ = ((l2capinbuf[14] << 2) | (l2capinbuf[11] & 0x40 >> 5))-500;
/* /*
Notify(PSTR("\r\naccX: ")); Notify(PSTR("\r\naccX: "));
Serial.print(accX); Serial.print(accX);
@ -200,20 +191,60 @@ void WII::ACLData(uint8_t* l2capinbuf) {
*/ */
pitch = (atan2(accY,accZ)+PI)*RAD_TO_DEG; pitch = (atan2(accY,accZ)+PI)*RAD_TO_DEG;
roll = (atan2(accX,accZ)+PI)*RAD_TO_DEG; roll = (atan2(accX,accZ)+PI)*RAD_TO_DEG;
/*
Notify(PSTR("\r\nPitch: "));
Serial.print(pitch);
Notify(PSTR("\tRoll: "));
Serial.print(roll);
*/
} }
switch (l2capinbuf[9]) { switch (l2capinbuf[9]) {
case 0x20: // Status Information case 0x20: // Status Information
// (a1) 20 BB BB LF 00 00 VV // (a1) 20 BB BB LF 00 00 VV
if(l2capinbuf[12] & 0x02) // Check if a extension is connected if(l2capinbuf[12] & 0x02) { // Check if a extension is connected
#ifdef DEBUG
Notify(PSTR("\r\nExtension connected"));
#endif
setReportMode(false,0x35); // Also read the extension setReportMode(false,0x35); // Also read the extension
else activateState = 1;
}
else {
#ifdef DEBUG
Notify(PSTR("\r\nExtension disconnected"));
#endif
nunchuckConnected = false;
setReportMode(false,0x31); // If there is no extension connected we will read the button and accelerometer setReportMode(false,0x31); // If there is no extension connected we will read the button and accelerometer
}
break;
case 0x21: // Read Memory Data
if((l2capinbuf[12] & 0x0F) == 0) { // No error
#ifdef EXTRADEBUG
Notify(PSTR("\r\nGot report: "));
PrintHex<uint8_t>(l2capinbuf[13]);
PrintHex<uint8_t>(l2capinbuf[14]);
Notify(PSTR("\r\nData: "));
for(uint8_t i = 0; i < ((l2capinbuf[12] >> 4)+1); i++) // bit 4-7 is the length-1
PrintHex<uint8_t>(l2capinbuf[15+i]);
#endif
if(l2capinbuf[15] == 0x00 && l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x00) { // See // http://wiibrew.org/wiki/Wiimote/Extension_Controllers
#ifdef DEBUG
Notify(PSTR("\r\nNunchuck connected"));
#endif
nunchuckConnected = true;
ButtonState |= (Z | C); // Since the Nunchuck button are cleared when pressed we set the buttonstates like so
ButtonClickState |= (Z | C);
}
}
#ifdef DEBUG
else {
Notify(PSTR("\r\nReport Error: "));
PrintHex<uint8_t>(l2capinbuf[13]);
PrintHex<uint8_t>(l2capinbuf[14]);
}
#endif
break;
case 0x22: // Acknowledge output report, return function result
#ifdef DEBUG
if(l2capinbuf[13] != 0x00) { // Check if there is an error
Notify(PSTR("\r\nCommand failed: "));
PrintHex<uint8_t>(l2capinbuf[12]);
} else if(l2capinbuf[12] == 0x16 && activateState > 20)
Notify(PSTR("\r\nExtension activated"));
#endif
break; break;
case 0x30: // Core buttons case 0x30: // Core buttons
// (a1) 30 BB BB // (a1) 30 BB BB
@ -223,33 +254,40 @@ void WII::ACLData(uint8_t* l2capinbuf) {
break; break;
case 0x32: // Core Buttons with 8 Extension bytes case 0x32: // Core Buttons with 8 Extension bytes
// (a1) 32 BB BB EE EE EE EE EE EE EE EE // (a1) 32 BB BB EE EE EE EE EE EE EE EE
/*
Notify(PSTR("\r\n"));
for (uint8_t i = 0; i < 8; i++) {
Serial.print(l2capinbuf[12+i]);
Notify(PSTR(" "));
}
*/
break; break;
case 0x34: // Core Buttons with 19 Extension bytes case 0x34: // Core Buttons with 19 Extension bytes
// (a1) 34 BB BB EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE // (a1) 34 BB BB EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
/*
Notify(PSTR("\r\n"));
for (uint8_t i = 0; i < 19; i++) {
Serial.print(l2capinbuf[12+i]);
Notify(PSTR(" "));
}
*/
break; break;
case 0x35: // Core Buttons and Accelerometer with 16 Extension Bytes 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 // (a1) 35 BB BB AA AA AA EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
if(activateState == 10) {
activateExtension1();
activateState = 11;
} else if(activateState == 20) {
activateExtension2();
activateState = 21;
} else if(activateState == 30) {
readExtensionType();
activateState = 31;
} else if(activateState < 31)
activateState++; // We make this counter as there has to be a short delay between the commands
hatValues[0] = l2capinbuf[15];
hatValues[1] = l2capinbuf[16];
accX = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x0C >> 2))-416;
accY = ((l2capinbuf[18] << 2) | (l2capinbuf[20] & 0x30 >> 4))-416;
accZ = ((l2capinbuf[19] << 2) | (l2capinbuf[20] & 0xC0 >> 6))-416;
/* /*
Notify(PSTR("\r\n")); Notify(PSTR("\r\naccX: "));
for (uint8_t i = 0; i < 16; i++) { Serial.print(accX);
Serial.print(l2capinbuf[15+i]); Notify(PSTR("\taccY: "));
Notify(PSTR(" ")); Serial.print(accY);
} Notify(PSTR("\taccZ: "));
Serial.print(accZ);
*/ */
nunchuckPitch = (atan2(accY,accZ)+PI)*RAD_TO_DEG;
nunchuckRoll = (atan2(accX,accZ)+PI)*RAD_TO_DEG;
break; break;
#ifdef DEBUG #ifdef DEBUG
default: default:
@ -311,7 +349,7 @@ void WII::L2CAP_task() {
break; break;
case L2CAP_WII_STATUS_STATE: case L2CAP_WII_STATUS_STATE:
connected = true; wiimoteConnected = true;
pBtd->connectToWii = false; pBtd->connectToWii = false;
ButtonState = 0; ButtonState = 0;
OldButtonState = 0; OldButtonState = 0;
@ -376,21 +414,25 @@ void WII::HID_Command(uint8_t* data, uint8_t nbytes) {
void WII::setAllOff() { void WII::setAllOff() {
HIDBuffer[1] = 0x11; HIDBuffer[1] = 0x11;
HIDBuffer[2] = 0x00; HIDBuffer[2] = 0x00;
rumbleBit = 0x00;
HID_Command(HIDBuffer, 3); HID_Command(HIDBuffer, 3);
} }
void WII::setRumbleOff() { void WII::setRumbleOff() {
HIDBuffer[1] = 0x11; HIDBuffer[1] = 0x11;
HIDBuffer[2] &= ~0x01; // Bit 0 control the rumble HIDBuffer[2] &= ~0x01; // Bit 0 control the rumble
rumbleBit = 0x00;
HID_Command(HIDBuffer, 3); HID_Command(HIDBuffer, 3);
} }
void WII::setRumbleOn() { void WII::setRumbleOn() {
HIDBuffer[1] = 0x11; HIDBuffer[1] = 0x11;
HIDBuffer[2] |= 0x01; // Bit 0 control the rumble HIDBuffer[2] |= 0x01; // Bit 0 control the rumble
rumbleBit = 0x01;
HID_Command(HIDBuffer, 3); HID_Command(HIDBuffer, 3);
} }
void WII::setRumbleToggle() { void WII::setRumbleToggle() {
HIDBuffer[1] = 0x11; HIDBuffer[1] = 0x11;
HIDBuffer[2] ^= 0x01; // Bit 0 control the rumble HIDBuffer[2] ^= 0x01; // Bit 0 control the rumble
rumbleBit ^= rumbleBit;
HID_Command(HIDBuffer, 3); HID_Command(HIDBuffer, 3);
} }
void WII::setLedOff(LED a) { void WII::setLedOff(LED a) {
@ -413,9 +455,9 @@ void WII::setReportMode(bool continuous, uint8_t mode) {
cmd_buf[0] = 0xA2; // HID BT DATA_request (0x50) | Report Type (Output 0x02) cmd_buf[0] = 0xA2; // HID BT DATA_request (0x50) | Report Type (Output 0x02)
cmd_buf[1] = 0x12; cmd_buf[1] = 0x12;
if(continuous) if(continuous)
cmd_buf[2] = 0x04; cmd_buf[2] = 0x04 | rumbleBit;
else else
cmd_buf[2] = 0x00; cmd_buf[2] = 0x00 | rumbleBit;
cmd_buf[3] = mode; cmd_buf[3] = mode;
HID_Command(cmd_buf, 4); HID_Command(cmd_buf, 4);
} }
@ -423,22 +465,90 @@ void WII::statusRequest() {
uint8_t cmd_buf[3]; uint8_t cmd_buf[3];
cmd_buf[0] = 0xA2; // HID BT DATA_request (0x50) | Report Type (Output 0x02) cmd_buf[0] = 0xA2; // HID BT DATA_request (0x50) | Report Type (Output 0x02)
cmd_buf[1] = 0x15; cmd_buf[1] = 0x15;
cmd_buf[2] = 0x00; cmd_buf[2] = rumbleBit;
HID_Command(cmd_buf, 3); HID_Command(cmd_buf, 3);
} }
/************************************************************/
/* 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 (0x50) | Report Type (Output 0x02)
cmd_buf[1] = 0x16; // Write data
cmd_buf[2] = 0x04 | rumbleBit; // Write to memory, clear bit 2 to write to EEPROM
cmd_buf[3] = (uint8_t)((offset & 0xFF0000) >> 16);
cmd_buf[4] = (uint8_t)((offset & 0xFF00) >> 8);
cmd_buf[5] = (uint8_t)(offset & 0xFF);
cmd_buf[6] = size;
uint8_t i = 0;
for(; i < size; i++)
cmd_buf[7+i] = data[i];
for(; i < 16; i++) // Set the rest to zero
cmd_buf[7+i] = 0x00;
HID_Command(cmd_buf,23);
}
void WII::activateExtension1() {
uint8_t buf[1];
buf[0] = 0x55;
writeData(0xA400F0,1,buf);
}
void WII::activateExtension2() {
uint8_t buf[1];
buf[0] = 0x00;
writeData(0xA400FB,1,buf);
}
void WII::readData(uint32_t offset, uint16_t size, bool EEPROM) {
uint8_t cmd_buf[8];
cmd_buf[0] = 0xA2; // HID BT DATA_request (0x50) | Report Type (Output 0x02)
cmd_buf[1] = 0x17; // Read data
if(EEPROM)
cmd_buf[2] = 0x00 | rumbleBit; // Read from EEPROM
else
cmd_buf[2] = 0x04 | rumbleBit; // Read from memory
cmd_buf[3] = (uint8_t)((offset & 0xFF0000) >> 16);
cmd_buf[4] = (uint8_t)((offset & 0xFF00) >> 8);
cmd_buf[5] = (uint8_t)(offset & 0xFF);
cmd_buf[6] = (uint8_t)((size & 0xFF00) >> 8);
cmd_buf[7] = (uint8_t)(size & 0xFF);
HID_Command(cmd_buf,8);
}
void WII::readExtensionType() {
readData(0xA400FA,6,false);
}
void WII::readCalData() {
readData(0x0016,8,true);
}
/************************************************************/ /************************************************************/
/* WII Commands */ /* WII Commands */
/************************************************************/ /************************************************************/
bool WII::getButtonPress(Button b) { bool WII::getButtonPress(Button b) { // Return true when a button is pressed
if(ButtonState & (uint16_t)b) bool press = (ButtonState & (uint32_t)b);
return true; if(b == Z || b == C)
return !press; // The nunchuck buttons are cleared when pressed
else else
return false; return press;
} }
bool WII::getButtonClick(Button b) { bool WII::getButtonClick(Button b) { // Only return true when a button is clicked
bool click = ((ButtonClickState & (uint16_t)b) != 0); bool click = (ButtonClickState & (uint32_t)b);
ButtonClickState &= ~((uint16_t)b); // clear "click" event if(b == Z || b == C) {
click = !click; // The nunchuck buttons are cleared when pressed
ButtonClickState |= (uint32_t)b; // clear "click" event
} else
ButtonClickState &= ~((uint32_t)b); // clear "click" event
return click; return click;
} }
uint8_t WII::getAnalogHat(AnalogHat a) {
if(!nunchuckConnected)
return 127; // Center position
else {
uint8_t output = hatValues[(uint8_t)a];
if(output == 0xFF) // The joystick will only read 255 when the cable is unplugged, so we will just return the center position
return 127;
else
return output;
}
}

66
Wii.h
View file

@ -63,18 +63,25 @@ enum LED {
}; };
enum Button { enum Button {
LEFT = 0x0001, LEFT = 0x00001,
RIGHT = 0x0002, RIGHT = 0x00002,
DOWN = 0x0004, DOWN = 0x00004,
UP = 0x0008, UP = 0x00008,
PLUS = 0x0010, PLUS = 0x00010,
TWO = 0x0100, TWO = 0x00100,
ONE = 0x0200, ONE = 0x00200,
B = 0x0400, B = 0x00400,
A = 0x0800, A = 0x00800,
MINUS = 0x1000, MINUS = 0x01000,
HOME = 0x8000, HOME = 0x08000,
Z = 0x10000,
C = 0x20000,
};
enum AnalogHat {
HatX = 0,
HatY = 1,
}; };
class WII : public BluetoothService { class WII : public BluetoothService {
@ -89,6 +96,7 @@ public:
bool getButtonPress(Button b); // This will read true as long as the button is held down bool getButtonPress(Button b); // This will read true as long as the button is held down
bool getButtonClick(Button b); // This will only be true when the button is clicked the first time bool getButtonClick(Button b); // This will only be true when the button is clicked the first time
uint8_t getAnalogHat(AnalogHat a); // Used to read the joystick of the Nunchuck
/* /*
TODO: Enable support for Motion Plus TODO: Enable support for Motion Plus
int16_t getSensor(Sensor a); int16_t getSensor(Sensor a);
@ -96,6 +104,8 @@ public:
*/ */
double getPitch() { return pitch; }; double getPitch() { return pitch; };
double getRoll() { return roll; }; double getRoll() { return roll; };
double getNunchuckPitch() { return nunchuckPitch; };
double getNunchuckRoll() { return nunchuckRoll; };
void setAllOff(); // Turn both rumble and all LEDs off void setAllOff(); // Turn both rumble and all LEDs off
void setRumbleOff(); void setRumbleOff();
@ -104,13 +114,9 @@ public:
void setLedOff(LED a); void setLedOff(LED a);
void setLedOn(LED a); void setLedOn(LED a);
void setLedToggle(LED a); void setLedToggle(LED a);
void setReportMode(bool continuous, uint8_t mode);
void statusRequest();
bool connected;// Variable used to indicate if a Wiimote is connected bool wiimoteConnected; // Variable used to indicate if a Wiimote is connected
bool buttonChanged;//Indicate if a button has been changed bool nunchuckConnected; // Variable used to indicate if a Nunchuck controller is connected
bool buttonPressed;//Indicate if a button has been pressed
bool buttonReleased;//Indicate if a button has been released
private: private:
/* Mandatory members */ /* Mandatory members */
@ -125,9 +131,10 @@ private:
uint8_t l2cap_state; uint8_t l2cap_state;
uint16_t l2cap_event_flag;// l2cap flags of received bluetooth events uint16_t l2cap_event_flag;// l2cap flags of received bluetooth events
uint16_t ButtonState; uint32_t ButtonState;
uint16_t OldButtonState; uint32_t OldButtonState;
uint16_t ButtonClickState; uint32_t ButtonClickState;
uint8_t hatValues[2];
uint8_t HIDBuffer[3];// Used to store HID commands uint8_t HIDBuffer[3];// Used to store HID commands
@ -140,8 +147,27 @@ private:
/* HID Commands */ /* HID Commands */
void HID_Command(uint8_t* data, uint8_t nbytes); void HID_Command(uint8_t* data, uint8_t nbytes);
void setReportMode(bool continuous, uint8_t mode);
void statusRequest();
void writeData(uint32_t offset, uint8_t size, uint8_t* data);
void activateExtension1();
void activateExtension2();
void readData(uint32_t offset, uint16_t size, bool EEPROM);
void readExtensionType();
void readCalData();
uint8_t activateState;
uint8_t rumbleBit;
double pitch; double pitch;
double roll; double roll;
double nunchuckPitch;
double nunchuckRoll;
int16_t accX; // Accelerometer values used to calculate pitch and roll
int16_t accY;
int16_t accZ;
}; };
#endif #endif

View file

@ -0,0 +1,101 @@
/*
Example sketch for the Wiimote 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>
USB Usb;
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); // This will start inquiry which will connect to any Wiimote
//WII Wii(&Btd,0x00,0x26,0x59,0x48,0xFF,0xFB); // This will connect to the Wiimote with that specific Bluetooth Address
bool printAngle;
void setup() {
Serial.begin(115200);
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while(1); //halt
}
Serial.print(F("\r\nWiimote Bluetooth Library Started"));
}
void loop() {
Usb.Task();
if(Wii.wiimoteConnected) {
if(Wii.getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down
Serial.print(F("\r\nHOME"));
Wii.disconnect(); // If you disconnect you have to reset the Arduino to establish the connection again
}
else {
if(Wii.getButtonClick(LEFT)) {
Wii.setAllOff();
Wii.setLedOn(LED1);
Serial.print(F("\r\nLeft"));
}
if(Wii.getButtonClick(RIGHT)) {
Wii.setAllOff();
Wii.setLedOn(LED3);
Serial.print(F("\r\nRight"));
}
if(Wii.getButtonClick(DOWN)) {
Wii.setAllOff();
Wii.setLedOn(LED4);
Serial.print(F("\r\nDown"));
}
if(Wii.getButtonClick(UP)) {
Wii.setAllOff();
Wii.setLedOn(LED2);
Serial.print(F("\r\nUp"));
}
if(Wii.getButtonClick(PLUS)) {
Serial.print(F("\r\nPlus"));
}
if(Wii.getButtonClick(MINUS)) {
Serial.print(F("\r\nMinus"));
}
if(Wii.getButtonClick(ONE)) {
Serial.print(F("\r\nOne"));
}
if(Wii.getButtonClick(TWO)) {
Serial.print(F("\r\nTwo"));
}
if(Wii.getButtonClick(A)) {
printAngle = !printAngle;
Serial.print(F("\r\nA"));
}
if(Wii.getButtonClick(B)) {
Wii.setRumbleToggle();
Serial.print(F("\r\nB"));
}
}
if(printAngle) {
Serial.print(F("\r\nPitch: "));
Serial.print(Wii.getPitch());
Serial.print(F("\tRoll: "));
Serial.print(Wii.getRoll());
if(Wii.nunchuckConnected) {
Serial.print(F("\tNunchuck Pitch: "));
Serial.print(Wii.getNunchuckPitch());
Serial.print(F("\tNunchuck Roll: "));
Serial.print(Wii.getNunchuckRoll());
}
}
}
if(Wii.nunchuckConnected) {
if(Wii.getButtonClick(Z))
Serial.print(F("\r\nZ"));
if(Wii.getButtonClick(C))
Serial.print(F("\r\nC"));
if(Wii.getAnalogHat(HatX) > 137 || Wii.getAnalogHat(HatX) < 117 || Wii.getAnalogHat(HatY) > 137 || Wii.getAnalogHat(HatY) < 117) {
Serial.print(F("\r\nHatX: "));
Serial.print(Wii.getAnalogHat(HatX));
Serial.print(F("\tHatY: "));
Serial.print(Wii.getAnalogHat(HatY));
}
}
}

View file

@ -1,86 +0,0 @@
/*
Example sketch for the Wiimote 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>
USB Usb;
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); // This will start inquiry which will connect to any Wiimote
//WII Wii(&Btd,0x00,0x26,0x59,0x48,0xFF,0xFB); // This will connect to the Wiimote with that specific Bluetooth Address
bool printAngle;
void setup() {
Serial.begin(115200);
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while(1); //halt
}
Serial.print(F("\r\nWiimote Bluetooth Library Started"));
}
void loop() {
Usb.Task();
if(Wii.connected) {
if(Wii.buttonPressed) {
if(Wii.getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down
Serial.print(F("\r\nHOME"));
Wii.disconnect(); // If you disconnect you have to reset the Arduino to establish the connection again
}
else {
if(Wii.getButtonClick(LEFT)) {
Wii.setAllOff();
Wii.setLedOn(LED1);
Serial.print(F("\r\nLeft"));
}
if(Wii.getButtonClick(RIGHT)) {
Wii.setAllOff();
Wii.setLedOn(LED3);
Serial.print(F("\r\nRight"));
}
if(Wii.getButtonClick(DOWN)) {
Wii.setAllOff();
Wii.setLedOn(LED4);
Serial.print(F("\r\nDown"));
}
if(Wii.getButtonClick(UP)) {
Wii.setAllOff();
Wii.setLedOn(LED2);
Serial.print(F("\r\nUp"));
}
if(Wii.getButtonClick(PLUS)) {
Serial.print(F("\r\nPlus"));
}
if(Wii.getButtonClick(MINUS)) {
Serial.print(F("\r\nMinus"));
}
if(Wii.getButtonClick(ONE)) {
Serial.print(F("\r\nOne"));
}
if(Wii.getButtonClick(TWO)) {
Serial.print(F("\r\nTwo"));
}
if(Wii.getButtonClick(A)) {
printAngle = !printAngle;
Serial.print(F("\r\nA"));
}
if(Wii.getButtonClick(B)) {
Wii.setRumbleToggle();
Serial.print(F("\r\nB"));
}
}
}
if(printAngle) {
Serial.print(F("\r\nPitch: "));
Serial.print(Wii.getPitch());
Serial.print(F("\tRoll: "));
Serial.print(Wii.getRoll());
}
}
}

View file

@ -217,8 +217,12 @@ WII KEYWORD1
# Methods and Functions (KEYWORD2) # Methods and Functions (KEYWORD2)
#################################################### ####################################################
wiimoteConnected KEYWORD2
nunchuckConnected KEYWORD2
getButtonPress KEYWORD2 getButtonPress KEYWORD2
getButtonClick KEYWORD2 getButtonClick KEYWORD2
setRumbleToggle KEYWORD2 setRumbleToggle KEYWORD2
getNunchuckPitch KEYWORD2
getNunchuckRoll KEYWORD2
getPitch KEYWORD2 getPitch KEYWORD2
getRoll KEYWORD2 getRoll KEYWORD2