Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BLE_API mbed nRF51822
Fork of BLE_GATT_Example by
main.cpp
00001 #include "mbed.h" 00002 #include "ble/BLE.h" 00003 00004 #define THRESHOLD_PRESS 0.08 00005 #define TIME_BETWEEN_TOUCH 0.05 00006 #define TIME_BETWEEN_CYCLE 0.1 00007 00008 #define LEFT_PUSH 1 00009 #define RIGHT_PUSH 2 00010 #define LEFT_SWIPE 3 00011 #define RIGHT_SWIPE 4 00012 00013 /* Four capacitive touch inputs; active low 00014 * Two on the left, two on the right, all in one row */ 00015 DigitalIn touch1(P0_12); 00016 DigitalIn touch2(P0_13); 00017 DigitalIn touch3(P0_14); 00018 DigitalIn touch4(P0_15); 00019 00020 /* One pressure sensor input */ 00021 AnalogIn press(P0_1); 00022 00023 /* One haptic input */ 00024 /* PwmOut haptic(P0_16); */ 00025 00026 /* Choose custom GATT UUIDS and profile name */ 00027 uint16_t customServiceUUID = 0xA000; 00028 uint16_t readCharUUID = 0xA001; 00029 const static char DEVICE_NAME[] = "Touch Signal"; 00030 static const uint16_t uuid16_list[] = {0xA000}; /* Custom UUID, FFFF is reserved for development */ 00031 00032 /* Variable used to search for inputs every 0.3 seconds and prevent connection timeout */ 00033 static volatile bool triggerSensorPolling = false; 00034 00035 /* Ouput variable */ 00036 uint8_t readSignal = 0; 00037 00038 /* Set up custom read characteristic*/ 00039 ReadOnlyGattCharacteristic<uint8_t> readChar(readCharUUID, &readSignal, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); 00040 00041 /* Set up custom service */ 00042 GattCharacteristic *characteristics[] = {&readChar}; 00043 GattService customService(customServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *)); 00044 00045 /* Restart advertising when phone app disconnects */ 00046 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *){ 00047 BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); 00048 } 00049 00050 void periodicCallback(void){ 00051 /* Note that the periodicCallback() executes in interrupt context, so it is safer to do 00052 * heavy-weight sensor polling from the main thread. */ 00053 triggerSensorPolling = true; 00054 } 00055 00056 /* Initialization callback */ 00057 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params){ 00058 BLE &ble = params->ble; 00059 ble_error_t error = params->error; 00060 if(error != BLE_ERROR_NONE){ 00061 return; 00062 } 00063 ble.gap().onDisconnection(disconnectionCallback); 00064 /* Setup advertising */ 00065 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); /* BLE only, no classic BT */ 00066 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); /* Advertising type */ 00067 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); /* Add name */ 00068 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); /* UUID's broadcast in advertising packet */ 00069 ble.gap().setAdvertisingInterval(300); /* 300 ms */ 00070 /* Add custom service */ 00071 ble.addService(customService); 00072 /* Start advertising */ 00073 ble.gap().startAdvertising(); 00074 } 00075 00076 void pressed(){ 00077 /* Check which side of capacitive touch pad is being touched */ 00078 if((touch1 == 0 || touch2 == 0) && (touch3 == 1 && touch4 == 1)){ 00079 /* Left push 00080 * Success buzz */ 00081 readSignal = LEFT_PUSH; 00082 } 00083 else if((touch3 == 0 || touch4 == 0) && (touch1 == 1 && touch2 == 1)){ 00084 /* Right push 00085 * Success buzz */ 00086 readSignal = RIGHT_PUSH; 00087 } 00088 /* If both sides are pressed, there is an error */ 00089 else{ 00090 /* Failure buzz */ 00091 wait(TIME_BETWEEN_CYCLE); 00092 } 00093 } 00094 00095 /* Three out of four of the switches need to be touched in the correct order */ 00096 void swiped_right(){ 00097 /* Assign bool variable that turns true if no error: if true, then there is a swipe */ 00098 bool checkSwipe = false; 00099 /* Variables used for polling */ 00100 int i, j; 00101 /* If the leftmost switch is touched, check if the next one is touched */ 00102 if(touch1 == 0){ 00103 /* If both left switches are touched, only one of the right switches need to be touched */ 00104 if(touch2 == 0){ 00105 /* Variables i and j are used for polling in a while loop 5 times to search for a touch 00106 * If the required input is sensed it exits the while loop to sense the next input or make checkSwipe true 00107 * Every time there is no input i or j increments 00108 * If no input is sensed and i = 5 or j = 5, then it exits the while loop to keep checkSwipe false */ 00109 i = 5; 00110 while(i > 0){ 00111 wait(TIME_BETWEEN_TOUCH); 00112 /* If one of the right switches are touched next, then checkSwipe is true */ 00113 if(touch3 == 0 || touch4 == 0){ 00114 checkSwipe = true; 00115 i = 0; 00116 } 00117 else{ 00118 i--; 00119 } 00120 } 00121 } 00122 else{ 00123 i = 5; 00124 while(i > 0){ 00125 wait(TIME_BETWEEN_TOUCH); 00126 /* If only the leftmost switch is touched, check if the other left switch is touched */ 00127 if(touch2 == 0){ 00128 j = 5; 00129 while(j > 0){ 00130 wait(TIME_BETWEEN_TOUCH); 00131 /* If both left switches are touched, only one of the right switches need to be touched for checkSwipe to be true */ 00132 if(touch3 == 0 || touch4 == 0){ 00133 checkSwipe = true; 00134 j = 0; 00135 } 00136 else{ 00137 j--; 00138 } 00139 } 00140 i = 0; 00141 } 00142 /* If the leftmost switch is touched and the third switch after, only the rightmost switch needs to be touched */ 00143 else if(touch3 == 0){ 00144 j = 5; 00145 while(j > 0){ 00146 wait(TIME_BETWEEN_TOUCH); 00147 /* If the rightmost switch is touched, checkSwipe becomes true */ 00148 if(touch4 == 0){ 00149 checkSwipe = true; 00150 j = 0; 00151 } 00152 else{ 00153 j--; 00154 } 00155 } 00156 } 00157 else{ 00158 i--; 00159 } 00160 } 00161 } 00162 } 00163 /* If only the second switchs is touched, the two right switches need to be touched */ 00164 else{ 00165 i = 5; 00166 while(i > 0){ 00167 wait(TIME_BETWEEN_TOUCH); 00168 /* If the third switch is touched, check if the rightmost switch is touched */ 00169 if(touch3 == 0){ 00170 j = 5; 00171 while(j > 5){ 00172 wait(TIME_BETWEEN_TOUCH); 00173 /* If the rightmost switch is touched, checkSwipe becomes true */ 00174 if(touch4 == 0){ 00175 checkSwipe = true; 00176 j = 0; 00177 } 00178 else{ 00179 j--; 00180 } 00181 } 00182 i = 0; 00183 } 00184 else{ 00185 i--; 00186 } 00187 } 00188 } 00189 /* If checkSwipe is true, then there was a swipe gesture */ 00190 if(checkSwipe){ 00191 /* Right swipe 00192 * Success buzz */ 00193 readSignal = RIGHT_SWIPE; 00194 } 00195 /* If checkswipe is false, then there was an error */ 00196 else{ 00197 /* Failure buzz */ 00198 wait(TIME_BETWEEN_CYCLE); 00199 } 00200 } 00201 00202 /* Three out of four of the switches need to be touched in the correct order 00203 * Same as swiped_right except in opposite direction */ 00204 void swiped_left(){ 00205 bool checkSwipe = false; 00206 int i, j; 00207 if(touch4 == 0){ 00208 if(touch3 == 0){ 00209 i = 5; 00210 while(i > 0){ 00211 wait(TIME_BETWEEN_TOUCH); 00212 if(touch2 == 0 || touch1 == 0){ 00213 checkSwipe = true; 00214 i = 0; 00215 } 00216 else{ 00217 i--; 00218 } 00219 } 00220 } 00221 else{ 00222 i = 5; 00223 while(i > 0){ 00224 wait(TIME_BETWEEN_TOUCH); 00225 if(touch3 == 0){ 00226 j = 5; 00227 while(j > 0){ 00228 wait(TIME_BETWEEN_TOUCH); 00229 if(touch2 == 0 || touch1 == 0){ 00230 checkSwipe = true; 00231 j = 0; 00232 } 00233 else{ 00234 j--; 00235 } 00236 } 00237 i = 0; 00238 } 00239 else if(touch2 == 0){ 00240 j = 5; 00241 while(j > 0){ 00242 wait(TIME_BETWEEN_TOUCH); 00243 if(touch1 == 0){ 00244 checkSwipe = true; 00245 j = 0; 00246 } 00247 else{ 00248 j--; 00249 } 00250 } 00251 } 00252 else{ 00253 i--; 00254 } 00255 } 00256 } 00257 } 00258 else{ 00259 i = 5; 00260 while(i > 0){ 00261 wait(TIME_BETWEEN_TOUCH); 00262 if(touch2 == 0){ 00263 j = 5; 00264 while(j > 5){ 00265 wait(TIME_BETWEEN_TOUCH); 00266 if(touch1 == 0){ 00267 checkSwipe = true; 00268 j = 0; 00269 } 00270 else{ 00271 j--; 00272 } 00273 } 00274 i = 0; 00275 } 00276 else{ 00277 i--; 00278 } 00279 } 00280 } 00281 if(checkSwipe){ 00282 /* Left swipe 00283 * Success buzz */ 00284 readSignal = LEFT_SWIPE; 00285 } 00286 else{ 00287 /* Failure buzz */ 00288 wait(TIME_BETWEEN_CYCLE); 00289 } 00290 } 00291 00292 /* Main loop */ 00293 int main(){ 00294 00295 /* Setup of recurring interrupt to look for inputs every 0.3 seconds */ 00296 Ticker ticker; 00297 ticker.attach(periodicCallback, 0.3); 00298 00299 /* Initialise BLE */ 00300 BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); 00301 ble.init(bleInitComplete); 00302 00303 /* SpinWait for initialization to complete. This is necessary because the 00304 * BLE object is used in the main loop below. */ 00305 while(ble.hasInitialized() == false){/* Spin loop */} 00306 00307 /* Infinite loop waiting for BLE interrupt events */ 00308 while(1){ 00309 /* Check for trigger from periodicCallback() */ 00310 if(triggerSensorPolling && ble.getGapState().connected){ 00311 triggerSensorPolling = false; 00312 /* Check if touch pad is pressed beyond threshold for pressing gesture */ 00313 if(press > THRESHOLD_PRESS){ 00314 pressed(); 00315 } 00316 /* Check if touch pad is touched on one side for swiping gesture 00317 * A touch on the left side would potentially be a right swipe */ 00318 else if((touch1 == 0 || touch2 == 0) && (touch3 == 1 && touch4 == 1)){ 00319 swiped_right(); 00320 } 00321 /* A touch on the right side would potentially be a left swipe */ 00322 else if((touch4 == 0 || touch3 == 0) && (touch2 == 1 && touch1 == 1)){ 00323 swiped_left(); 00324 } 00325 /* Input is not sent via Bluetooth if 0 00326 * If not 0, send and reset to 0 for next input cycle */ 00327 if(readSignal != 0){ 00328 ble.updateCharacteristicValue(readChar.getValueHandle(), &readSignal, 1); 00329 readSignal = 0; 00330 wait(TIME_BETWEEN_CYCLE); 00331 } 00332 } 00333 else{ 00334 ble.waitForEvent(); /* Low power wait for event */ 00335 } 00336 } 00337 }
Generated on Sat Jul 16 2022 21:51:12 by
1.7.2
