BLE ADV sensor for 2-pin interrupt (i.e. window/door sensor w/ reed switch)

Dependencies:   BLE_API mbed nRF51822

Basic door/window sensor for nRF51822 BLE modules.

Committer:
andresag
Date:
Tue Jan 12 10:12:43 2016 +0000
Revision:
7:0a8bbb6dea16
Parent:
5:f4d74a8cad43
Child:
8:46c5e0bfab05
Update example to latest BLE API.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sunsmile2015 0:3dc6e424dba0 1 /* mbed Microcontroller Library
sunsmile2015 0:3dc6e424dba0 2 * Copyright (c) 2006-2015 ARM Limited
sunsmile2015 0:3dc6e424dba0 3 *
sunsmile2015 0:3dc6e424dba0 4 * Licensed under the Apache License, Version 2.0 (the "License");
sunsmile2015 0:3dc6e424dba0 5 * you may not use this file except in compliance with the License.
sunsmile2015 0:3dc6e424dba0 6 * You may obtain a copy of the License at
sunsmile2015 0:3dc6e424dba0 7 *
sunsmile2015 0:3dc6e424dba0 8 * http://www.apache.org/licenses/LICENSE-2.0
sunsmile2015 0:3dc6e424dba0 9 *
sunsmile2015 0:3dc6e424dba0 10 * Unless required by applicable law or agreed to in writing, software
sunsmile2015 0:3dc6e424dba0 11 * distributed under the License is distributed on an "AS IS" BASIS,
sunsmile2015 0:3dc6e424dba0 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
sunsmile2015 0:3dc6e424dba0 13 * See the License for the specific language governing permissions and
sunsmile2015 0:3dc6e424dba0 14 * limitations under the License.
sunsmile2015 0:3dc6e424dba0 15 */
sunsmile2015 0:3dc6e424dba0 16
sunsmile2015 0:3dc6e424dba0 17 #include "mbed.h"
rgrover1 5:f4d74a8cad43 18 #include "toolchain.h"
sunsmile2015 0:3dc6e424dba0 19 #include "ble/BLE.h"
sunsmile2015 0:3dc6e424dba0 20 #include "TMP_nrf51/TMP_nrf51.h"
sunsmile2015 0:3dc6e424dba0 21
andresag 7:0a8bbb6dea16 22 static Ticker ticker;
rgrover1 5:f4d74a8cad43 23 static TMP_nrf51 tempSensor;
rgrover1 5:f4d74a8cad43 24 static bool triggerTempValueUpdate = false;
rgrover1 5:f4d74a8cad43 25 static DigitalOut alivenessLED(LED1, 1);
rgrover1 5:f4d74a8cad43 26
sunsmile2015 4:e5fa4c8838db 27 struct ApplicationData_t {
rgrover1 5:f4d74a8cad43 28 uint16_t applicationSpecificId; /* An ID used to identify temperature value in the manufacture specific AD data field */
rgrover1 5:f4d74a8cad43 29 TMP_nrf51::TempSensorValue_t tmpSensorValue; /* User defined application data */
rgrover1 5:f4d74a8cad43 30 } PACKED;
sunsmile2015 0:3dc6e424dba0 31
sunsmile2015 2:b935358da5ba 32 void periodicCallback(void)
sunsmile2015 2:b935358da5ba 33 {
rgrover1 5:f4d74a8cad43 34 alivenessLED = !alivenessLED; /* Do blinky on LED1 while we're waiting for BLE events. */
rgrover1 5:f4d74a8cad43 35
rgrover1 5:f4d74a8cad43 36 /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
rgrover1 5:f4d74a8cad43 37 * heavy-weight sensor polling from the main thread (where we should be able to block safely, if needed). */
sunsmile2015 4:e5fa4c8838db 38 triggerTempValueUpdate = true;
sunsmile2015 4:e5fa4c8838db 39 }
sunsmile2015 4:e5fa4c8838db 40
rgrover1 5:f4d74a8cad43 41 void setupApplicationData(ApplicationData_t &appData)
sunsmile2015 4:e5fa4c8838db 42 {
rgrover1 5:f4d74a8cad43 43 static const uint16_t APP_SPECIFIC_ID_TEST = 0xFEFE;
andresag 7:0a8bbb6dea16 44
sunsmile2015 4:e5fa4c8838db 45 appData.applicationSpecificId = APP_SPECIFIC_ID_TEST;
rgrover1 5:f4d74a8cad43 46 appData.tmpSensorValue = tempSensor.get();
sunsmile2015 0:3dc6e424dba0 47 }
sunsmile2015 0:3dc6e424dba0 48
andresag 7:0a8bbb6dea16 49 /**
andresag 7:0a8bbb6dea16 50 * This function is called when the ble initialization process has failled
andresag 7:0a8bbb6dea16 51 */
andresag 7:0a8bbb6dea16 52 void onBleInitError(BLE &ble, ble_error_t error)
andresag 7:0a8bbb6dea16 53 {
andresag 7:0a8bbb6dea16 54 /* Initialization error handling should go here */
andresag 7:0a8bbb6dea16 55 }
andresag 7:0a8bbb6dea16 56
andresag 7:0a8bbb6dea16 57 /**
andresag 7:0a8bbb6dea16 58 * Callback triggered when the ble initialization process has finished
andresag 7:0a8bbb6dea16 59 */
andresag 7:0a8bbb6dea16 60 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
sunsmile2015 2:b935358da5ba 61 {
andresag 7:0a8bbb6dea16 62 BLE& ble = params->ble;
andresag 7:0a8bbb6dea16 63 ble_error_t error = params->error;
andresag 7:0a8bbb6dea16 64
andresag 7:0a8bbb6dea16 65 if (error != BLE_ERROR_NONE) {
andresag 7:0a8bbb6dea16 66 /* In case of error, forward the error handling to onBleInitError */
andresag 7:0a8bbb6dea16 67 onBleInitError(ble, error);
andresag 7:0a8bbb6dea16 68 return;
andresag 7:0a8bbb6dea16 69 }
andresag 7:0a8bbb6dea16 70
andresag 7:0a8bbb6dea16 71 /* Ensure that it is the default instance of BLE */
andresag 7:0a8bbb6dea16 72 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
andresag 7:0a8bbb6dea16 73 return;
andresag 7:0a8bbb6dea16 74 }
andresag 7:0a8bbb6dea16 75
rgrover1 5:f4d74a8cad43 76 /* Setup advertising payload */
rgrover1 5:f4d74a8cad43 77 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
rgrover1 5:f4d74a8cad43 78 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER);
sunsmile2015 4:e5fa4c8838db 79 ApplicationData_t appData;
rgrover1 5:f4d74a8cad43 80 setupApplicationData(appData);
rgrover1 5:f4d74a8cad43 81 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&appData, sizeof(ApplicationData_t));
rgrover1 5:f4d74a8cad43 82
sunsmile2015 3:3eda308b78e6 83 /* Setup advertising parameters */
sunsmile2015 2:b935358da5ba 84 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
sunsmile2015 2:b935358da5ba 85 ble.gap().setAdvertisingInterval(500);
sunsmile2015 2:b935358da5ba 86
sunsmile2015 4:e5fa4c8838db 87 ble.gap().startAdvertising();
sunsmile2015 4:e5fa4c8838db 88 }
sunsmile2015 4:e5fa4c8838db 89
sunsmile2015 2:b935358da5ba 90 int main(void)
sunsmile2015 2:b935358da5ba 91 {
rgrover1 5:f4d74a8cad43 92 ticker.attach(periodicCallback, 2); /* trigger sensor polling every 2 seconds */
sunsmile2015 0:3dc6e424dba0 93
andresag 7:0a8bbb6dea16 94 BLE &ble = BLE::Instance();
andresag 7:0a8bbb6dea16 95 ble.init(bleInitComplete);
andresag 7:0a8bbb6dea16 96
andresag 7:0a8bbb6dea16 97 /* SpinWait for initialization to complete. This is necessary because the
andresag 7:0a8bbb6dea16 98 * BLE object is used in the main loop below. */
andresag 7:0a8bbb6dea16 99 while (ble.hasInitialized() == false) { /* spin loop */ }
rgrover1 5:f4d74a8cad43 100
sunsmile2015 0:3dc6e424dba0 101 while (true) {
sunsmile2015 4:e5fa4c8838db 102 if (triggerTempValueUpdate) {
andresag 7:0a8bbb6dea16 103 /* Do blocking calls or whatever hardware-specific action is
andresag 7:0a8bbb6dea16 104 * necessary to poll the sensor. */
rgrover1 5:f4d74a8cad43 105 ApplicationData_t appData;
rgrover1 5:f4d74a8cad43 106 setupApplicationData(appData);
andresag 7:0a8bbb6dea16 107 ble.gap().updateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *) &appData, sizeof(ApplicationData_t));
rgrover1 5:f4d74a8cad43 108
sunsmile2015 4:e5fa4c8838db 109 triggerTempValueUpdate = false;
sunsmile2015 0:3dc6e424dba0 110 }
rgrover1 5:f4d74a8cad43 111
sunsmile2015 0:3dc6e424dba0 112 ble.waitForEvent();
sunsmile2015 0:3dc6e424dba0 113 }
sunsmile2015 0:3dc6e424dba0 114 }