diff options
Diffstat (limited to 'arduino/libraries/Bluefruit52Lib/examples/Central/central_hid')
-rwxr-xr-x | arduino/libraries/Bluefruit52Lib/examples/Central/central_hid/central_hid.ino | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/arduino/libraries/Bluefruit52Lib/examples/Central/central_hid/central_hid.ino b/arduino/libraries/Bluefruit52Lib/examples/Central/central_hid/central_hid.ino new file mode 100755 index 0000000..c78d055 --- /dev/null +++ b/arduino/libraries/Bluefruit52Lib/examples/Central/central_hid/central_hid.ino @@ -0,0 +1,226 @@ +/********************************************************************* + This is an example for our nRF52 based Bluefruit LE modules + + Pick one up today in the adafruit shop! + + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + MIT license, check LICENSE for more information + All text above, and the splash screen below must be included in + any redistribution +*********************************************************************/ + +/* + * This sketch demonstrate the central API(). An additional bluefruit + * that has blehid as peripheral is required for the demo. + */ +#include <bluefruit.h> + +// Polling or callback implementation +#define POLLING 1 + +BLEClientHidAdafruit hid; + +// Last checked report, to detect if there is changes between reports +hid_keyboard_report_t last_kbd_report = { 0 }; +hid_mouse_report_t last_mse_report = { 0 }; + +void setup() +{ + Serial.begin(115200); + while ( !Serial ) delay(10); // for nrf52840 with native usb + + Serial.println("Bluefruit52 Central HID (Keyboard + Mouse) Example"); + Serial.println("--------------------------------------------------\n"); + + // Initialize Bluefruit with maximum connections as Peripheral = 0, Central = 1 + // SRAM usage required by SoftDevice will increase dramatically with number of connections + Bluefruit.begin(0, 1); + + Bluefruit.setName("Bluefruit52 Central"); + + // Init BLE Central Uart Serivce + hid.begin(); + + #if POLLING == 0 + hid.setKeyboardReportCallback(keyboard_report_callback); + #endif + + // Increase Blink rate to different from PrPh advertising mode + Bluefruit.setConnLedInterval(250); + + // Callbacks for Central + Bluefruit.Central.setConnectCallback(connect_callback); + Bluefruit.Central.setDisconnectCallback(disconnect_callback); + + /* Start Central Scanning + * - Enable auto scan if disconnected + * - Interval = 100 ms, window = 80 ms + * - Don't use active scan + * - Filter only accept HID service in advertising + * - Start(timeout) with timeout = 0 will scan forever (until connected) + */ + Bluefruit.Scanner.setRxCallback(scan_callback); + Bluefruit.Scanner.restartOnDisconnect(true); + Bluefruit.Scanner.setInterval(160, 80); // in unit of 0.625 ms + Bluefruit.Scanner.filterService(hid); // only report HID service + Bluefruit.Scanner.useActiveScan(false); + Bluefruit.Scanner.start(0); // 0 = Don't stop scanning after n seconds +} + +/** + * Callback invoked when scanner pick up an advertising data + * @param report Structural advertising data + */ +void scan_callback(ble_gap_evt_adv_report_t* report) +{ + // Since we configure the scanner with filterUuid() + // Scan callback only invoked for device with hid service advertised + // Connect to the device with hid service in advertising packet + Bluefruit.Central.connect(report); +} + +/** + * Callback invoked when an connection is established + * @param conn_handle + */ +void connect_callback(uint16_t conn_handle) +{ + Serial.println("Connected"); + + Serial.print("Discovering HID Service ... "); + + if ( hid.discover(conn_handle) ) + { + Serial.println("Found it"); + + // HID device mostly require pairing/bonding + if ( !Bluefruit.Gap.requestPairing(conn_handle) ) + { + Serial.print("Failed to paired"); + return; + } + + // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.hid_information.xml + uint8_t hidInfo[4]; + hid.getHidInfo(hidInfo); + + Serial.printf("HID version: %d.%d\n", hidInfo[0], hidInfo[1]); + Serial.print("Country code: "); Serial.println(hidInfo[2]); + Serial.printf("HID Flags : 0x%02X\n", hidInfo[3]); + + // BLEClientHidAdafruit currently only suports Boot Protocol Mode + // for Keyboard and Mouse. Let's set the protocol mode on prph to Boot Mode + hid.setProtocolMode(HID_PROTOCOL_MODE_BOOT); + + // Enable Keyboard report notification if present on prph + if ( hid.keyboardPresent() ) hid.enableKeyboard(); + + // Enable Mouse report notification if present on prph + if ( hid.mousePresent() ) hid.enableMouse(); + + Serial.println("Ready to receive from peripheral"); + }else + { + Serial.println("Found NONE"); + + // disconect since we couldn't find bleuart service + Bluefruit.Central.disconnect(conn_handle); + } +} + +/** + * Callback invoked when a connection is dropped + * @param conn_handle + * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h + * https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/master/cores/nRF5/nordic/softdevice/s140_nrf52_6.1.1_API/include/ble_hci.h + */ +void disconnect_callback(uint16_t conn_handle, uint8_t reason) +{ + (void) conn_handle; + (void) reason; + + Serial.println("Disconnected"); +} + +void loop() +{ + +#if POLLING == 1 + // nothing to do if hid not discovered + if ( !hid.discovered() ) return; + + /*------------- Polling Keyboard -------------*/ + hid_keyboard_report_t kbd_report; + + // Get latest report + hid.getKeyboardReport(&kbd_report); + + processKeyboardReport(&kbd_report); + + + // polling interval is 5 ms + delay(5); +#endif + +} + + +void keyboard_report_callback(hid_keyboard_report_t* report) +{ + processKeyboardReport(report); +} + +void processKeyboardReport(hid_keyboard_report_t* report) +{ + // Check with last report to see if there is any changes + if ( memcmp(&last_kbd_report, report, sizeof(hid_keyboard_report_t)) ) + { + bool shifted = false; + + if ( report->modifier ) + { + if ( report->modifier & (KEYBOARD_MODIFIER_LEFTCTRL | KEYBOARD_MODIFIER_RIGHTCTRL) ) + { + Serial.print("Ctrl "); + } + + if ( report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT) ) + { + Serial.print("Shift "); + + shifted = true; + } + + if ( report->modifier & (KEYBOARD_MODIFIER_LEFTALT | KEYBOARD_MODIFIER_RIGHTALT) ) + { + Serial.print("Alt "); + } + } + + for(uint8_t i=0; i<6; i++) + { + uint8_t kc = report->keycode[i]; + char ch = 0; + + if ( kc < 128 ) + { + ch = shifted ? HID_KEYCODE_TO_ASCII[kc].shifted : HID_KEYCODE_TO_ASCII[kc].ascii; + }else + { + // non-US keyboard !!?? + } + + // Printable + if (ch) + { + Serial.print(ch); + } + } + } + + // update last report + memcpy(&last_kbd_report, report, sizeof(hid_keyboard_report_t)); +} |