Geo beacon for VF.
Dependencies: MMA8452 aconno_bsp adc52832_common
main.cpp@7:89c9abaa257e, 2017-07-19 (annotated)
- 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?
User | Revision | Line number | New 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 | } |