Simple beacon for nRF51822

Dependencies:   BLE_API mbed nRF51822Copy

Fork of BLE_iBeacon by Bluetooth Low Energy

This is the demo beacon for ARM TechCon 2014.

Based on the original library, this demo reads the onboard switches and temperature sensor and beacons them out as a BLE advertisment.

Revision:
44:6a5d976d6e61
Parent:
43:b5dc3241fc91
Child:
45:e64d1e920cd1
--- a/main.cpp	Tue Sep 02 16:09:59 2014 +0000
+++ b/main.cpp	Sun Sep 21 19:23:27 2014 +0000
@@ -16,8 +16,17 @@
 
 #include "mbed.h"
 #include "BLEDevice.h"
+#include "nrf_temp.h"
+
+#define ADVTIME 1000    // advertise time in ms
+#define UPDTIME 2000   // update time in ms
 
 BLEDevice ble;
+Timer msclock;
+DigitalOut activity(LED1);  // blinks to show activity
+DigitalOut errLED(LED2);    // comes on if error occurs
+DigitalIn btn1(BUTTON1);
+DigitalIn btn2(BUTTON2);
 
 #define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console;
                                * it will have an impact on code-size and power consumption. */
@@ -29,10 +38,28 @@
 #define DEBUG(...) /* nothing */
 #endif /* #if NEED_CONSOLE_OUTPUT */
 
+// Try a BLE function and if failed, light LED 2 and halt
+// but don't catch fire....
+
+void errTry(ble_error_t fn,int n=1)
+{
+    if (fn)
+    {
+        while (1)
+        {
+            for (int i=0;i<n*2;i++)
+            {
+                wait_ms(250);
+                errLED=!errLED;
+            }
+        wait_ms(2000);
+        }
+    }
+} 
+
+
+
 /*
- * For this demo application, populate the beacon advertisement payload
- * with 2 AD structures: FLAG and MSD (manufacturer specific data).
- *
  * Reference:
  *  Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 11, 18
  */
@@ -41,41 +68,85 @@
  * The Beacon payload (encapsulated within the MSD advertising data structure)
  * has the following composition:
  * 128-Bit UUID = E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61
- * Major/Minor  = 0000 / 0000
+ * Major/Minor  = 0000 / 0000 (We steal this for data)
  * Tx Power     = C8
  */
-const uint8_t beaconPayload[] = {
-    0x4C, 0x00,
-    0x02,
-    0x15,
-    0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4,
+   uint8_t beaconPayload[] = {
+    0x4C, 0x00,   // vendor ID
+    0x02,         // packet type (2)
+    0x15,         // length
+    0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4,  // UUID
     0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61,
-    0x00, 0x00,
-    0x00, 0x00,
-    0xC8
+    0x00, 0x00,  // Major
+    0x00, 0x00,  // Minor
+    0xC8         // TXPower
+,   0x99         // one spare byte!
 };
 
+
+// Grab the sensors and put 55AA in major
+// Put minor data for temperature reading 
+// (which returns 0 on this board)
+// as well as switches
+void readSensors()
+{
+    int temp;
+    beaconPayload[20]=0x55;
+    beaconPayload[21]=0xAA;
+    temp=nrf_temp_read();  // always reads 0? (should read 0-1023)
+    if (!btn1) temp|=0x8000;   // switches are inverted sense (0=pressed)
+    if (!btn2) temp|=0x4000;
+        
+    beaconPayload[22]=temp>>8;
+    beaconPayload[23]=temp&0xFF;
+
+}
+
+// Build up advertising packet including sensors
+void setupBLE()
+{
+    ble.clearAdvertisingPayload();
+    readSensors();
+    errTry(ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE),5);
+    errTry(ble.accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, beaconPayload, sizeof(beaconPayload)),6);    
+
+}
+
+
+
+
+
 int main(void)
 {
-    DEBUG("Initialising BTLE transport\n\r");
-    ble.init();
-
-    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
-    ble.accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, beaconPayload, sizeof(beaconPayload));
+    char *devname="DDJ";
+    DEBUG("Init\n\r");
+    activity=errLED=0;
+    nrf_temp_init();
+    errTry(ble.init(),1);
 
-    ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
-    ble.setAdvertisingInterval(1600); /* 1s; in multiples of 0.625ms. */
-    ble.startAdvertising();
+// Build advert
+    setupBLE();
+    
+    // Set up general parameters
+    errTry(ble.setDeviceName((uint8_t *)devname),2);
+  #if 0
+    errTry(ble.setAdvertisingType(GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED));  // this will give you one "ping" and no repeats
+  #else
+    ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);  // This will give you a ping every interval
+  #endif
+   
+    ble.setAdvertisingInterval((16*ADVTIME)/10); /* 1s; in multiples of 0.625ms. is 1600 */
+   
+// start timer for sensor reading 
+    msclock.start();
 
-    for (;;) {
-        ble.waitForEvent();
+    while (true) {
+        msclock.reset();    
+        errTry(ble.startAdvertising(),3);   // start advert
+         wait_ms(UPDTIME);                // wait awhile
+        activity=!activity;               // blink led
+        errTry(ble.stopAdvertising(),4);    // stop advert
+        setupBLE();                       // set up with new data
     }
 
-    // An alternative to the above:
-    //
-    // DigitalOut mainloopLED(LED1);
-    // for (;;) {
-    //     mainloopLED = !mainloopLED;
-    //     ble.waitForEvent();
-    // }
 }