Bluetooth BLE HID Mouse for the AlterErgo device, based on Seeed Studio Tiny BLE.
Dependencies: BLE_API BLE_HID mbed nRF51822
Fork of BLENano_HID by
main.cpp@1:2749e6ff50ce, 2018-08-26 (annotated)
- Committer:
- shervinemami
- Date:
- Sun Aug 26 10:51:20 2018 +0000
- Revision:
- 1:2749e6ff50ce
- Parent:
- 0:3435302551b3
- Child:
- 2:0218f7d82bfa
Initial working version of the HID mouse
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
shervinemami | 1:2749e6ff50ce | 1 | /** |
shervinemami | 1:2749e6ff50ce | 2 | * Handheld BLE finger input device based on Seeed Studio Tiny BLE (TinyBLE). |
shervinemami | 1:2749e6ff50ce | 3 | * By Shervin Emami (http://shervinemami.info/), 25th Aug 2018. |
shervinemami | 1:2749e6ff50ce | 4 | * If the analog voltage on a "finger" pin is below a threshold voltage, |
shervinemami | 1:2749e6ff50ce | 5 | * then it sends a mouse command using Bluetooth BLE, so that any computer or |
shervinemami | 1:2749e6ff50ce | 6 | * smartphone can be configured to perform a desired function due to this input event. |
shervinemami | 1:2749e6ff50ce | 7 | * |
shervinemami | 1:2749e6ff50ce | 8 | * |
shervinemami | 1:2749e6ff50ce | 9 | * This program implements a complete HID-over-Gatt Profile: |
shervinemami | 1:2749e6ff50ce | 10 | * - HID is provided by KeyboardService |
shervinemami | 1:2749e6ff50ce | 11 | * - Battery Service |
shervinemami | 1:2749e6ff50ce | 12 | * - Device Information Service |
shervinemami | 1:2749e6ff50ce | 13 | * |
shervinemami | 1:2749e6ff50ce | 14 | * Complete strings can be sent over BLE using printf. Please note, however, than a 12char string |
shervinemami | 1:2749e6ff50ce | 15 | * will take about 500ms to transmit, principally because of the limited notification rate in BLE. |
shervinemami | 1:2749e6ff50ce | 16 | * KeyboardService uses a circular buffer to store the strings to send, and calls to putc will fail |
shervinemami | 1:2749e6ff50ce | 17 | * once this buffer is full. This will result in partial strings being sent to the client. |
shervinemami | 1:2749e6ff50ce | 18 | |
shervinemami | 1:2749e6ff50ce | 19 | * Tested with mbed libraries for April 2nd, 2018. If you use a newer version of mbed or other |
shervinemami | 1:2749e6ff50ce | 20 | * libs and you have problems, try rolling back to April 2nd, 2018. |
shervinemami | 1:2749e6ff50ce | 21 | */ |
shervinemami | 1:2749e6ff50ce | 22 | |
shervinemami | 1:2749e6ff50ce | 23 | // Configure the settings of my board. |
shervinemami | 1:2749e6ff50ce | 24 | #include "tiny_ble.h" // Seeed Studio Tiny BLE |
shervinemami | 1:2749e6ff50ce | 25 | |
shervinemami | 1:2749e6ff50ce | 26 | |
shervinemami | 1:2749e6ff50ce | 27 | // Define LOG_MESSAGES if you want various debug messages to be sent to the PC via a UART cable. |
shervinemami | 1:2749e6ff50ce | 28 | #define LOG_MESSAGES |
shervinemami | 1:2749e6ff50ce | 29 | |
shervinemami | 1:2749e6ff50ce | 30 | |
shervinemami | 1:2749e6ff50ce | 31 | const float FINGER1_PRESS = 0.42f; // Set how much the person needs to press their finger in to trigger a keypress. |
shervinemami | 1:2749e6ff50ce | 32 | const float FINGER2_PRESS = 0.41f; // Note that each finger is slightly different strength, due to the mechanical design. |
shervinemami | 1:2749e6ff50ce | 33 | const float FINGER3_PRESS = 0.38f; // |
shervinemami | 1:2749e6ff50ce | 34 | const float FINGER4_PRESS = 0.37f; // |
shervinemami | 1:2749e6ff50ce | 35 | |
shervinemami | 1:2749e6ff50ce | 36 | const float FINGER1_RELEASE = 0.35f; // Set how much the person needs to release their finger to finish a keypress. |
shervinemami | 1:2749e6ff50ce | 37 | const float FINGER2_RELEASE = 0.35f; // Note that each finger is slightly different strength, due to the mechanical design. |
shervinemami | 1:2749e6ff50ce | 38 | const float FINGER3_RELEASE = 0.34f; // |
shervinemami | 1:2749e6ff50ce | 39 | const float FINGER4_RELEASE = 0.34f; // |
shervinemami | 1:2749e6ff50ce | 40 | |
shervinemami | 1:2749e6ff50ce | 41 | const float BATTERY_NEEDS_CHARGE = 0.198f; // 0.20 means >= 3.4V, 0.19 means >= 2.4V. |
shervinemami | 1:2749e6ff50ce | 42 | |
shervinemami | 1:2749e6ff50ce | 43 | |
YuuichiAkagawa | 0:3435302551b3 | 44 | /* mbed Microcontroller Library |
YuuichiAkagawa | 0:3435302551b3 | 45 | * Copyright (c) 2015 ARM Limited |
YuuichiAkagawa | 0:3435302551b3 | 46 | * |
YuuichiAkagawa | 0:3435302551b3 | 47 | * Licensed under the Apache License, Version 2.0 (the "License"); |
YuuichiAkagawa | 0:3435302551b3 | 48 | * you may not use this file except in compliance with the License. |
YuuichiAkagawa | 0:3435302551b3 | 49 | * You may obtain a copy of the License at |
YuuichiAkagawa | 0:3435302551b3 | 50 | * |
YuuichiAkagawa | 0:3435302551b3 | 51 | * http://www.apache.org/licenses/LICENSE-2.0 |
YuuichiAkagawa | 0:3435302551b3 | 52 | * |
YuuichiAkagawa | 0:3435302551b3 | 53 | * Unless required by applicable law or agreed to in writing, software |
YuuichiAkagawa | 0:3435302551b3 | 54 | * distributed under the License is distributed on an "AS IS" BASIS, |
YuuichiAkagawa | 0:3435302551b3 | 55 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
YuuichiAkagawa | 0:3435302551b3 | 56 | * See the License for the specific language governing permissions and |
YuuichiAkagawa | 0:3435302551b3 | 57 | * limitations under the License. |
YuuichiAkagawa | 0:3435302551b3 | 58 | */ |
YuuichiAkagawa | 0:3435302551b3 | 59 | |
YuuichiAkagawa | 0:3435302551b3 | 60 | #include "mbed.h" |
YuuichiAkagawa | 0:3435302551b3 | 61 | |
YuuichiAkagawa | 0:3435302551b3 | 62 | #include "ble/BLE.h" |
shervinemami | 1:2749e6ff50ce | 63 | //#include "KeyboardService.h" |
shervinemami | 1:2749e6ff50ce | 64 | #include "MouseService.h" |
shervinemami | 1:2749e6ff50ce | 65 | |
YuuichiAkagawa | 0:3435302551b3 | 66 | |
YuuichiAkagawa | 0:3435302551b3 | 67 | #include "examples_common.h" |
shervinemami | 1:2749e6ff50ce | 68 | |
shervinemami | 1:2749e6ff50ce | 69 | |
shervinemami | 1:2749e6ff50ce | 70 | |
shervinemami | 1:2749e6ff50ce | 71 | #undef HID_DEBUG |
shervinemami | 1:2749e6ff50ce | 72 | #undef LOG |
shervinemami | 1:2749e6ff50ce | 73 | #ifdef LOG_MESSAGES |
shervinemami | 1:2749e6ff50ce | 74 | #define LOG(...) { pc.printf(__VA_ARGS__); } |
shervinemami | 1:2749e6ff50ce | 75 | Serial pc(UART_TX, UART_RX); |
shervinemami | 1:2749e6ff50ce | 76 | #else |
shervinemami | 1:2749e6ff50ce | 77 | #define LOG(...) |
shervinemami | 1:2749e6ff50ce | 78 | #endif |
shervinemami | 1:2749e6ff50ce | 79 | #define HID_DEBUG LOG |
shervinemami | 1:2749e6ff50ce | 80 | |
shervinemami | 1:2749e6ff50ce | 81 | |
shervinemami | 1:2749e6ff50ce | 82 | AnalogIn battery(BATTERY_PIN); // For measuring the battery level |
shervinemami | 1:2749e6ff50ce | 83 | AnalogIn finger1(FINGER1_PIN); // For measuring a finger level |
shervinemami | 1:2749e6ff50ce | 84 | AnalogIn finger2(FINGER2_PIN); // |
shervinemami | 1:2749e6ff50ce | 85 | AnalogIn finger3(FINGER3_PIN); // |
shervinemami | 1:2749e6ff50ce | 86 | AnalogIn finger4(FINGER4_PIN); // |
shervinemami | 1:2749e6ff50ce | 87 | DigitalOut waiting_led(LED_RED); // For showing BLE is trying to connect |
shervinemami | 1:2749e6ff50ce | 88 | DigitalOut connected_led(LED_GREEN); // For showing BLE is connected |
shervinemami | 1:2749e6ff50ce | 89 | DigitalOut status_led(LED_BLUE); // For showing BLE is busy |
shervinemami | 1:2749e6ff50ce | 90 | DigitalOut enable_out3v3(OUT3V3_PIN); // For using OUT_3V3 pin of TinyBLE |
shervinemami | 1:2749e6ff50ce | 91 | |
shervinemami | 1:2749e6ff50ce | 92 | #define LED_ON 0 // LEDs on Tiny BLE need 0V to light up. |
shervinemami | 1:2749e6ff50ce | 93 | #define LED_OFF 1 // |
shervinemami | 1:2749e6ff50ce | 94 | |
shervinemami | 1:2749e6ff50ce | 95 | |
shervinemami | 1:2749e6ff50ce | 96 | bool haveAskedForRecharge = false; // Only ask for a recharge once per poweron. Requires user to turn device off once per day! |
shervinemami | 1:2749e6ff50ce | 97 | |
shervinemami | 1:2749e6ff50ce | 98 | |
shervinemami | 1:2749e6ff50ce | 99 | InterruptIn button1(BUTTON_PIN); // For sending a BLE command |
YuuichiAkagawa | 0:3435302551b3 | 100 | |
YuuichiAkagawa | 0:3435302551b3 | 101 | BLE ble; |
shervinemami | 1:2749e6ff50ce | 102 | //KeyboardService *kbdServicePtr; |
shervinemami | 1:2749e6ff50ce | 103 | MouseService *mouseServicePtr; |
YuuichiAkagawa | 0:3435302551b3 | 104 | |
shervinemami | 1:2749e6ff50ce | 105 | static const char DEVICE_NAME[] = "ShervMouse"; |
shervinemami | 1:2749e6ff50ce | 106 | static const char SHORT_DEVICE_NAME[] = "ShMouse"; |
shervinemami | 1:2749e6ff50ce | 107 | |
shervinemami | 1:2749e6ff50ce | 108 | |
shervinemami | 1:2749e6ff50ce | 109 | // Status flags that are updated in ISR callback functions. |
shervinemami | 1:2749e6ff50ce | 110 | volatile bool check_fingers = false; |
shervinemami | 1:2749e6ff50ce | 111 | volatile bool press_keyup[5] = {false}; |
shervinemami | 1:2749e6ff50ce | 112 | |
shervinemami | 1:2749e6ff50ce | 113 | |
shervinemami | 1:2749e6ff50ce | 114 | |
YuuichiAkagawa | 0:3435302551b3 | 115 | static void onDisconnect(const Gap::DisconnectionCallbackParams_t *params) |
YuuichiAkagawa | 0:3435302551b3 | 116 | { |
shervinemami | 1:2749e6ff50ce | 117 | HID_DEBUG("discon\n\r"); |
shervinemami | 1:2749e6ff50ce | 118 | waiting_led = LED_ON; |
shervinemami | 1:2749e6ff50ce | 119 | connected_led = LED_OFF; |
YuuichiAkagawa | 0:3435302551b3 | 120 | |
YuuichiAkagawa | 0:3435302551b3 | 121 | ble.gap().startAdvertising(); // restart advertising |
YuuichiAkagawa | 0:3435302551b3 | 122 | } |
YuuichiAkagawa | 0:3435302551b3 | 123 | |
YuuichiAkagawa | 0:3435302551b3 | 124 | static void onConnect(const Gap::ConnectionCallbackParams_t *params) |
YuuichiAkagawa | 0:3435302551b3 | 125 | { |
shervinemami | 1:2749e6ff50ce | 126 | HID_DEBUG("conn\n\r"); |
shervinemami | 1:2749e6ff50ce | 127 | waiting_led = LED_OFF; |
shervinemami | 1:2749e6ff50ce | 128 | connected_led = LED_ON; |
YuuichiAkagawa | 0:3435302551b3 | 129 | } |
shervinemami | 1:2749e6ff50ce | 130 | |
shervinemami | 1:2749e6ff50ce | 131 | |
shervinemami | 1:2749e6ff50ce | 132 | |
shervinemami | 1:2749e6ff50ce | 133 | |
shervinemami | 1:2749e6ff50ce | 134 | |
shervinemami | 1:2749e6ff50ce | 135 | // ISR callback function that is automatically called every 0.1 seconds or so. |
shervinemami | 1:2749e6ff50ce | 136 | // Make sure there isn't anything slow like printf in this ISR! |
shervinemami | 1:2749e6ff50ce | 137 | static void heartbeat_ISR() { |
shervinemami | 1:2749e6ff50ce | 138 | if (!mouseServicePtr->isConnected()) |
YuuichiAkagawa | 0:3435302551b3 | 139 | waiting_led = !waiting_led; |
shervinemami | 1:2749e6ff50ce | 140 | else { |
shervinemami | 1:2749e6ff50ce | 141 | //connected_led = !connected_led; |
shervinemami | 1:2749e6ff50ce | 142 | //waiting_led = 0; |
shervinemami | 1:2749e6ff50ce | 143 | } |
shervinemami | 1:2749e6ff50ce | 144 | |
shervinemami | 1:2749e6ff50ce | 145 | // Signal that we should check the finger sensors soon. |
shervinemami | 1:2749e6ff50ce | 146 | check_fingers = true; |
YuuichiAkagawa | 0:3435302551b3 | 147 | } |
YuuichiAkagawa | 0:3435302551b3 | 148 | |
YuuichiAkagawa | 0:3435302551b3 | 149 | |
YuuichiAkagawa | 0:3435302551b3 | 150 | int main() |
YuuichiAkagawa | 0:3435302551b3 | 151 | { |
shervinemami | 1:2749e6ff50ce | 152 | #ifdef LOG_MESSAGES |
shervinemami | 1:2749e6ff50ce | 153 | pc.baud(115200); // Use fast UART for log messages instead of default 9600 bps. |
shervinemami | 1:2749e6ff50ce | 154 | #endif |
shervinemami | 1:2749e6ff50ce | 155 | |
shervinemami | 1:2749e6ff50ce | 156 | waiting_led = LED_OFF; // Set LEDs to blue, until ready. |
shervinemami | 1:2749e6ff50ce | 157 | connected_led = LED_OFF; |
shervinemami | 1:2749e6ff50ce | 158 | status_led = LED_ON; |
shervinemami | 1:2749e6ff50ce | 159 | |
shervinemami | 1:2749e6ff50ce | 160 | wait(1); |
shervinemami | 1:2749e6ff50ce | 161 | LOG("---- Shervin's Mouse Input device, using TinyBLE + BLE HID mouse service ----\n\r"); |
shervinemami | 1:2749e6ff50ce | 162 | |
shervinemami | 1:2749e6ff50ce | 163 | // Call the button1_ISR function whenever the pushbutton is pressed. |
shervinemami | 1:2749e6ff50ce | 164 | //button1.rise(button1_ISR); |
YuuichiAkagawa | 0:3435302551b3 | 165 | |
shervinemami | 1:2749e6ff50ce | 166 | HID_DEBUG("initialising ticker\n\r"); |
shervinemami | 1:2749e6ff50ce | 167 | |
shervinemami | 1:2749e6ff50ce | 168 | // Call the heartbeat_ISR function every 0.1 seconds |
shervinemami | 1:2749e6ff50ce | 169 | Ticker heartbeat; |
shervinemami | 1:2749e6ff50ce | 170 | heartbeat.attach(heartbeat_ISR, 0.1f); |
shervinemami | 1:2749e6ff50ce | 171 | |
shervinemami | 1:2749e6ff50ce | 172 | HID_DEBUG("enabling finger sensors\n\r"); |
shervinemami | 1:2749e6ff50ce | 173 | enable_out3v3 = 1; |
YuuichiAkagawa | 0:3435302551b3 | 174 | |
shervinemami | 1:2749e6ff50ce | 175 | HID_DEBUG("initialising ble\n\r"); |
YuuichiAkagawa | 0:3435302551b3 | 176 | ble.init(); |
YuuichiAkagawa | 0:3435302551b3 | 177 | |
YuuichiAkagawa | 0:3435302551b3 | 178 | ble.gap().onDisconnection(onDisconnect); |
YuuichiAkagawa | 0:3435302551b3 | 179 | ble.gap().onConnection(onConnect); |
YuuichiAkagawa | 0:3435302551b3 | 180 | |
YuuichiAkagawa | 0:3435302551b3 | 181 | initializeSecurity(ble); |
YuuichiAkagawa | 0:3435302551b3 | 182 | |
shervinemami | 1:2749e6ff50ce | 183 | HID_DEBUG("adding hid mouse service\n\r"); |
shervinemami | 1:2749e6ff50ce | 184 | MouseService mouseService(ble); |
shervinemami | 1:2749e6ff50ce | 185 | mouseServicePtr = &mouseService; |
YuuichiAkagawa | 0:3435302551b3 | 186 | |
shervinemami | 1:2749e6ff50ce | 187 | HID_DEBUG("adding device info and battery service\n\r"); |
YuuichiAkagawa | 0:3435302551b3 | 188 | initializeHOGP(ble); |
YuuichiAkagawa | 0:3435302551b3 | 189 | |
shervinemami | 1:2749e6ff50ce | 190 | HID_DEBUG("setting up gap\n\r"); |
shervinemami | 1:2749e6ff50ce | 191 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MOUSE); |
YuuichiAkagawa | 0:3435302551b3 | 192 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, |
YuuichiAkagawa | 0:3435302551b3 | 193 | (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); |
YuuichiAkagawa | 0:3435302551b3 | 194 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, |
YuuichiAkagawa | 0:3435302551b3 | 195 | (uint8_t *)SHORT_DEVICE_NAME, sizeof(SHORT_DEVICE_NAME)); |
YuuichiAkagawa | 0:3435302551b3 | 196 | |
shervinemami | 1:2749e6ff50ce | 197 | HID_DEBUG("advertising\n\r"); |
YuuichiAkagawa | 0:3435302551b3 | 198 | ble.gap().startAdvertising(); |
shervinemami | 1:2749e6ff50ce | 199 | |
shervinemami | 1:2749e6ff50ce | 200 | // Turn LEDs to green connected. |
shervinemami | 1:2749e6ff50ce | 201 | connected_led = LED_ON; |
shervinemami | 1:2749e6ff50ce | 202 | waiting_led = LED_OFF; |
shervinemami | 1:2749e6ff50ce | 203 | status_led = LED_OFF; |
shervinemami | 1:2749e6ff50ce | 204 | |
shervinemami | 1:2749e6ff50ce | 205 | // Run forever ... |
shervinemami | 1:2749e6ff50ce | 206 | LOG("Ready to run forever ...\n\r"); |
shervinemami | 1:2749e6ff50ce | 207 | int counter1 = 0; |
shervinemami | 1:2749e6ff50ce | 208 | int counter2 = 0; |
YuuichiAkagawa | 0:3435302551b3 | 209 | while (true) { |
YuuichiAkagawa | 0:3435302551b3 | 210 | ble.waitForEvent(); |
shervinemami | 1:2749e6ff50ce | 211 | |
shervinemami | 1:2749e6ff50ce | 212 | // Signal that we should check the finger sensors soon. |
shervinemami | 1:2749e6ff50ce | 213 | if (check_fingers) { |
shervinemami | 1:2749e6ff50ce | 214 | check_fingers = false; |
shervinemami | 1:2749e6ff50ce | 215 | |
shervinemami | 1:2749e6ff50ce | 216 | // Measure all the finger sensors and battery level. |
shervinemami | 1:2749e6ff50ce | 217 | float fing1 = finger1.read(); |
shervinemami | 1:2749e6ff50ce | 218 | float fing2 = finger2.read(); |
shervinemami | 1:2749e6ff50ce | 219 | float fing3 = finger3.read(); |
shervinemami | 1:2749e6ff50ce | 220 | float fing4 = finger4.read(); |
shervinemami | 1:2749e6ff50ce | 221 | float batt = battery.read(); |
shervinemami | 1:2749e6ff50ce | 222 | |
shervinemami | 1:2749e6ff50ce | 223 | // If a finger was pressed and now has been released, send the keyUp event soon after. |
shervinemami | 1:2749e6ff50ce | 224 | if (press_keyup[1] && fing1 < FINGER1_RELEASE) { |
shervinemami | 1:2749e6ff50ce | 225 | press_keyup[1] = false; // Clear the flag |
shervinemami | 1:2749e6ff50ce | 226 | //kbdServicePtr->keyUpCode(); |
shervinemami | 1:2749e6ff50ce | 227 | HID_DEBUG("sent key up for 1.\n\r"); |
shervinemami | 1:2749e6ff50ce | 228 | } |
shervinemami | 1:2749e6ff50ce | 229 | if (press_keyup[2] && fing2 < FINGER2_RELEASE) { |
shervinemami | 1:2749e6ff50ce | 230 | press_keyup[2] = false; // Clear the flag |
shervinemami | 1:2749e6ff50ce | 231 | //send_keypress(FING2UP_KEYCODE, 2); |
shervinemami | 1:2749e6ff50ce | 232 | HID_DEBUG("sent final key down for 2.\n\r"); |
shervinemami | 1:2749e6ff50ce | 233 | ble.waitForEvent(); // Add a slight delay |
shervinemami | 1:2749e6ff50ce | 234 | //wait(0.1); // Add a slight delay |
shervinemami | 1:2749e6ff50ce | 235 | //ble.waitForEvent(); // Add a slight delay |
shervinemami | 1:2749e6ff50ce | 236 | //kbdServicePtr->keyUpCode(); |
shervinemami | 1:2749e6ff50ce | 237 | HID_DEBUG("sent final key up for 2.\n\r"); |
shervinemami | 1:2749e6ff50ce | 238 | press_keyup[2] = false; // Clear the flag |
shervinemami | 1:2749e6ff50ce | 239 | } |
shervinemami | 1:2749e6ff50ce | 240 | if (press_keyup[3] && fing3 < FINGER3_RELEASE) { |
shervinemami | 1:2749e6ff50ce | 241 | press_keyup[3] = false; // Clear the flag |
shervinemami | 1:2749e6ff50ce | 242 | //kbdServicePtr->keyUpCode(); |
shervinemami | 1:2749e6ff50ce | 243 | HID_DEBUG("sent key up for 3.\n\r"); |
shervinemami | 1:2749e6ff50ce | 244 | } |
shervinemami | 1:2749e6ff50ce | 245 | if (press_keyup[4] && fing4 < FINGER4_RELEASE) { |
shervinemami | 1:2749e6ff50ce | 246 | press_keyup[4] = false; // Clear the flag |
shervinemami | 1:2749e6ff50ce | 247 | //kbdServicePtr->keyUpCode(); |
shervinemami | 1:2749e6ff50ce | 248 | HID_DEBUG("sent key up for 4.\n\r"); |
shervinemami | 1:2749e6ff50ce | 249 | } |
shervinemami | 1:2749e6ff50ce | 250 | |
shervinemami | 1:2749e6ff50ce | 251 | |
shervinemami | 1:2749e6ff50ce | 252 | // Very occasionally, show the connected LED |
shervinemami | 1:2749e6ff50ce | 253 | counter1++; |
shervinemami | 1:2749e6ff50ce | 254 | if (counter1 == 1) { |
shervinemami | 1:2749e6ff50ce | 255 | if (mouseServicePtr->isConnected()) { |
shervinemami | 1:2749e6ff50ce | 256 | connected_led = LED_ON; |
shervinemami | 1:2749e6ff50ce | 257 | waiting_led = LED_OFF; |
shervinemami | 1:2749e6ff50ce | 258 | } |
shervinemami | 1:2749e6ff50ce | 259 | } |
shervinemami | 1:2749e6ff50ce | 260 | if (counter1 == 2) { |
shervinemami | 1:2749e6ff50ce | 261 | //counter2 = 0; |
shervinemami | 1:2749e6ff50ce | 262 | connected_led = LED_OFF; |
shervinemami | 1:2749e6ff50ce | 263 | waiting_led = LED_OFF; |
shervinemami | 1:2749e6ff50ce | 264 | } |
shervinemami | 1:2749e6ff50ce | 265 | |
shervinemami | 1:2749e6ff50ce | 266 | |
shervinemami | 1:2749e6ff50ce | 267 | // Occasionally show some debug info |
shervinemami | 1:2749e6ff50ce | 268 | if (counter1 > 15) { |
shervinemami | 1:2749e6ff50ce | 269 | //counter2++; |
shervinemami | 1:2749e6ff50ce | 270 | LOG("%.2f%. F1=%.2f, F2=%.2f, F3=%.2f, F4=%.2f\n\r", batt, fing1, fing2, fing3, fing4); |
shervinemami | 1:2749e6ff50ce | 271 | |
shervinemami | 1:2749e6ff50ce | 272 | // Check for low battery |
shervinemami | 1:2749e6ff50ce | 273 | if (batt < BATTERY_NEEDS_CHARGE) { |
shervinemami | 1:2749e6ff50ce | 274 | // Toggle blue LED |
shervinemami | 1:2749e6ff50ce | 275 | waiting_led = LED_OFF; |
shervinemami | 1:2749e6ff50ce | 276 | connected_led = LED_OFF; |
shervinemami | 1:2749e6ff50ce | 277 | status_led = !status_led; |
shervinemami | 1:2749e6ff50ce | 278 | if (!haveAskedForRecharge) { |
shervinemami | 1:2749e6ff50ce | 279 | //send_string("RECHARGE BATTERY!"); |
shervinemami | 1:2749e6ff50ce | 280 | haveAskedForRecharge = true; |
shervinemami | 1:2749e6ff50ce | 281 | } |
shervinemami | 1:2749e6ff50ce | 282 | LOG("RECHARGE BATTERY!\n\r"); |
shervinemami | 1:2749e6ff50ce | 283 | } |
shervinemami | 1:2749e6ff50ce | 284 | //else { |
shervinemami | 1:2749e6ff50ce | 285 | //} |
shervinemami | 1:2749e6ff50ce | 286 | counter1 = 0; |
shervinemami | 1:2749e6ff50ce | 287 | } |
shervinemami | 1:2749e6ff50ce | 288 | |
shervinemami | 1:2749e6ff50ce | 289 | // Check if a finger was pressed |
shervinemami | 1:2749e6ff50ce | 290 | if (fing1 > FINGER1_PRESS && !press_keyup[1]) { |
shervinemami | 1:2749e6ff50ce | 291 | //send_keypress(FING1_KEYCODE, 1); |
shervinemami | 1:2749e6ff50ce | 292 | HID_DEBUG("sent keypress %d for 1.\n\r"); |
shervinemami | 1:2749e6ff50ce | 293 | //counter2+=20; |
shervinemami | 1:2749e6ff50ce | 294 | //LOG("%d\n\r", counter2); |
shervinemami | 1:2749e6ff50ce | 295 | } |
shervinemami | 1:2749e6ff50ce | 296 | if (fing2 > FINGER2_PRESS && !press_keyup[2]) { |
shervinemami | 1:2749e6ff50ce | 297 | //send_keypress(FING2DOWN_KEYCODE, 2); |
shervinemami | 1:2749e6ff50ce | 298 | HID_DEBUG("sent keypress %d for 2.\n\r"); |
shervinemami | 1:2749e6ff50ce | 299 | // Finger 2 is treated differently. We want to be able to hold down finger 2 |
shervinemami | 1:2749e6ff50ce | 300 | // Without causing repeated keystrokes, so we will send an up press straight after the down press, |
shervinemami | 1:2749e6ff50ce | 301 | // and a different key down and up when the fingure is released, so the client software can |
shervinemami | 1:2749e6ff50ce | 302 | // figure out the duration that it was held for. |
shervinemami | 1:2749e6ff50ce | 303 | ble.waitForEvent(); // Add a slight delay |
shervinemami | 1:2749e6ff50ce | 304 | //wait(0.1); // Add a slight delay |
shervinemami | 1:2749e6ff50ce | 305 | //ble.waitForEvent(); // Add a slight delay |
shervinemami | 1:2749e6ff50ce | 306 | //kbdServicePtr->keyUpCode(); |
shervinemami | 1:2749e6ff50ce | 307 | HID_DEBUG("sent initial key up for 2.\n\r"); |
shervinemami | 1:2749e6ff50ce | 308 | } |
shervinemami | 1:2749e6ff50ce | 309 | if (fing3 > FINGER3_PRESS && !press_keyup[3]) { |
shervinemami | 1:2749e6ff50ce | 310 | //send_keypress(FING3_KEYCODE, 3); |
shervinemami | 1:2749e6ff50ce | 311 | HID_DEBUG("sent keypress %d for 3.\n\r"); |
shervinemami | 1:2749e6ff50ce | 312 | //counter2++; |
shervinemami | 1:2749e6ff50ce | 313 | //send_keypress(counter2, 3); |
shervinemami | 1:2749e6ff50ce | 314 | //LOG("%d\n\r", counter2); |
shervinemami | 1:2749e6ff50ce | 315 | |
shervinemami | 1:2749e6ff50ce | 316 | LOG("send scroll down\n\r"); |
shervinemami | 1:2749e6ff50ce | 317 | mouseServicePtr->setSpeed(0, 0, 1); |
shervinemami | 1:2749e6ff50ce | 318 | |
shervinemami | 1:2749e6ff50ce | 319 | wait(0.05); // Add a slight delay |
shervinemami | 1:2749e6ff50ce | 320 | ble.waitForEvent(); // Add a slight delay |
shervinemami | 1:2749e6ff50ce | 321 | |
shervinemami | 1:2749e6ff50ce | 322 | mouseServicePtr->setSpeed(0, 0, 0); |
shervinemami | 1:2749e6ff50ce | 323 | |
shervinemami | 1:2749e6ff50ce | 324 | } |
shervinemami | 1:2749e6ff50ce | 325 | if (fing4 > FINGER4_PRESS && !press_keyup[4]) { |
shervinemami | 1:2749e6ff50ce | 326 | //send_keypress(FING4_KEYCODE, 4); |
shervinemami | 1:2749e6ff50ce | 327 | HID_DEBUG("sent keypress %d for 4.\n\r"); |
shervinemami | 1:2749e6ff50ce | 328 | //counter2--; |
shervinemami | 1:2749e6ff50ce | 329 | //send_keypress(counter2, 4); |
shervinemami | 1:2749e6ff50ce | 330 | //LOG("%d\n\r", counter2); |
shervinemami | 1:2749e6ff50ce | 331 | |
shervinemami | 1:2749e6ff50ce | 332 | } |
shervinemami | 1:2749e6ff50ce | 333 | } |
YuuichiAkagawa | 0:3435302551b3 | 334 | } |
shervinemami | 1:2749e6ff50ce | 335 | } |