Use Tiny BLE as a joystick. The data is got from an external data source via a serial port.
Dependencies: BLE_API BLE_HID eMPL_MPU6050 mbed nRF51822
Fork of Seeed_Tiny_BLE_Get_Started by
main.cpp@4:89f37a17eba6, 2017-06-12 (annotated)
- Committer:
- bowenfeng
- Date:
- Mon Jun 12 04:10:04 2017 +0000
- Revision:
- 4:89f37a17eba6
- Parent:
- 3:24e365bd1b97
Use Tiny BLE as a BLE joystick. The direction data is got from an external data source via serial protocol.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
yihui | 0:26da608265f8 | 1 | #include "mbed.h" |
yihui | 2:b61ddbb8528e | 2 | #include "nrf51.h" |
yihui | 2:b61ddbb8528e | 3 | #include "nrf51_bitfields.h" |
yihui | 0:26da608265f8 | 4 | |
bowenfeng | 4:89f37a17eba6 | 5 | #include "ble/BLE.h" |
bowenfeng | 4:89f37a17eba6 | 6 | #include "JoystickService.h" |
yihui | 0:26da608265f8 | 7 | #include "DFUService.h" |
yihui | 0:26da608265f8 | 8 | #include "UARTService.h" |
yihui | 0:26da608265f8 | 9 | |
bowenfeng | 4:89f37a17eba6 | 10 | #include "examples_common.h" |
yihui | 0:26da608265f8 | 11 | |
yihui | 0:26da608265f8 | 12 | #define LOG(...) { pc.printf(__VA_ARGS__); } |
yihui | 0:26da608265f8 | 13 | |
yihui | 0:26da608265f8 | 14 | #define LED_GREEN p21 |
yihui | 0:26da608265f8 | 15 | #define LED_RED p22 |
yihui | 0:26da608265f8 | 16 | #define LED_BLUE p23 |
yihui | 0:26da608265f8 | 17 | |
bowenfeng | 4:89f37a17eba6 | 18 | #define LED_OFF 1 |
bowenfeng | 4:89f37a17eba6 | 19 | #define LED_ON 0 |
yihui | 0:26da608265f8 | 20 | |
yihui | 0:26da608265f8 | 21 | #define UART_TX p9 |
yihui | 0:26da608265f8 | 22 | #define UART_RX p11 |
yihui | 0:26da608265f8 | 23 | #define UART_CTS p8 |
yihui | 0:26da608265f8 | 24 | #define UART_RTS p10 |
yihui | 0:26da608265f8 | 25 | |
bowenfeng | 4:89f37a17eba6 | 26 | #define DATA_TX p3 |
bowenfeng | 4:89f37a17eba6 | 27 | #define DATA_RX p6 |
yihui | 0:26da608265f8 | 28 | |
yihui | 0:26da608265f8 | 29 | DigitalOut blue(LED_BLUE); |
yihui | 0:26da608265f8 | 30 | DigitalOut green(LED_GREEN); |
yihui | 0:26da608265f8 | 31 | DigitalOut red(LED_RED); |
yihui | 0:26da608265f8 | 32 | |
yihui | 0:26da608265f8 | 33 | Serial pc(UART_TX, UART_RX); |
bowenfeng | 4:89f37a17eba6 | 34 | Serial data(DATA_TX, DATA_RX); |
yihui | 0:26da608265f8 | 35 | |
bowenfeng | 4:89f37a17eba6 | 36 | BLE ble; |
bowenfeng | 4:89f37a17eba6 | 37 | JoystickService *joystickServicePtr; |
bowenfeng | 4:89f37a17eba6 | 38 | static const char DEVICE_NAME[] = "BunnyJoystick"; |
bowenfeng | 4:89f37a17eba6 | 39 | static const char SHORT_DEVICE_NAME[] = "joystick0"; |
yihui | 0:26da608265f8 | 40 | |
yihui | 0:26da608265f8 | 41 | volatile bool bleIsConnected = false; |
yihui | 0:26da608265f8 | 42 | volatile uint8_t tick_event = 0; |
yihui | 0:26da608265f8 | 43 | |
bowenfeng | 4:89f37a17eba6 | 44 | static void onDisconnect(const Gap::DisconnectionCallbackParams_t *params) { |
bowenfeng | 4:89f37a17eba6 | 45 | LOG("disconnected\r\n"); |
yihui | 0:26da608265f8 | 46 | bleIsConnected = false; |
bowenfeng | 4:89f37a17eba6 | 47 | red = LED_OFF; |
bowenfeng | 4:89f37a17eba6 | 48 | blue = LED_OFF; |
bowenfeng | 4:89f37a17eba6 | 49 | green = LED_ON; |
bowenfeng | 4:89f37a17eba6 | 50 | ble.gap().startAdvertising(); // restart advertising |
yihui | 0:26da608265f8 | 51 | } |
yihui | 0:26da608265f8 | 52 | |
yihui | 0:26da608265f8 | 53 | |
bowenfeng | 4:89f37a17eba6 | 54 | static void onConnect(const Gap::ConnectionCallbackParams_t *params) { |
bowenfeng | 4:89f37a17eba6 | 55 | LOG("connected\r\n"); |
bowenfeng | 4:89f37a17eba6 | 56 | bleIsConnected = true; |
bowenfeng | 4:89f37a17eba6 | 57 | red = LED_OFF; |
bowenfeng | 4:89f37a17eba6 | 58 | blue = LED_ON; |
bowenfeng | 4:89f37a17eba6 | 59 | green = LED_OFF; |
yihui | 0:26da608265f8 | 60 | } |
yihui | 0:26da608265f8 | 61 | |
bowenfeng | 4:89f37a17eba6 | 62 | static void waiting() { |
bowenfeng | 4:89f37a17eba6 | 63 | if (!joystickServicePtr->isConnected()) { |
bowenfeng | 4:89f37a17eba6 | 64 | green = !green; |
bowenfeng | 4:89f37a17eba6 | 65 | } else { |
bowenfeng | 4:89f37a17eba6 | 66 | blue = !blue; |
bowenfeng | 4:89f37a17eba6 | 67 | } |
yihui | 0:26da608265f8 | 68 | } |
yihui | 0:26da608265f8 | 69 | |
yihui | 0:26da608265f8 | 70 | |
bowenfeng | 4:89f37a17eba6 | 71 | int main() { |
bowenfeng | 4:89f37a17eba6 | 72 | blue = LED_OFF; |
bowenfeng | 4:89f37a17eba6 | 73 | green = LED_OFF; |
bowenfeng | 4:89f37a17eba6 | 74 | red = LED_OFF; |
yihui | 0:26da608265f8 | 75 | |
bowenfeng | 4:89f37a17eba6 | 76 | data.baud(115200); |
bowenfeng | 4:89f37a17eba6 | 77 | |
bowenfeng | 4:89f37a17eba6 | 78 | wait(4); |
bowenfeng | 4:89f37a17eba6 | 79 | LOG("Bunny Joystick started.\n"); |
yihui | 0:26da608265f8 | 80 | |
bowenfeng | 4:89f37a17eba6 | 81 | LOG("initialising ticker\r\n"); |
bowenfeng | 4:89f37a17eba6 | 82 | Ticker heartbeat; |
bowenfeng | 4:89f37a17eba6 | 83 | heartbeat.attach(waiting, 1); |
yihui | 3:24e365bd1b97 | 84 | |
bowenfeng | 4:89f37a17eba6 | 85 | LOG("initialising ble\r\n"); |
bowenfeng | 4:89f37a17eba6 | 86 | ble.init(); |
yihui | 2:b61ddbb8528e | 87 | |
bowenfeng | 4:89f37a17eba6 | 88 | ble.gap().onDisconnection(onDisconnect); |
bowenfeng | 4:89f37a17eba6 | 89 | ble.gap().onConnection(onConnect); |
bowenfeng | 4:89f37a17eba6 | 90 | |
bowenfeng | 4:89f37a17eba6 | 91 | initializeSecurity(ble); |
yihui | 2:b61ddbb8528e | 92 | |
bowenfeng | 4:89f37a17eba6 | 93 | LOG("adding hid service\r\n"); |
bowenfeng | 4:89f37a17eba6 | 94 | JoystickService joystickService(ble); |
bowenfeng | 4:89f37a17eba6 | 95 | joystickServicePtr = &joystickService; |
yihui | 2:b61ddbb8528e | 96 | |
bowenfeng | 4:89f37a17eba6 | 97 | LOG("adding dev info and battery service\r\n"); |
bowenfeng | 4:89f37a17eba6 | 98 | initializeHOGP(ble); |
yihui | 2:b61ddbb8528e | 99 | |
bowenfeng | 4:89f37a17eba6 | 100 | LOG("setting up gap\r\n"); |
bowenfeng | 4:89f37a17eba6 | 101 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::JOYSTICK); |
bowenfeng | 4:89f37a17eba6 | 102 | ble.gap().accumulateAdvertisingPayload( |
bowenfeng | 4:89f37a17eba6 | 103 | GapAdvertisingData::COMPLETE_LOCAL_NAME, |
bowenfeng | 4:89f37a17eba6 | 104 | (const uint8_t *)DEVICE_NAME, |
bowenfeng | 4:89f37a17eba6 | 105 | sizeof(DEVICE_NAME)); |
bowenfeng | 4:89f37a17eba6 | 106 | ble.gap().accumulateAdvertisingPayload( |
bowenfeng | 4:89f37a17eba6 | 107 | GapAdvertisingData::SHORTENED_LOCAL_NAME, |
bowenfeng | 4:89f37a17eba6 | 108 | (const uint8_t *)SHORT_DEVICE_NAME, |
bowenfeng | 4:89f37a17eba6 | 109 | sizeof(SHORT_DEVICE_NAME)); |
bowenfeng | 4:89f37a17eba6 | 110 | ble.gap().setDeviceName((const uint8_t *)DEVICE_NAME); |
yihui | 2:b61ddbb8528e | 111 | |
bowenfeng | 4:89f37a17eba6 | 112 | LOG("advertising\r\n"); |
yihui | 3:24e365bd1b97 | 113 | ble.gap().startAdvertising(); |
yihui | 2:b61ddbb8528e | 114 | |
bowenfeng | 4:89f37a17eba6 | 115 | int xraw, yraw, zraw; |
bowenfeng | 4:89f37a17eba6 | 116 | |
yihui | 0:26da608265f8 | 117 | while (true) { |
bowenfeng | 4:89f37a17eba6 | 118 | if (data.readable()) { |
bowenfeng | 4:89f37a17eba6 | 119 | char buffer[256] = {0}; |
bowenfeng | 4:89f37a17eba6 | 120 | char c; |
bowenfeng | 4:89f37a17eba6 | 121 | int i = 0; |
bowenfeng | 4:89f37a17eba6 | 122 | while(data.readable() && i < 256) { |
bowenfeng | 4:89f37a17eba6 | 123 | buffer[i++] = c = data.getc(); |
bowenfeng | 4:89f37a17eba6 | 124 | if (c == '\n') { |
bowenfeng | 4:89f37a17eba6 | 125 | buffer[i] = 0; |
bowenfeng | 4:89f37a17eba6 | 126 | break; |
yihui | 3:24e365bd1b97 | 127 | } |
yihui | 3:24e365bd1b97 | 128 | } |
bowenfeng | 4:89f37a17eba6 | 129 | LOG("Received data from FTHR:\n"); |
bowenfeng | 4:89f37a17eba6 | 130 | LOG(buffer); |
bowenfeng | 4:89f37a17eba6 | 131 | sscanf(buffer, "%d,%d,%d", &xraw, &yraw, &zraw); |
bowenfeng | 4:89f37a17eba6 | 132 | LOG("%d,%d,%d", xraw, yraw, zraw); |
bowenfeng | 4:89f37a17eba6 | 133 | joystickServicePtr->setSpeed(xraw, yraw, zraw); |
yihui | 3:24e365bd1b97 | 134 | |
bowenfeng | 4:89f37a17eba6 | 135 | wait(0.5); |
yihui | 0:26da608265f8 | 136 | } |
bowenfeng | 4:89f37a17eba6 | 137 | |
bowenfeng | 4:89f37a17eba6 | 138 | ble.waitForEvent(); |
yihui | 0:26da608265f8 | 139 | } |
yihui | 0:26da608265f8 | 140 | } |