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.

Revision:
5:f4d74a8cad43
Parent:
4:e5fa4c8838db
Child:
7:0a8bbb6dea16
--- a/main.cpp	Fri Jul 31 09:11:43 2015 +0000
+++ b/main.cpp	Wed Aug 26 12:21:47 2015 +0000
@@ -1,4 +1,3 @@
-
 /* mbed Microcontroller Library
  * Copyright (c) 2006-2015 ARM Limited
  *
@@ -16,86 +15,71 @@
  */
 
 #include "mbed.h"
+#include "toolchain.h"
 #include "ble/BLE.h"
 #include "TMP_nrf51/TMP_nrf51.h"
 
-#define APP_SPECIFIC_ID_TEST 0xFEFE
+BLE ble;
 
-#pragma pack(1)
+static Ticker ticker;
+static TMP_nrf51  tempSensor;
+static bool       triggerTempValueUpdate = false;
+static DigitalOut alivenessLED(LED1, 1);
+
 struct ApplicationData_t {
-    uint16_t applicationSpecificId;             /* An ID used to identify temperature value
-                                                   in the manufacture specific AD data field */
-    TMP_nrf51::tmpSensorValue_t tmpSensorValue; /* User defined application data */
-};
-#pragma pack()
-
-BLE ble;
-TMP_nrf51 tempSensor;
-DigitalOut alivenessLED(LED1, 1);
-static bool triggerTempValueUpdate = false;
+    uint16_t                     applicationSpecificId; /* An ID used to identify temperature value in the manufacture specific AD data field */
+    TMP_nrf51::TempSensorValue_t tmpSensorValue;        /* User defined application data */
+} PACKED;
 
 void periodicCallback(void)
 {
-    /* Do blinky on LED1 while we're waiting for BLE events */
-    alivenessLED = !alivenessLED;
+    alivenessLED = !alivenessLED;  /* Do blinky on LED1 while we're waiting for BLE events. */
+
+    /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
+     * heavy-weight sensor polling from the main thread (where we should be able to block safely, if needed). */
     triggerTempValueUpdate = true;
 }
 
-void accumulateApplicationData(ApplicationData_t &appData)
+void setupApplicationData(ApplicationData_t &appData)
 {
+    static const uint16_t APP_SPECIFIC_ID_TEST = 0xFEFE;
     appData.applicationSpecificId = APP_SPECIFIC_ID_TEST;
-    /* Read a new temperature value */
-    appData.tmpSensorValue = tempSensor.get();
+    appData.tmpSensorValue        = tempSensor.get();
 }
 
-void temperatureValueAdvertising(void)
+void startAdvertisingTemperature(void)
 {
+    /* Setup advertising payload */
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER);
     ApplicationData_t appData;
-    
-    accumulateApplicationData(appData);
-    //printf("Temp is %f\r\n", (float)appData.tmpSensorValue);
-    
-    /* Setup advertising payload */
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); /* Set flag */
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER); /* Set appearance */
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&appData, sizeof(ApplicationData_t)); /* Set data */
+    setupApplicationData(appData);
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&appData, sizeof(ApplicationData_t));
+
     /* Setup advertising parameters */
     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
     ble.gap().setAdvertisingInterval(500);
-    /* Start advertising */
-    ble.gap().startAdvertising();
-}
 
-void updateSensorValueInAdvPayload(void)
-{
-    ApplicationData_t appData;
-    
-    accumulateApplicationData(appData);
-    
-    /* Stop advertising first */
-    ble.gap().stopAdvertising();
-    /* Only update temperature value field */
-    ble.gap().updateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&appData, sizeof(ApplicationData_t));
-    /* Start advertising again */
     ble.gap().startAdvertising();
 }
 
 int main(void)
 {
-    Ticker ticker;
-    /* Enable trigger every 2 seconds */
-    ticker.attach(periodicCallback, 2);
+    ticker.attach(periodicCallback, 2); /* trigger sensor polling every 2 seconds */
 
     ble.init();
-    /* Start temperature advertising */
-    temperatureValueAdvertising();
-    
+    startAdvertisingTemperature();
+
     while (true) {
         if (triggerTempValueUpdate) {
-            /* Update temperature value */
-            updateSensorValueInAdvPayload();
+            // Do blocking calls or whatever hardware-specific action is necessary to poll the sensor.
+            ApplicationData_t appData;
+            setupApplicationData(appData);
+            ble.gap().updateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&appData, sizeof(ApplicationData_t));
+
             triggerTempValueUpdate = false;
         }
+
         ble.waitForEvent();
     }
 }