diff --git a/ESP32Wiimote.cpp b/ESP32Wiimote.cpp index b42b37c..a181edb 100644 --- a/ESP32Wiimote.cpp +++ b/ESP32Wiimote.cpp @@ -12,7 +12,7 @@ // Under the following terms: // NonCommercial — You may not use the material for commercial purposes. -#define CONFIG_CLASSIC_BT_ENABLED +//#define CONFIG_CLASSIC_BT_ENABLED 1 #include #include @@ -42,6 +42,9 @@ #define VERBOSE_PRINTLN(...) do {} while(0) #endif +//#define UNVERBOSE_PRINT(...) Serial.printf(__VA_ARGS__) +#define UNVERBOSE_PRINT(...) do {} while(0) + #define RX_QUEUE_SIZE 32 #define TX_QUEUE_SIZE 32 xQueueHandle ESP32Wiimote::rxQueue = NULL; @@ -53,11 +56,9 @@ const TwHciInterface ESP32Wiimote::tinywii_hci_interface = { esp_vhci_host_callback_t ESP32Wiimote::vhci_callback; -ESP32Wiimote::ESP32Wiimote(void) +ESP32Wiimote::ESP32Wiimote(int NUNCHUK_STICK_THRESHOLD) { - _pNunchukState = &_nunchukStateA; - _pOldNunchukState = &_nunchukStateB; - _nunStickThreshold = NUNCHUK_STICK_THRESHOLD * NUNCHUK_STICK_THRESHOLD; + _nunStickThreshold = NUNCHUK_STICK_THRESHOLD; _filter = FILTER_NONE; } @@ -89,7 +90,7 @@ void ESP32Wiimote::handleTxQueue(void) { queuedata_t *queuedata = NULL; if(xQueueReceive(txQueue, &queuedata, 0) == pdTRUE){ esp_vhci_host_send_packet(queuedata->data, queuedata->len); - VERBOSE_PRINT("SEND => %s", format2Hex(queuedata->data, queuedata->len)); + UNVERBOSE_PRINT("SEND => %s\n", format2Hex(queuedata->data, queuedata->len)); free(queuedata); } } @@ -119,6 +120,7 @@ esp_err_t ESP32Wiimote::sendQueueData(xQueueHandle queue, uint8_t *data, size_t } queuedata->len = len; memcpy(queuedata->data, data, len); + UNVERBOSE_PRINT("RECV <= %s\n", format2Hex(queuedata->data, queuedata->len)); if (xQueueSend(queue, &queuedata, portMAX_DELAY) != pdPASS) { VERBOSE_PRINTLN("xQueueSend failed"); free(queuedata); @@ -176,99 +178,170 @@ void ESP32Wiimote::task(void) int ESP32Wiimote::available(void) { - int stateIsAvailable = TinyWiimoteAvailable(); - if (stateIsAvailable) { - NunchukState *pTmpNunchuck; - - _gotData = TinyWiimoteRead(); - - // update old button state - _oldButtonState = _buttonState; - - // update button state - _buttonState = 0; - _buttonState = (_gotData.data[TWII_OFFSET_BTNS1] << 8) | _gotData.data[TWII_OFFSET_BTNS2]; - - // update old nunchuck state(= exchange nunchuk state area) - pTmpNunchuck = _pOldNunchukState; - _pOldNunchukState = _pNunchukState; - _pNunchukState = pTmpNunchuck; - - // update nunchuk state - _pNunchukState->xStick = _gotData.data[TWII_OFFSET_EXTCTRL + 0]; - _pNunchukState->yStick = _gotData.data[TWII_OFFSET_EXTCTRL + 1]; - _pNunchukState->xAxis = _gotData.data[TWII_OFFSET_EXTCTRL + 2]; - _pNunchukState->yAxis = _gotData.data[TWII_OFFSET_EXTCTRL + 3]; - _pNunchukState->zAxis = _gotData.data[TWII_OFFSET_EXTCTRL + 4]; - _pNunchukState->cBtn = ((_gotData.data[TWII_OFFSET_EXTCTRL + 5] & 0x02) >> 1) ^ 0x01; - _pNunchukState->zBtn = (_gotData.data[TWII_OFFSET_EXTCTRL + 5] & 0x01) ^ 0x01; - - // check button change - int buttonIsChanged = false; - if (_filter & FILTER_REMOTE_BUTTON) { - ; // ignore - } - else if (_buttonState != _oldButtonState) { - buttonIsChanged = true; - } + int offs = 0; + int buttonIsChanged = false; +// int nunchukButtonIsChanged = false; + int accelIsChanged = false; + int nunchukStickIsChanged = false; + uint8_t cBtn = 0; + uint8_t zBtn = 0; + + if (! TinyWiimoteAvailable()) + return 0; + + TinyWiimoteData rd = TinyWiimoteRead(); + + if (rd.len < 4) // + return 0; + if (rd.data[0] != 0xA1) // no data input + return 0; + + // update old states + _oldButtonState = _buttonState; + _oldAccelState = _accelState; + _oldNunchukState = _nunchukState; + + if ((rd.data[1] >= 0x30) && (rd.data[1] <= 0x37)) // data report with button data + offs = 2; + + if (offs) // update button state + _buttonState = (ButtonState)((rd.data[offs + 0] << 8) | rd.data[offs + 1]); + + // get accelerometer offset + switch (rd.data[1]) + { + case 0x31: offs = 4; break; // Core Buttons and Accelerometer + case 0x35: offs = 4; break; // Core Buttons and Accelerometer with 16 Extension Bytes + default: offs = 0; + } - // check nunchuk stick change - int nunchukStickIsChanged = false; - int nunXStickDelta = (int)(_pNunchukState->xStick) - _pOldNunchukState->xStick; - int nunYStickDelta = (int)(_pNunchukState->yStick) - _pOldNunchukState->yStick; - int nunStickDelta = (nunXStickDelta*nunXStickDelta + nunYStickDelta*nunYStickDelta) / 2; - if (_filter & FILTER_NUNCHUK_STICK) { - ; // ignore - } - else if (nunStickDelta >= _nunStickThreshold) { - nunchukStickIsChanged = true; - } + if (offs) // update accelerometer + { + _accelState.xAxis = rd.data[offs + 0]; + _accelState.yAxis = rd.data[offs + 1]; + _accelState.zAxis = rd.data[offs + 2]; + + // check accel change + if (_filter & FILTER_ACCEL) { + ; // ignore + } + else { + accelIsChanged = true; + } + } + else + { + _accelState.xAxis = 0; + _accelState.yAxis = 0; + _accelState.zAxis = 0; + } - // check nunchuk button change - int nunchukButtonIsChanged = false; - if (_filter & FILTER_NUNCHUK_BUTTON) { - ; // ignore - } - else if ( - (_pNunchukState->cBtn != _pOldNunchukState->cBtn) - || (_pNunchukState->zBtn != _pOldNunchukState->zBtn) - ) { - nunchukButtonIsChanged = true; - } + // get extension offset + switch (rd.data[1]) + { + case 0x32: offs = 4; break; // Core Buttons with 8 Extension bytes + case 0x35: offs = 7; break; // Core Buttons and Accelerometer with 16 Extension Bytes + default: offs = 0; + } + + if (offs) // update nunchuk state + { + _nunchukState.xStick = rd.data[offs + 0]; + _nunchukState.yStick = rd.data[offs + 1]; + _nunchukState.xAxis = rd.data[offs + 2]; + _nunchukState.yAxis = rd.data[offs + 3]; + _nunchukState.zAxis = rd.data[offs + 4]; + + // update nunchuk buttons + cBtn = ((rd.data[offs + 5] & 0x02) >> 1) ^ 0x01; + zBtn = (rd.data[offs + 5] & 0x01) ^ 0x01; + } + else + { + _nunchukState.xStick = 0; + _nunchukState.yStick = 0; + _nunchukState.xAxis = 0; + _nunchukState.yAxis = 0; + _nunchukState.zAxis = 0; + } + - // check accel change - int accelIsChanged = false; - if (_filter & FILTER_NUNCHUK_ACCEL) { + // add nunchuk buttons + if (cBtn) + _buttonState = (ButtonState)((int)_buttonState | BUTTON_C); + if (zBtn) + _buttonState = (ButtonState)((int)_buttonState | BUTTON_Z); + + // check button change + if (_filter & FILTER_BUTTON) { ; // ignore - } - else { - accelIsChanged = true; - } + } + else if (_buttonState != _oldButtonState) { + buttonIsChanged = true; + } - stateIsAvailable = + // check nunchuk stick change + if (offs) + { + int nunXStickDelta = (int)(_nunchukState.xStick) - _oldNunchukState.xStick; + int nunYStickDelta = (int)(_nunchukState.yStick) - _oldNunchukState.yStick; + int nunStickDelta = (nunXStickDelta*nunXStickDelta + nunYStickDelta*nunYStickDelta); + if (_filter & FILTER_NUNCHUK_STICK) { + ; // ignore + } + else if (nunStickDelta >= _nunStickThreshold) { + nunchukStickIsChanged = true; + } + +// // check nunchuk button change +// if (_filter & FILTER_NUNCHUK_BUTTON) { +// ; // ignore +// } +// else if ( +// (_pNunchukState->cBtn != _pOldNunchukState->cBtn) +// || (_pNunchukState->zBtn != _pOldNunchukState->zBtn) +// ) { +// nunchukButtonIsChanged = true; +// } + + // check accel change + if (_filter & FILTER_ACCEL) { + ; // ignore + } + else { + accelIsChanged = true; + } + } + + return ( buttonIsChanged | nunchukStickIsChanged - | nunchukButtonIsChanged +// | nunchukButtonIsChanged | accelIsChanged ); - - } - return stateIsAvailable; } -uint16_t ESP32Wiimote::getButtonState(void) +ButtonState ESP32Wiimote::getButtonState(void) { return _buttonState; } +AccelState ESP32Wiimote::getAccelState(void) +{ + return _accelState; +} + NunchukState ESP32Wiimote::getNunchukState(void) { - return *_pNunchukState; + return _nunchukState; } void ESP32Wiimote::addFilter(int action, int filter) { if (action == ACTION_IGNORE) { _filter = _filter | filter; + + if (filter & FILTER_ACCEL) + TinyWiimoteReqAccelerometer(false); } } diff --git a/ESP32Wiimote.h b/ESP32Wiimote.h index 820c913..936dda1 100644 --- a/ESP32Wiimote.h +++ b/ESP32Wiimote.h @@ -18,23 +18,47 @@ #include "esp_bt.h" #include "TinyWiimote.h" +typedef struct { + uint8_t xAxis; + uint8_t yAxis; + uint8_t zAxis; +} AccelState; + +typedef enum { + BUTTON_Z = 0x00020000, // nunchuk + BUTTON_C = 0x00010000, // nunchuk + BUTTON_PLUS = 0x00001000, + BUTTON_UP = 0x00000800, // vertical orientation + BUTTON_DOWN = 0x00000400, + BUTTON_RIGHT = 0x00000200, + BUTTON_LEFT = 0x00000100, + BUTTON_HOME = 0x00000080, + BUTTON_MINUS = 0x00000010, + BUTTON_A = 0x00000008, + BUTTON_B = 0x00000004, + BUTTON_ONE = 0x00000002, + BUTTON_TWO = 0x00000001, + NO_BUTTON = 0x00000000 +} ButtonState; + typedef struct { uint8_t xStick; uint8_t yStick; uint8_t xAxis; uint8_t yAxis; uint8_t zAxis; - uint8_t cBtn; - uint8_t zBtn; +// moved to ButtonState +// uint8_t cBtn; +// uint8_t zBtn; } NunchukState; enum { FILTER_NONE = 0x0000, - FILTER_REMOTE_BUTTON = 0x0001, - FILTER_NUNCHUK_BUTTON = 0x0002, + FILTER_BUTTON = 0x0001, +//FILTER_NUNCHUK_BUTTON = 0x0002, FILTER_NUNCHUK_STICK = 0x0004, - FILTER_NUNCHUK_ACCEL = 0x0008, + FILTER_ACCEL = 0x0008, }; enum @@ -45,29 +69,13 @@ enum class ESP32Wiimote { public: - enum - { - BUTTON_LEFT = 0x0800, - BUTTON_RIGHT = 0x0400, - BUTTON_UP = 0x0200, - BUTTON_DOWN = 0x0100, - BUTTON_A = 0x0008, - BUTTON_B = 0x0004, - BUTTON_PLUS = 0x1000, - BUTTON_HOME = 0x0080, - BUTTON_MINUS = 0x0010, - BUTTON_ONE = 0x0002, - BUTTON_TWO = 0x0001 - }; - - const int NUNCHUK_STICK_THRESHOLD = 2; - - ESP32Wiimote(void); + ESP32Wiimote(int NUNCHUK_STICK_THRESHOLD = 1); // was 2 void init(void); void task(void); int available(void); - uint16_t getButtonState(void); + ButtonState getButtonState(void); + AccelState getAccelState(void); NunchukState getNunchukState(void); void addFilter(int action, int filter); @@ -78,16 +86,14 @@ class ESP32Wiimote uint8_t data[]; } queuedata_t; - TinyWiimoteData _gotData; - - uint16_t _buttonState; - uint16_t _oldButtonState; + ButtonState _buttonState; + ButtonState _oldButtonState; - NunchukState *_pNunchukState; - NunchukState *_pOldNunchukState; + AccelState _accelState; + AccelState _oldAccelState; - NunchukState _nunchukStateA; - NunchukState _nunchukStateB; + NunchukState _nunchukState; + NunchukState _oldNunchukState; int _nunStickThreshold; diff --git a/README.md b/README.md index 7d92985..86cce06 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,22 @@ -# Arduino-ESP32Wiimote +# ESP32Wiimote -ESP32Wiimote is a Arduino library that connects with a Wii remote. +ESP32Wiimote is an Arduino library for ESP32 devices, that connects over Bluetooth with a Wii remote (Wiimote), and its optional connected Nunchuk. + +This fork has the following improvements: +- better output in example +- optional accelerometer read-out of Wiimote itself + +On the ESP32, it reports easily at 100Hz: +- all regular button presses (A/B/C/Z/1/2/-/Home/+/D-Pad) +- the 3-dimensional acceleration/orientation of both Wiimote and Nunchuk +- the analog joystick of the Nunchuk ## Requirement -- [ESP32 dev board](https://www.switch-science.com/catalog/3210/) -- Arduino IDE (Version: 1.8.5) +- ESP32 board (any) +- Arduino IDE (Version >= 1.8.5) - Wii Remote (RVL-CNT-01) +- Wii Nunchuk (optional) ## Installation 1. Download the zip file. @@ -16,95 +26,16 @@ ESP32Wiimote is a Arduino library that connects with a Wii remote. ## Examples -### Basic Example - -```ESP32WiimoteDemo.ino.cpp -#include "ESP32Wiimote.h" - -ESP32Wiimote wiimote; - -void setup() -{ - Serial.begin(115200); - wiimote.init(); -} - -void loop() -{ - wiimote.task(); - if (wiimote.available() > 0) { - uint16_t button = wiimote.getButtonState(); - Serial.printf("%04x\n", button); - if (button == ESP32Wiimote::BUTTON_A) { - Serial.println("A button"); - } - } - delay(10); -} - - -``` -### Example With Nunchuck - -```ESP32WiimoteDemo.ino.cpp -#include "ESP32Wiimote.h" +A full example can be found at [ESP32WiimoteDemo.ino](./examples/ESP32WiimoteDemo/ESP32WiimoteDemo.ino) -ESP32Wiimote wiimote; +- Caution: the accelerometers report a lot of data +- This can get filtered/prevented by using 'add filter(ACTION_IGNORE,...)' +- The reports from the analog joystick of the Nunchuk can als be configured for larger minimal steps -void setup() -{ - Serial.begin(115200); - wiimote.init(); - wiimote.addFilter(ACTION_IGNORE, FILTER_NUNCHUK_ACCEL); -} - -void loop() -{ - wiimote.task(); - if (wiimote.available() > 0) { - uint16_t button = wiimote.getButtonState(); - Serial.printf("%04x\n", button); - - NunchukState nunchuk = wiimote.getNunchukState(); - Serial.printf("nunchuk:"); - Serial.printf(" X-Stick: %d", nunchuk.xStick); - Serial.printf(" Y-Stick: %d", nunchuk.yStick); - Serial.printf(" X-Axis: %d", nunchuk.xAxis); - Serial.printf(" Y-Axis: %d", nunchuk.yAxis); - Serial.printf(" Z-Axis: %d", nunchuk.zAxis); - Serial.printf(" C-Button: %02x", nunchuk.cBtn); - Serial.printf(" Z-Button: %02x", nunchuk.zBtn); - Serial.printf("\n"); - } - delay(10); -} - -``` - -- Caution: Nunchuck keeps outputting a lot of data for acceleration sensing -- You can Ignore changes with 'add filter(ACTION_IGNORE,...)' - -#### Button Definition -'button' is expressed as OR of bits: - -``` - BUTTON_LEFT = 0x0800, - BUTTON_RIGHT = 0x0400, - BUTTON_UP = 0x0200, - BUTTON_DOWN = 0x0100, - BUTTON_A = 0x0008, - BUTTON_B = 0x0004, - BUTTON_PLUS = 0x1000, - BUTTON_HOME = 0x0080, - BUTTON_MINUS = 0x0010, - BUTTON_ONE = 0x0002, - BUTTON_TWO = 0x0001 -``` ## Usage - +No need to pair the controller over Bluetooth. Just do: 1. To connect, press the 1 and 2 buttons on Wii Remote - -1. The LED1 will be on when they have finished connecting +2. The LED1 will be on when they have finished connecting ## Licence diff --git a/TinyWiimote.cpp b/TinyWiimote.cpp index f06db73..c75b6d5 100644 --- a/TinyWiimote.cpp +++ b/TinyWiimote.cpp @@ -18,6 +18,7 @@ #include #include #include +#include // for Arduino #include "time.h" #include "sys/time.h" @@ -27,7 +28,6 @@ #define WIIMOTE_VERBOSE 0 #if WIIMOTE_VERBOSE -#include // for Arduino #define VERBOSE_PRINT(...) Serial.printf(__VA_ARGS__) #define VERBOSE_PRINTLN(...) Serial.println(__VA_ARGS__) #else @@ -35,6 +35,9 @@ #define VERBOSE_PRINTLN(...) do {} while(0) #endif +#define UNVERBOSE_PRINT(...) Serial.printf(__VA_ARGS__) +//#define UNVERBOSE_PRINT(...) do {} while(0) + #define HCI_H4_CMD_PREAMBLE_SIZE (4) #define HCI_H4_ACL_PREAMBLE_SIZE (5) @@ -119,6 +122,8 @@ enum { static bool deviceInited = false; static bool wiimoteConnected = false; +static bool nunchukConnected = false; +static bool useAccelerometer = true; /** * Command Maker @@ -244,7 +249,7 @@ static uint16_t make_acl_l2cap_packet(uint8_t *buf, uint16_t ch, uint8_t pbf, ui return HCI_H4_ACL_PREAMBLE_SIZE + l2capLen; } -TwHciInterface _hciInterface; +static TwHciInterface _hciInterface; static void sendHciPacket(uint8_t *data, size_t len) { VERBOSE_PRINTLN("sendHciPacket"); @@ -327,18 +332,13 @@ static void l2capClearConnection(void) { static uint8_t tmpQueueData[256]; static void resetDevice(void) { - VERBOSE_PRINTLN("resetDevice"); + UNVERBOSE_PRINT("resetDevice\n"); connected_device_clear(); l2capClearConnection(); uint16_t len = make_cmd_reset(tmpQueueData); sendHciPacket(tmpQueueData, len); } -void TinyWiimoteResetDevice(void) { - resetDevice(); - deviceInited = true; -} - /** * HCI Event Handler */ @@ -526,7 +526,7 @@ static void handleRemoteNameRequestCompleteEvent(uint8_t len, uint8_t* data) { } #define L2CAP_PAYLOAD_MAX_LEN (64) -uint8_t payload[L2CAP_PAYLOAD_MAX_LEN]; +static uint8_t payload[L2CAP_PAYLOAD_MAX_LEN]; static void l2capConnect(uint16_t ch, uint16_t psm, uint16_t cid) { uint8_t pbf = 0b10; // Packet Boundary Flag @@ -580,7 +580,9 @@ static void handleDisconnectionCompleteEvent(uint8_t len, uint8_t* data) { VERBOSE_PRINT("Connection_Handle = 0x%04X ", ch); VERBOSE_PRINT("Reason = %02X", reason); + UNVERBOSE_PRINT("Wiimote lost\n"); wiimoteConnected = false; + nunchukConnected = false; resetDevice(); } @@ -849,6 +851,7 @@ static void readingEEPROM(uint16_t ch, int as, uint32_t offset, uint16_t size) { } static void setDataReportingMode(uint16_t ch, uint8_t mode, bool continuous) { + UNVERBOSE_PRINT("setDataReportingMode 0x%02X (ch:%d)\n", (int)mode, (int)ch); int idx = l2capFindConnection(ch); struct l2cap_connection_t connection = l2capConnectionList[idx]; @@ -889,11 +892,16 @@ static void handleExtensionControllerReports(uint16_t ch, uint16_t channelID, ui // (a1) 20 BB BB LF 00 00 VV if(data[1] == 0x20){ if(data[4] & 0x02){ // extension controller is connected + UNVERBOSE_PRINT("Extension controller connected\n"); writingEEPROM(ch, CONTROL_REGISTER, 0xA400F0, (const uint8_t[]){0x55}, 1); controllerReportState = REPORT_STATE_WAIT_ACK_OUT_REPORT; }else{ // extension controller is NOT connected - setDataReportingMode(ch, 0x30, false); // 0x30: Core Buttons : 30 BB BB - // [note] Core Buttons and Accelerometer: 31 BB BB AA AA AA + UNVERBOSE_PRINT("Extension controller NOT connected\n"); + nunchukConnected = false; + if (useAccelerometer) + setDataReportingMode(ch, 0x31, false); // Core Buttons and Accelerometer: 31 BB BB AA AA AA + else + setDataReportingMode(ch, 0x30, false); // Core Buttons : 30 BB BB // [note] Core Buttons and Accelerometer with 12 IR bytes: 33 BB BB AA AA AA II II II II II II II II II II II II } } @@ -929,8 +937,13 @@ static void handleExtensionControllerReports(uint16_t ch, uint16_t channelID, ui // (a1) 21 BB BB SE FF FF DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD if(data[1] == 0x21){ if(memcmp(data+5, (const uint8_t[]){0x00, 0xFA}, 2) == 0){ - if(memcmp(data+7, (const uint8_t[]){0x00, 0x00, 0xA4, 0x20, 0x00, 0x00}, 6) == 0){ // Nunchuck - setDataReportingMode(ch, 0x32, false); // 0x32: Core Buttons with 8 Extension bytes : 32 BB BB EE EE EE EE EE EE EE EE + if(memcmp(data+7, (const uint8_t[]){0x00, 0x00, 0xA4, 0x20, 0x00, 0x00}, 6) == 0){ // Nunchuk + UNVERBOSE_PRINT("Nunchuk detected\n"); + nunchukConnected = true; + if (useAccelerometer) + setDataReportingMode(ch, 0x35, false); // Core Buttons and Accelerometer with 16 Extension bytes: 35 BB BB AA AA AA EE EE ... + else + setDataReportingMode(ch, 0x32, false); // Core Buttons with 8 Extension bytes : 32 BB BB EE EE EE EE EE EE EE EE } controllerReportState = REPORT_STATE_INIT; } @@ -948,9 +961,9 @@ struct recv_data_rb { uint8_t rp; uint8_t cnt; }; -recv_data_rb receivedDataRb; +static recv_data_rb receivedDataRb; #define RECIEVED_DATA_MAX_NUM (5) -TinyWiimoteData receivedData[RECIEVED_DATA_MAX_NUM]; +static TinyWiimoteData receivedData[RECIEVED_DATA_MAX_NUM]; void putWiimoteReceivedData(uint8_t number, uint8_t* data, uint8_t len) { if(receivedDataRb.cnt < RECIEVED_DATA_MAX_NUM) { @@ -990,7 +1003,10 @@ static void handleL2capData(uint16_t ch, uint16_t channelID, uint8_t* data, uint case BTCODE_HID: if(!wiimoteConnected){ setPlayerLEDs(ch, 0b0001); + UNVERBOSE_PRINT("Wiimote detected\n"); wiimoteConnected = true; + if (useAccelerometer) + setDataReportingMode(ch, 0x31, false); // Core Buttons and Accelerometer: 31 BB BB AA AA AA } handleExtensionControllerReports(ch, channelID, data, len); handleReport(data, len); @@ -1041,6 +1057,11 @@ void handleHciData(uint8_t* data, size_t len) { } } +void TinyWiimoteResetDevice(void) { + resetDevice(); + deviceInited = true; +} + bool TinyWiimoteDeviceIsInited(void) { return deviceInited; } @@ -1067,3 +1088,7 @@ void TinyWiimoteInit(TwHciInterface hciInterface) { receivedDataRb.rp = 0; _hciInterface = hciInterface; } + +void TinyWiimoteReqAccelerometer(bool use) { + useAccelerometer = use; +} diff --git a/TinyWiimote.h b/TinyWiimote.h index 9bd5437..28a88ab 100644 --- a/TinyWiimote.h +++ b/TinyWiimote.h @@ -21,9 +21,9 @@ struct TinyWiimoteData { uint8_t data[RECIEVED_DATA_MAX_LEN]; uint8_t len; }; -#define TWII_OFFSET_BTNS1 (2) -#define TWII_OFFSET_BTNS2 (3) -#define TWII_OFFSET_EXTCTRL (4) // Offset for Extension Controllers data +//#define TWII_OFFSET_BTNS1 (2) +//#define TWII_OFFSET_BTNS2 (3) +//#define TWII_OFFSET_EXTCTRL (4) // Offset for Extension Controllers data typedef struct tinywii_device_callback { void (*hci_send_packet)(uint8_t *data, size_t len); @@ -35,6 +35,9 @@ TinyWiimoteData TinyWiimoteRead(void); void TinyWiimoteResetDevice(void); bool TinyWiimoteDeviceIsInited(void); + +void TinyWiimoteReqAccelerometer(bool use); + void handleHciData(uint8_t* data, size_t len); char* format2Hex(uint8_t* data, uint16_t len); diff --git a/examples/ESP32WiimoteDemo/ESP32WiimoteDemo.ino b/examples/ESP32WiimoteDemo/ESP32WiimoteDemo.ino index dbdc9e3..32f3ea9 100644 --- a/examples/ESP32WiimoteDemo/ESP32WiimoteDemo.ino +++ b/examples/ESP32WiimoteDemo/ESP32WiimoteDemo.ino @@ -2,21 +2,81 @@ ESP32Wiimote wiimote; +static bool logging = true; +static long last_ms = 0; +static int num_run = 0, num_updates = 0; + void setup() { Serial.begin(115200); + Serial.println("ESP32Wiimote"); + wiimote.init(); + if (! logging) + wiimote.addFilter(ACTION_IGNORE, FILTER_ACCEL); // optional + + Serial.println("Started"); + last_ms = millis(); } void loop() { - wiimote.task(); - if (wiimote.available() > 0) { - uint16_t button = wiimote.getButtonState(); - Serial.printf("%04x\n", button); - if (button == ESP32Wiimote::BUTTON_A) { - Serial.println("A button"); - } - } - delay(10); + wiimote.task(); + num_run++; + + if (wiimote.available() > 0) + { + ButtonState button = wiimote.getButtonState(); + AccelState accel = wiimote.getAccelState(); + NunchukState nunchuk = wiimote.getNunchukState(); + + num_updates++; + if (logging) + { + char ca = (button & BUTTON_A) ? 'A' : '.'; + char cb = (button & BUTTON_B) ? 'B' : '.'; + char cc = (button & BUTTON_C) ? 'C' : '.'; + char cz = (button & BUTTON_Z) ? 'Z' : '.'; + char c1 = (button & BUTTON_ONE) ? '1' : '.'; + char c2 = (button & BUTTON_TWO) ? '2' : '.'; + char cminus = (button & BUTTON_MINUS) ? '-' : '.'; + char cplus = (button & BUTTON_PLUS) ? '+' : '.'; + char chome = (button & BUTTON_HOME) ? 'H' : '.'; + char cleft = (button & BUTTON_LEFT) ? '<' : '.'; + char cright = (button & BUTTON_RIGHT) ? '>' : '.'; + char cup = (button & BUTTON_UP) ? '^' : '.'; + char cdown = (button & BUTTON_DOWN) ? 'v' : '.'; + + Serial.printf("button: %05x = ", (int)button); + Serial.print(ca); + Serial.print(cb); + Serial.print(cc); + Serial.print(cz); + Serial.print(c1); + Serial.print(c2); + Serial.print(cminus); + Serial.print(chome); + Serial.print(cplus); + Serial.print(cleft); + Serial.print(cright); + Serial.print(cup); + Serial.print(cdown); + Serial.printf(", wiimote.axis: %3d/%3d/%3d", accel.xAxis, accel.yAxis, accel.zAxis); + Serial.printf(", nunchuk.axis: %3d/%3d/%3d", nunchuk.xAxis, nunchuk.yAxis, nunchuk.zAxis); + Serial.printf(", nunchuk.stick: %3d/%3d\n", nunchuk.xStick, nunchuk.yStick); + } + } + + if (! logging) + { + long ms = millis(); + if (ms - last_ms >= 1000) + { + Serial.printf("Run %d times per second with %d updates\n", num_run, num_updates); + num_run = num_updates = 0; + last_ms += 1000; + } + } + + delay(10); }