Geo beacon for VF.

Dependencies:   MMA8452 aconno_bsp adc52832_common

Committer:
jurica238814
Date:
Wed Jul 19 12:48:14 2017 +0000
Revision:
7:89c9abaa257e
Parent:
4:331dddea780e
Child:
12:6b072c2a061c
Short sleep time mechanism added.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jurica238814 1:5f34885f5cff 1 /*
jurica238814 0:f8c1e0b2d473 2 *
jurica238814 1:5f34885f5cff 3 * Made by Jurica Resetar @ aconno
jurica238814 1:5f34885f5cff 4 * aconno.de
jurica238814 4:331dddea780e 5 * All rights reserved.
jurica238814 0:f8c1e0b2d473 6 *
jurica238814 0:f8c1e0b2d473 7 */
jurica238814 0:f8c1e0b2d473 8
jurica238814 0:f8c1e0b2d473 9 #include "mbed.h"
jurica238814 0:f8c1e0b2d473 10 #include "ble/BLE.h"
jurica238814 1:5f34885f5cff 11 #include "GapAdvertisingData.h"
jurica238814 0:f8c1e0b2d473 12 #include "acd52832_bsp.h"
jurica238814 1:5f34885f5cff 13
jurica238814 7:89c9abaa257e 14 #define SLEEP_TIME (5.0) // Sleep time in seconds
jurica238814 7:89c9abaa257e 15 #define SHORT_SLEEP_TIME (0.5) // Shorter sleep time (s)
jurica238814 7:89c9abaa257e 16 #define SHORT_SLEEP_TIME_PERIOD (60) // Time after a last scanned advertisment. In the period, sleep time is SHORT_SLEEP_TIME
jurica238814 7:89c9abaa257e 17 #define AWAKE_TIME (0.25) // Was 0.15 -> Was not enough
jurica238814 7:89c9abaa257e 18 #define BUZZER (p31)
jurica238814 0:f8c1e0b2d473 19
jurica238814 1:5f34885f5cff 20 /* Static constants for the BLE example */
jurica238814 3:2a4ac5b87046 21 #define MAX_BLE_PACKET_SIZE (31)
jurica238814 3:2a4ac5b87046 22 #define MSD_SIZE (18)
jurica238814 3:2a4ac5b87046 23 #define MSD_ID (0xFF)
jurica238814 7:89c9abaa257e 24 #define BUZZ_TIME (2.0) // Buzz time in s
jurica238814 1:5f34885f5cff 25
jurica238814 0:f8c1e0b2d473 26
jurica238814 0:f8c1e0b2d473 27 bool SLEEP = true;
jurica238814 7:89c9abaa257e 28 uint8_t tempSleepTime = SLEEP_TIME;
jurica238814 0:f8c1e0b2d473 29 int8_t txPower = 4;
jurica238814 1:5f34885f5cff 30 uint8_t MSD[MSD_SIZE] = {0x59, 0x00, 0xE1, 0x61, 0x35, 0xBA, 0xC0, 0xEC, 0x47, 0x2A, 0x98, 0x00, 0xAF, 0x18, 0x43, 0xFF, 0x05, 0x00};
jurica238814 1:5f34885f5cff 31 uint8_t my_mac_address[6] = {};
jurica238814 0:f8c1e0b2d473 32
jurica238814 2:5504b714c9ae 33 void turnBuzzOff(void);
jurica238814 2:5504b714c9ae 34 void goToSleep();
jurica238814 0:f8c1e0b2d473 35
jurica238814 2:5504b714c9ae 36 Ticker WakeSleepT;
jurica238814 2:5504b714c9ae 37 Ticker turnBuzzOffT;
jurica238814 7:89c9abaa257e 38 Ticker sleepChanger;
jurica238814 1:5f34885f5cff 39 PwmOut buzzer(BUZZER);
jurica238814 1:5f34885f5cff 40 BLE &ble = BLE::Instance();
jurica238814 2:5504b714c9ae 41
jurica238814 0:f8c1e0b2d473 42 /* Restart Advertising on disconnection*/
jurica238814 0:f8c1e0b2d473 43 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params){
jurica238814 0:f8c1e0b2d473 44 BLE::Instance().gap().startAdvertising();
jurica238814 0:f8c1e0b2d473 45 }
jurica238814 0:f8c1e0b2d473 46
jurica238814 0:f8c1e0b2d473 47
jurica238814 0:f8c1e0b2d473 48 /**
jurica238814 0:f8c1e0b2d473 49 * This function is called when the ble initialization process has failed
jurica238814 0:f8c1e0b2d473 50 */
jurica238814 0:f8c1e0b2d473 51 void onBleInitError(BLE &ble, ble_error_t error){
jurica238814 0:f8c1e0b2d473 52 /* Avoid compiler warnings */
jurica238814 0:f8c1e0b2d473 53 (void) ble;
jurica238814 0:f8c1e0b2d473 54 (void) error;
jurica238814 0:f8c1e0b2d473 55 /* Initialization error handling should go here */
jurica238814 0:f8c1e0b2d473 56 }
jurica238814 0:f8c1e0b2d473 57
jurica238814 0:f8c1e0b2d473 58 /**
jurica238814 0:f8c1e0b2d473 59 * Callback triggered when the ble initialization process has finished
jurica238814 0:f8c1e0b2d473 60 */
jurica238814 0:f8c1e0b2d473 61 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params){
jurica238814 0:f8c1e0b2d473 62 BLE& ble = params->ble;
jurica238814 0:f8c1e0b2d473 63 ble_error_t error = params->error;
jurica238814 0:f8c1e0b2d473 64
jurica238814 0:f8c1e0b2d473 65 if (error != BLE_ERROR_NONE) {
jurica238814 0:f8c1e0b2d473 66 /* In case of error, forward the error handling to onBleInitError */
jurica238814 0:f8c1e0b2d473 67 onBleInitError(ble, error);
jurica238814 0:f8c1e0b2d473 68 return;
jurica238814 0:f8c1e0b2d473 69 }
jurica238814 0:f8c1e0b2d473 70
jurica238814 0:f8c1e0b2d473 71 /* Ensure that it is the default instance of BLE */
jurica238814 0:f8c1e0b2d473 72 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
jurica238814 0:f8c1e0b2d473 73 return;
jurica238814 0:f8c1e0b2d473 74 }
jurica238814 0:f8c1e0b2d473 75
jurica238814 0:f8c1e0b2d473 76 ble.gap().onDisconnection(disconnectionCallback);
jurica238814 0:f8c1e0b2d473 77
jurica238814 1:5f34885f5cff 78 /* Get my MAC address */
jurica238814 1:5f34885f5cff 79 BLEProtocol::AddressType_t temp_address_type;
jurica238814 1:5f34885f5cff 80 ble.gap().getAddress(&temp_address_type, my_mac_address);
jurica238814 1:5f34885f5cff 81
jurica238814 1:5f34885f5cff 82
jurica238814 0:f8c1e0b2d473 83 /* setup advertising */
jurica238814 0:f8c1e0b2d473 84 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
jurica238814 1:5f34885f5cff 85 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)MSD, MSD_SIZE);
jurica238814 0:f8c1e0b2d473 86 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
jurica238814 2:5504b714c9ae 87 ble.gap().setAdvertisingInterval(100); // --> Has to be at least 100ms!
jurica238814 2:5504b714c9ae 88 ble.gap().startAdvertising();
jurica238814 0:f8c1e0b2d473 89 }
jurica238814 0:f8c1e0b2d473 90
jurica238814 3:2a4ac5b87046 91
jurica238814 3:2a4ac5b87046 92 uint8_t findMSDIndex(const Gap::AdvertisementCallbackParams_t *params){
jurica238814 1:5f34885f5cff 93 uint8_t i=0;
jurica238814 3:2a4ac5b87046 94 uint8_t len;
jurica238814 3:2a4ac5b87046 95
jurica238814 3:2a4ac5b87046 96 do{
jurica238814 3:2a4ac5b87046 97 len = params->advertisingData[i];
jurica238814 3:2a4ac5b87046 98 i++;
jurica238814 3:2a4ac5b87046 99 if(params->advertisingData[i] == MSD_ID) return i;
jurica238814 3:2a4ac5b87046 100 else i += (len-1);
jurica238814 3:2a4ac5b87046 101 }while(i<MAX_BLE_PACKET_SIZE);
jurica238814 3:2a4ac5b87046 102
jurica238814 3:2a4ac5b87046 103 return 0;
jurica238814 3:2a4ac5b87046 104 }
jurica238814 3:2a4ac5b87046 105
jurica238814 3:2a4ac5b87046 106 /**
jurica238814 3:2a4ac5b87046 107 * Function is called when BLE radio discovers any kind of advertisment
jurica238814 3:2a4ac5b87046 108 */
jurica238814 3:2a4ac5b87046 109 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params){
jurica238814 3:2a4ac5b87046 110 uint8_t i=0;
jurica238814 3:2a4ac5b87046 111 uint8_t msdOffset;
jurica238814 3:2a4ac5b87046 112
jurica238814 3:2a4ac5b87046 113 msdOffset = findMSDIndex(params);
jurica238814 3:2a4ac5b87046 114 if(msdOffset == 0){
jurica238814 3:2a4ac5b87046 115 // There's no MSD in BLE advertisement data
jurica238814 3:2a4ac5b87046 116 return;
jurica238814 3:2a4ac5b87046 117 }
jurica238814 3:2a4ac5b87046 118
jurica238814 3:2a4ac5b87046 119 if ((params->advertisingData[msdOffset]) == MSD_ID){
jurica238814 1:5f34885f5cff 120 // Follows Manufacturer Specific Data
jurica238814 3:2a4ac5b87046 121 if ((params->advertisingData[msdOffset+1]) == 0x59){
jurica238814 3:2a4ac5b87046 122 if ((params->advertisingData[msdOffset+2]) == 0x00){
jurica238814 1:5f34885f5cff 123 for(i=0; i<6; i++){
jurica238814 3:2a4ac5b87046 124 if((params->advertisingData[msdOffset+i+3]) == my_mac_address[5-i]){
jurica238814 1:5f34885f5cff 125 continue;
jurica238814 1:5f34885f5cff 126 }
jurica238814 1:5f34885f5cff 127 else{
jurica238814 1:5f34885f5cff 128 return;
jurica238814 1:5f34885f5cff 129 }
jurica238814 1:5f34885f5cff 130 }
jurica238814 2:5504b714c9ae 131 turnBuzzOffT.detach();
jurica238814 2:5504b714c9ae 132 WakeSleepT.detach();
jurica238814 2:5504b714c9ae 133 buzzer.write(0.5F);
jurica238814 2:5504b714c9ae 134 turnBuzzOffT.attach(turnBuzzOff, BUZZ_TIME);
jurica238814 1:5f34885f5cff 135 }
jurica238814 1:5f34885f5cff 136 }
jurica238814 2:5504b714c9ae 137 }
jurica238814 2:5504b714c9ae 138 }
jurica238814 2:5504b714c9ae 139
jurica238814 7:89c9abaa257e 140 /* Call this function few minutes (TBD) after a last scanned advertisment */
jurica238814 7:89c9abaa257e 141 void changeSleepTime(){
jurica238814 7:89c9abaa257e 142 tempSleepTime = SLEEP_TIME;
jurica238814 7:89c9abaa257e 143 sleepChanger.detach();
jurica238814 7:89c9abaa257e 144 }
jurica238814 7:89c9abaa257e 145
jurica238814 7:89c9abaa257e 146 /**
jurica238814 7:89c9abaa257e 147 * The function is called when ticker generates interrupt
jurica238814 7:89c9abaa257e 148 */
jurica238814 7:89c9abaa257e 149 void turnBuzzOff(void){
jurica238814 7:89c9abaa257e 150 buzzer.write(0.0F);
jurica238814 7:89c9abaa257e 151 tempSleepTime = SHORT_SLEEP_TIME;
jurica238814 7:89c9abaa257e 152 turnBuzzOffT.detach();
jurica238814 7:89c9abaa257e 153 WakeSleepT.attach(goToSleep, AWAKE_TIME);
jurica238814 7:89c9abaa257e 154 sleepChanger.attach(changeSleepTime, SHORT_SLEEP_TIME_PERIOD);
jurica238814 7:89c9abaa257e 155 }
jurica238814 7:89c9abaa257e 156
jurica238814 2:5504b714c9ae 157 void WakeMeUp(){
jurica238814 2:5504b714c9ae 158 WakeSleepT.detach();
jurica238814 2:5504b714c9ae 159 WakeSleepT.attach(goToSleep, AWAKE_TIME);
jurica238814 2:5504b714c9ae 160
jurica238814 2:5504b714c9ae 161 ble.gap().startScan(advertisementCallback);
jurica238814 2:5504b714c9ae 162 ble.gap().startAdvertising();
jurica238814 2:5504b714c9ae 163 SLEEP = false;
jurica238814 2:5504b714c9ae 164 }
jurica238814 2:5504b714c9ae 165
jurica238814 2:5504b714c9ae 166 void goToSleep(){
jurica238814 2:5504b714c9ae 167 WakeSleepT.detach();
jurica238814 7:89c9abaa257e 168 WakeSleepT.attach(WakeMeUp, tempSleepTime);
jurica238814 2:5504b714c9ae 169
jurica238814 2:5504b714c9ae 170 ble.gap().stopAdvertising();
jurica238814 2:5504b714c9ae 171 ble.gap().stopScan();
jurica238814 2:5504b714c9ae 172 SLEEP = true;
jurica238814 1:5f34885f5cff 173 }
jurica238814 1:5f34885f5cff 174
jurica238814 0:f8c1e0b2d473 175 int main(void){
jurica238814 2:5504b714c9ae 176 WakeSleepT.attach(goToSleep, AWAKE_TIME);
jurica238814 0:f8c1e0b2d473 177 ble.init(bleInitComplete);
jurica238814 0:f8c1e0b2d473 178 ble.gap().setTxPower(txPower);
jurica238814 0:f8c1e0b2d473 179 GapAdvertisingData postavke = GapAdvertisingData();
jurica238814 0:f8c1e0b2d473 180
jurica238814 2:5504b714c9ae 181 ble.gap().setScanParams(100, 100);
jurica238814 1:5f34885f5cff 182 ble.gap().startScan(advertisementCallback);
jurica238814 1:5f34885f5cff 183
jurica238814 7:89c9abaa257e 184 buzzer.period(0.0009F);
jurica238814 1:5f34885f5cff 185 buzzer.write(0.0F);
jurica238814 0:f8c1e0b2d473 186
jurica238814 2:5504b714c9ae 187 __enable_irq();
jurica238814 2:5504b714c9ae 188
jurica238814 0:f8c1e0b2d473 189 /* SpinWait for initialization to complete. This is necessary because the
jurica238814 0:f8c1e0b2d473 190 * BLE object is used in the main loop below. */
jurica238814 3:2a4ac5b87046 191 while (ble.hasInitialized() == false){
jurica238814 3:2a4ac5b87046 192 /* spin loop */
jurica238814 3:2a4ac5b87046 193 }
jurica238814 1:5f34885f5cff 194
jurica238814 1:5f34885f5cff 195 while(true){
jurica238814 3:2a4ac5b87046 196 if(SLEEP) __WFI();
jurica238814 3:2a4ac5b87046 197 else ble.waitForEvent();
jurica238814 0:f8c1e0b2d473 198 }
jurica238814 0:f8c1e0b2d473 199 }