BLE code for touch signal
Dependencies: BLE_API mbed nRF51822
Fork of BLE_GATT_Example by
main.cpp
- Committer:
- mk5814
- Date:
- 2017-06-29
- Revision:
- 23:721f64d359ff
- Parent:
- 22:406127954d1f
File content as of revision 23:721f64d359ff:
#include "mbed.h" #include "ble/BLE.h" #define THRESHOLD_PRESS 0.08 #define TIME_BETWEEN_TOUCH 0.05 #define TIME_BETWEEN_CYCLE 0.1 #define LEFT_PUSH 1 #define RIGHT_PUSH 2 #define LEFT_SWIPE 3 #define RIGHT_SWIPE 4 /* Four capacitive touch inputs; active low * Two on the left, two on the right, all in one row */ DigitalIn touch1(P0_12); DigitalIn touch2(P0_13); DigitalIn touch3(P0_14); DigitalIn touch4(P0_15); /* One pressure sensor input */ AnalogIn press(P0_1); /* One haptic input */ /* PwmOut haptic(P0_16); */ /* Choose custom GATT UUIDS and profile name */ uint16_t customServiceUUID = 0xA000; uint16_t readCharUUID = 0xA001; const static char DEVICE_NAME[] = "Touch Signal"; static const uint16_t uuid16_list[] = {0xA000}; /* Custom UUID, FFFF is reserved for development */ /* Variable used to search for inputs every 0.3 seconds and prevent connection timeout */ static volatile bool triggerSensorPolling = false; /* Ouput variable */ uint8_t readSignal = 0; /* Set up custom read characteristic*/ ReadOnlyGattCharacteristic<uint8_t> readChar(readCharUUID, &readSignal, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); /* Set up custom service */ GattCharacteristic *characteristics[] = {&readChar}; GattService customService(customServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *)); /* Restart advertising when phone app disconnects */ void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *){ BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); } void periodicCallback(void){ /* Note that the periodicCallback() executes in interrupt context, so it is safer to do * heavy-weight sensor polling from the main thread. */ triggerSensorPolling = true; } /* Initialization callback */ void bleInitComplete(BLE::InitializationCompleteCallbackContext *params){ BLE &ble = params->ble; ble_error_t error = params->error; if(error != BLE_ERROR_NONE){ return; } ble.gap().onDisconnection(disconnectionCallback); /* Setup advertising */ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); /* BLE only, no classic BT */ ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); /* Advertising type */ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); /* Add name */ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); /* UUID's broadcast in advertising packet */ ble.gap().setAdvertisingInterval(300); /* 300 ms */ /* Add custom service */ ble.addService(customService); /* Start advertising */ ble.gap().startAdvertising(); } void pressed(){ /* Check which side of capacitive touch pad is being touched */ if((touch1 == 0 || touch2 == 0) && (touch3 == 1 && touch4 == 1)){ /* Left push * Success buzz */ readSignal = LEFT_PUSH; } else if((touch3 == 0 || touch4 == 0) && (touch1 == 1 && touch2 == 1)){ /* Right push * Success buzz */ readSignal = RIGHT_PUSH; } /* If both sides are pressed, there is an error */ else{ /* Failure buzz */ wait(TIME_BETWEEN_CYCLE); } } /* Three out of four of the switches need to be touched in the correct order */ void swiped_right(){ /* Assign bool variable that turns true if no error: if true, then there is a swipe */ bool checkSwipe = false; /* Variables used for polling */ int i, j; /* If the leftmost switch is touched, check if the next one is touched */ if(touch1 == 0){ /* If both left switches are touched, only one of the right switches need to be touched */ if(touch2 == 0){ /* Variables i and j are used for polling in a while loop 5 times to search for a touch * If the required input is sensed it exits the while loop to sense the next input or make checkSwipe true * Every time there is no input i or j increments * If no input is sensed and i = 5 or j = 5, then it exits the while loop to keep checkSwipe false */ i = 5; while(i > 0){ wait(TIME_BETWEEN_TOUCH); /* If one of the right switches are touched next, then checkSwipe is true */ if(touch3 == 0 || touch4 == 0){ checkSwipe = true; i = 0; } else{ i--; } } } else{ i = 5; while(i > 0){ wait(TIME_BETWEEN_TOUCH); /* If only the leftmost switch is touched, check if the other left switch is touched */ if(touch2 == 0){ j = 5; while(j > 0){ wait(TIME_BETWEEN_TOUCH); /* If both left switches are touched, only one of the right switches need to be touched for checkSwipe to be true */ if(touch3 == 0 || touch4 == 0){ checkSwipe = true; j = 0; } else{ j--; } } i = 0; } /* If the leftmost switch is touched and the third switch after, only the rightmost switch needs to be touched */ else if(touch3 == 0){ j = 5; while(j > 0){ wait(TIME_BETWEEN_TOUCH); /* If the rightmost switch is touched, checkSwipe becomes true */ if(touch4 == 0){ checkSwipe = true; j = 0; } else{ j--; } } } else{ i--; } } } } /* If only the second switchs is touched, the two right switches need to be touched */ else{ i = 5; while(i > 0){ wait(TIME_BETWEEN_TOUCH); /* If the third switch is touched, check if the rightmost switch is touched */ if(touch3 == 0){ j = 5; while(j > 5){ wait(TIME_BETWEEN_TOUCH); /* If the rightmost switch is touched, checkSwipe becomes true */ if(touch4 == 0){ checkSwipe = true; j = 0; } else{ j--; } } i = 0; } else{ i--; } } } /* If checkSwipe is true, then there was a swipe gesture */ if(checkSwipe){ /* Right swipe * Success buzz */ readSignal = RIGHT_SWIPE; } /* If checkswipe is false, then there was an error */ else{ /* Failure buzz */ wait(TIME_BETWEEN_CYCLE); } } /* Three out of four of the switches need to be touched in the correct order * Same as swiped_right except in opposite direction */ void swiped_left(){ bool checkSwipe = false; int i, j; if(touch4 == 0){ if(touch3 == 0){ i = 5; while(i > 0){ wait(TIME_BETWEEN_TOUCH); if(touch2 == 0 || touch1 == 0){ checkSwipe = true; i = 0; } else{ i--; } } } else{ i = 5; while(i > 0){ wait(TIME_BETWEEN_TOUCH); if(touch3 == 0){ j = 5; while(j > 0){ wait(TIME_BETWEEN_TOUCH); if(touch2 == 0 || touch1 == 0){ checkSwipe = true; j = 0; } else{ j--; } } i = 0; } else if(touch2 == 0){ j = 5; while(j > 0){ wait(TIME_BETWEEN_TOUCH); if(touch1 == 0){ checkSwipe = true; j = 0; } else{ j--; } } } else{ i--; } } } } else{ i = 5; while(i > 0){ wait(TIME_BETWEEN_TOUCH); if(touch2 == 0){ j = 5; while(j > 5){ wait(TIME_BETWEEN_TOUCH); if(touch1 == 0){ checkSwipe = true; j = 0; } else{ j--; } } i = 0; } else{ i--; } } } if(checkSwipe){ /* Left swipe * Success buzz */ readSignal = LEFT_SWIPE; } else{ /* Failure buzz */ wait(TIME_BETWEEN_CYCLE); } } /* Main loop */ int main(){ /* Setup of recurring interrupt to look for inputs every 0.3 seconds */ Ticker ticker; ticker.attach(periodicCallback, 0.3); /* Initialise BLE */ BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); ble.init(bleInitComplete); /* SpinWait for initialization to complete. This is necessary because the * BLE object is used in the main loop below. */ while(ble.hasInitialized() == false){/* Spin loop */} /* Infinite loop waiting for BLE interrupt events */ while(1){ /* Check for trigger from periodicCallback() */ if(triggerSensorPolling && ble.getGapState().connected){ triggerSensorPolling = false; /* Check if touch pad is pressed beyond threshold for pressing gesture */ if(press > THRESHOLD_PRESS){ pressed(); } /* Check if touch pad is touched on one side for swiping gesture * A touch on the left side would potentially be a right swipe */ else if((touch1 == 0 || touch2 == 0) && (touch3 == 1 && touch4 == 1)){ swiped_right(); } /* A touch on the right side would potentially be a left swipe */ else if((touch4 == 0 || touch3 == 0) && (touch2 == 1 && touch1 == 1)){ swiped_left(); } /* Input is not sent via Bluetooth if 0 * If not 0, send and reset to 0 for next input cycle */ if(readSignal != 0){ ble.updateCharacteristicValue(readChar.getValueHandle(), &readSignal, 1); readSignal = 0; wait(TIME_BETWEEN_CYCLE); } } else{ ble.waitForEvent(); /* Low power wait for event */ } } }