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.

Committer:
wd5gnr
Date:
Wed Oct 01 22:06:43 2014 +0000
Revision:
45:e64d1e920cd1
Parent:
44:6a5d976d6e61
Replace the mbed-src library with mbed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ktownsend 0:7613d21e5974 1 /* mbed Microcontroller Library
ktownsend 0:7613d21e5974 2 * Copyright (c) 2006-2013 ARM Limited
ktownsend 0:7613d21e5974 3 *
ktownsend 0:7613d21e5974 4 * Licensed under the Apache License, Version 2.0 (the "License");
ktownsend 0:7613d21e5974 5 * you may not use this file except in compliance with the License.
ktownsend 0:7613d21e5974 6 * You may obtain a copy of the License at
ktownsend 0:7613d21e5974 7 *
ktownsend 0:7613d21e5974 8 * http://www.apache.org/licenses/LICENSE-2.0
ktownsend 0:7613d21e5974 9 *
ktownsend 0:7613d21e5974 10 * Unless required by applicable law or agreed to in writing, software
ktownsend 0:7613d21e5974 11 * distributed under the License is distributed on an "AS IS" BASIS,
ktownsend 0:7613d21e5974 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ktownsend 0:7613d21e5974 13 * See the License for the specific language governing permissions and
ktownsend 0:7613d21e5974 14 * limitations under the License.
ktownsend 0:7613d21e5974 15 */
ktownsend 0:7613d21e5974 16
ktownsend 0:7613d21e5974 17 #include "mbed.h"
Rohit Grover 32:7b7093b653a8 18 #include "BLEDevice.h"
wd5gnr 44:6a5d976d6e61 19 #include "nrf_temp.h"
wd5gnr 44:6a5d976d6e61 20
wd5gnr 44:6a5d976d6e61 21 #define ADVTIME 1000 // advertise time in ms
wd5gnr 44:6a5d976d6e61 22 #define UPDTIME 2000 // update time in ms
ktownsend 0:7613d21e5974 23
Rohit Grover 32:7b7093b653a8 24 BLEDevice ble;
wd5gnr 44:6a5d976d6e61 25 Timer msclock;
wd5gnr 44:6a5d976d6e61 26 DigitalOut activity(LED1); // blinks to show activity
wd5gnr 44:6a5d976d6e61 27 DigitalOut errLED(LED2); // comes on if error occurs
wd5gnr 44:6a5d976d6e61 28 DigitalIn btn1(BUTTON1);
wd5gnr 44:6a5d976d6e61 29 DigitalIn btn2(BUTTON2);
Rohit Grover 31:93e50a3c3dc6 30
Rohit Grover 31:93e50a3c3dc6 31 #define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console;
Rohit Grover 31:93e50a3c3dc6 32 * it will have an impact on code-size and power consumption. */
ktownsend 0:7613d21e5974 33
Rohit Grover 31:93e50a3c3dc6 34 #if NEED_CONSOLE_OUTPUT
Rohit Grover 31:93e50a3c3dc6 35 Serial pc(USBTX, USBRX);
Rohit Grover 31:93e50a3c3dc6 36 #define DEBUG(...) { pc.printf(__VA_ARGS__); }
Rohit Grover 31:93e50a3c3dc6 37 #else
Rohit Grover 31:93e50a3c3dc6 38 #define DEBUG(...) /* nothing */
Rohit Grover 31:93e50a3c3dc6 39 #endif /* #if NEED_CONSOLE_OUTPUT */
ktownsend 0:7613d21e5974 40
wd5gnr 44:6a5d976d6e61 41 // Try a BLE function and if failed, light LED 2 and halt
wd5gnr 44:6a5d976d6e61 42 // but don't catch fire....
wd5gnr 44:6a5d976d6e61 43
wd5gnr 44:6a5d976d6e61 44 void errTry(ble_error_t fn,int n=1)
wd5gnr 44:6a5d976d6e61 45 {
wd5gnr 44:6a5d976d6e61 46 if (fn)
wd5gnr 44:6a5d976d6e61 47 {
wd5gnr 44:6a5d976d6e61 48 while (1)
wd5gnr 44:6a5d976d6e61 49 {
wd5gnr 44:6a5d976d6e61 50 for (int i=0;i<n*2;i++)
wd5gnr 44:6a5d976d6e61 51 {
wd5gnr 44:6a5d976d6e61 52 wait_ms(250);
wd5gnr 44:6a5d976d6e61 53 errLED=!errLED;
wd5gnr 44:6a5d976d6e61 54 }
wd5gnr 44:6a5d976d6e61 55 wait_ms(2000);
wd5gnr 44:6a5d976d6e61 56 }
wd5gnr 44:6a5d976d6e61 57 }
wd5gnr 44:6a5d976d6e61 58 }
wd5gnr 44:6a5d976d6e61 59
wd5gnr 44:6a5d976d6e61 60
wd5gnr 44:6a5d976d6e61 61
Rohit Grover 10:391c1acf4b9d 62 /*
Rohit Grover 10:391c1acf4b9d 63 * Reference:
Rohit Grover 10:391c1acf4b9d 64 * Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 11, 18
Rohit Grover 10:391c1acf4b9d 65 */
ktownsend 0:7613d21e5974 66
Rohit Grover 14:dfdf0c8b1c09 67 /*
Rohit Grover 15:4e1b36b73213 68 * The Beacon payload (encapsulated within the MSD advertising data structure)
Rohit Grover 15:4e1b36b73213 69 * has the following composition:
Rohit Grover 10:391c1acf4b9d 70 * 128-Bit UUID = E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61
wd5gnr 44:6a5d976d6e61 71 * Major/Minor = 0000 / 0000 (We steal this for data)
Rohit Grover 10:391c1acf4b9d 72 * Tx Power = C8
Rohit Grover 10:391c1acf4b9d 73 */
wd5gnr 44:6a5d976d6e61 74 uint8_t beaconPayload[] = {
wd5gnr 44:6a5d976d6e61 75 0x4C, 0x00, // vendor ID
wd5gnr 44:6a5d976d6e61 76 0x02, // packet type (2)
wd5gnr 44:6a5d976d6e61 77 0x15, // length
wd5gnr 44:6a5d976d6e61 78 0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4, // UUID
Rohit Grover 10:391c1acf4b9d 79 0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61,
wd5gnr 44:6a5d976d6e61 80 0x00, 0x00, // Major
wd5gnr 44:6a5d976d6e61 81 0x00, 0x00, // Minor
wd5gnr 44:6a5d976d6e61 82 0xC8 // TXPower
wd5gnr 44:6a5d976d6e61 83 , 0x99 // one spare byte!
Rohit Grover 10:391c1acf4b9d 84 };
Rohit Grover 10:391c1acf4b9d 85
wd5gnr 44:6a5d976d6e61 86
wd5gnr 45:e64d1e920cd1 87 // Read temperature
wd5gnr 45:e64d1e920cd1 88 int temp_read()
wd5gnr 45:e64d1e920cd1 89 {
wd5gnr 45:e64d1e920cd1 90 int t;
wd5gnr 45:e64d1e920cd1 91 NRF_TEMP->TASKS_START=1;
wd5gnr 45:e64d1e920cd1 92 while (NRF_TEMP->EVENTS_DATARDY==0);
wd5gnr 45:e64d1e920cd1 93 NRF_TEMP->EVENTS_DATARDY=0;
wd5gnr 45:e64d1e920cd1 94 t=nrf_temp_read();
wd5gnr 45:e64d1e920cd1 95 NRF_TEMP->TASKS_STOP=1;
wd5gnr 45:e64d1e920cd1 96 return t;
wd5gnr 45:e64d1e920cd1 97 }
wd5gnr 45:e64d1e920cd1 98
wd5gnr 45:e64d1e920cd1 99
wd5gnr 44:6a5d976d6e61 100 // Grab the sensors and put 55AA in major
wd5gnr 44:6a5d976d6e61 101 // Put minor data for temperature reading
wd5gnr 44:6a5d976d6e61 102 // (which returns 0 on this board)
wd5gnr 44:6a5d976d6e61 103 // as well as switches
wd5gnr 44:6a5d976d6e61 104 void readSensors()
wd5gnr 44:6a5d976d6e61 105 {
wd5gnr 44:6a5d976d6e61 106 int temp;
wd5gnr 44:6a5d976d6e61 107 beaconPayload[20]=0x55;
wd5gnr 44:6a5d976d6e61 108 beaconPayload[21]=0xAA;
wd5gnr 45:e64d1e920cd1 109 temp=temp_read(); // (should read 0-1023)
wd5gnr 44:6a5d976d6e61 110 if (!btn1) temp|=0x8000; // switches are inverted sense (0=pressed)
wd5gnr 44:6a5d976d6e61 111 if (!btn2) temp|=0x4000;
wd5gnr 44:6a5d976d6e61 112
wd5gnr 44:6a5d976d6e61 113 beaconPayload[22]=temp>>8;
wd5gnr 44:6a5d976d6e61 114 beaconPayload[23]=temp&0xFF;
wd5gnr 44:6a5d976d6e61 115
wd5gnr 44:6a5d976d6e61 116 }
wd5gnr 44:6a5d976d6e61 117
wd5gnr 44:6a5d976d6e61 118 // Build up advertising packet including sensors
wd5gnr 44:6a5d976d6e61 119 void setupBLE()
wd5gnr 44:6a5d976d6e61 120 {
wd5gnr 44:6a5d976d6e61 121 ble.clearAdvertisingPayload();
wd5gnr 44:6a5d976d6e61 122 readSensors();
wd5gnr 44:6a5d976d6e61 123 errTry(ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE),5);
wd5gnr 44:6a5d976d6e61 124 errTry(ble.accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, beaconPayload, sizeof(beaconPayload)),6);
wd5gnr 44:6a5d976d6e61 125
wd5gnr 44:6a5d976d6e61 126 }
wd5gnr 44:6a5d976d6e61 127
wd5gnr 44:6a5d976d6e61 128
wd5gnr 44:6a5d976d6e61 129
wd5gnr 44:6a5d976d6e61 130
wd5gnr 44:6a5d976d6e61 131
ktownsend 0:7613d21e5974 132 int main(void)
ktownsend 0:7613d21e5974 133 {
wd5gnr 44:6a5d976d6e61 134 char *devname="DDJ";
wd5gnr 44:6a5d976d6e61 135 DEBUG("Init\n\r");
wd5gnr 44:6a5d976d6e61 136 activity=errLED=0;
wd5gnr 44:6a5d976d6e61 137 nrf_temp_init();
wd5gnr 44:6a5d976d6e61 138 errTry(ble.init(),1);
wd5gnr 45:e64d1e920cd1 139 NRF_TEMP->TASKS_START=1;
ktownsend 0:7613d21e5974 140
wd5gnr 44:6a5d976d6e61 141 // Build advert
wd5gnr 44:6a5d976d6e61 142 setupBLE();
wd5gnr 44:6a5d976d6e61 143
wd5gnr 44:6a5d976d6e61 144 // Set up general parameters
wd5gnr 44:6a5d976d6e61 145 errTry(ble.setDeviceName((uint8_t *)devname),2);
wd5gnr 44:6a5d976d6e61 146 #if 0
wd5gnr 44:6a5d976d6e61 147 errTry(ble.setAdvertisingType(GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED)); // this will give you one "ping" and no repeats
wd5gnr 44:6a5d976d6e61 148 #else
wd5gnr 44:6a5d976d6e61 149 ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); // This will give you a ping every interval
wd5gnr 44:6a5d976d6e61 150 #endif
wd5gnr 44:6a5d976d6e61 151
wd5gnr 44:6a5d976d6e61 152 ble.setAdvertisingInterval((16*ADVTIME)/10); /* 1s; in multiples of 0.625ms. is 1600 */
wd5gnr 44:6a5d976d6e61 153
wd5gnr 44:6a5d976d6e61 154 // start timer for sensor reading
wd5gnr 44:6a5d976d6e61 155 msclock.start();
ktownsend 0:7613d21e5974 156
wd5gnr 44:6a5d976d6e61 157 while (true) {
wd5gnr 44:6a5d976d6e61 158 msclock.reset();
wd5gnr 44:6a5d976d6e61 159 errTry(ble.startAdvertising(),3); // start advert
wd5gnr 44:6a5d976d6e61 160 wait_ms(UPDTIME); // wait awhile
wd5gnr 44:6a5d976d6e61 161 activity=!activity; // blink led
wd5gnr 44:6a5d976d6e61 162 errTry(ble.stopAdvertising(),4); // stop advert
wd5gnr 44:6a5d976d6e61 163 setupBLE(); // set up with new data
ktownsend 0:7613d21e5974 164 }
Rohit Grover 31:93e50a3c3dc6 165
Rohit Grover 10:391c1acf4b9d 166 }