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:
Sun Sep 21 19:23:27 2014 +0000
Revision:
44:6a5d976d6e61
Parent:
43:b5dc3241fc91
Child:
45:e64d1e920cd1
First commit

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 44:6a5d976d6e61 87 // Grab the sensors and put 55AA in major
wd5gnr 44:6a5d976d6e61 88 // Put minor data for temperature reading
wd5gnr 44:6a5d976d6e61 89 // (which returns 0 on this board)
wd5gnr 44:6a5d976d6e61 90 // as well as switches
wd5gnr 44:6a5d976d6e61 91 void readSensors()
wd5gnr 44:6a5d976d6e61 92 {
wd5gnr 44:6a5d976d6e61 93 int temp;
wd5gnr 44:6a5d976d6e61 94 beaconPayload[20]=0x55;
wd5gnr 44:6a5d976d6e61 95 beaconPayload[21]=0xAA;
wd5gnr 44:6a5d976d6e61 96 temp=nrf_temp_read(); // always reads 0? (should read 0-1023)
wd5gnr 44:6a5d976d6e61 97 if (!btn1) temp|=0x8000; // switches are inverted sense (0=pressed)
wd5gnr 44:6a5d976d6e61 98 if (!btn2) temp|=0x4000;
wd5gnr 44:6a5d976d6e61 99
wd5gnr 44:6a5d976d6e61 100 beaconPayload[22]=temp>>8;
wd5gnr 44:6a5d976d6e61 101 beaconPayload[23]=temp&0xFF;
wd5gnr 44:6a5d976d6e61 102
wd5gnr 44:6a5d976d6e61 103 }
wd5gnr 44:6a5d976d6e61 104
wd5gnr 44:6a5d976d6e61 105 // Build up advertising packet including sensors
wd5gnr 44:6a5d976d6e61 106 void setupBLE()
wd5gnr 44:6a5d976d6e61 107 {
wd5gnr 44:6a5d976d6e61 108 ble.clearAdvertisingPayload();
wd5gnr 44:6a5d976d6e61 109 readSensors();
wd5gnr 44:6a5d976d6e61 110 errTry(ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE),5);
wd5gnr 44:6a5d976d6e61 111 errTry(ble.accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, beaconPayload, sizeof(beaconPayload)),6);
wd5gnr 44:6a5d976d6e61 112
wd5gnr 44:6a5d976d6e61 113 }
wd5gnr 44:6a5d976d6e61 114
wd5gnr 44:6a5d976d6e61 115
wd5gnr 44:6a5d976d6e61 116
wd5gnr 44:6a5d976d6e61 117
wd5gnr 44:6a5d976d6e61 118
ktownsend 0:7613d21e5974 119 int main(void)
ktownsend 0:7613d21e5974 120 {
wd5gnr 44:6a5d976d6e61 121 char *devname="DDJ";
wd5gnr 44:6a5d976d6e61 122 DEBUG("Init\n\r");
wd5gnr 44:6a5d976d6e61 123 activity=errLED=0;
wd5gnr 44:6a5d976d6e61 124 nrf_temp_init();
wd5gnr 44:6a5d976d6e61 125 errTry(ble.init(),1);
ktownsend 0:7613d21e5974 126
wd5gnr 44:6a5d976d6e61 127 // Build advert
wd5gnr 44:6a5d976d6e61 128 setupBLE();
wd5gnr 44:6a5d976d6e61 129
wd5gnr 44:6a5d976d6e61 130 // Set up general parameters
wd5gnr 44:6a5d976d6e61 131 errTry(ble.setDeviceName((uint8_t *)devname),2);
wd5gnr 44:6a5d976d6e61 132 #if 0
wd5gnr 44:6a5d976d6e61 133 errTry(ble.setAdvertisingType(GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED)); // this will give you one "ping" and no repeats
wd5gnr 44:6a5d976d6e61 134 #else
wd5gnr 44:6a5d976d6e61 135 ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); // This will give you a ping every interval
wd5gnr 44:6a5d976d6e61 136 #endif
wd5gnr 44:6a5d976d6e61 137
wd5gnr 44:6a5d976d6e61 138 ble.setAdvertisingInterval((16*ADVTIME)/10); /* 1s; in multiples of 0.625ms. is 1600 */
wd5gnr 44:6a5d976d6e61 139
wd5gnr 44:6a5d976d6e61 140 // start timer for sensor reading
wd5gnr 44:6a5d976d6e61 141 msclock.start();
ktownsend 0:7613d21e5974 142
wd5gnr 44:6a5d976d6e61 143 while (true) {
wd5gnr 44:6a5d976d6e61 144 msclock.reset();
wd5gnr 44:6a5d976d6e61 145 errTry(ble.startAdvertising(),3); // start advert
wd5gnr 44:6a5d976d6e61 146 wait_ms(UPDTIME); // wait awhile
wd5gnr 44:6a5d976d6e61 147 activity=!activity; // blink led
wd5gnr 44:6a5d976d6e61 148 errTry(ble.stopAdvertising(),4); // stop advert
wd5gnr 44:6a5d976d6e61 149 setupBLE(); // set up with new data
ktownsend 0:7613d21e5974 150 }
Rohit Grover 31:93e50a3c3dc6 151
Rohit Grover 10:391c1acf4b9d 152 }