Skip to content

[RFC] add a bunch of hackish (but working) observer role functions #155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a4f2f96
add a bunch of hackish (but working) observer role functions
floe May 19, 2017
9a963a7
use proper adv data type when non-connectable, but scan data present
floe May 23, 2017
e3c9088
Merge branch 'fix_scan_response'
floe May 23, 2017
6d937a0
add local scan response pointer
floe May 23, 2017
7fd029e
fix rfduino build
floe May 23, 2017
ca979a2
Merge branch 'master' of https://github.com/sandeepmistry/arduino-BLE…
floe Aug 8, 2017
7c93bbf
don't change default advertising behaviour
floe Aug 9, 2017
4164dce
Merge branch 'master' of https://github.com/sandeepmistry/arduino-BLE…
floe Oct 23, 2017
6f033c6
minor refactoring to prepare for advertisement updates
floe Oct 23, 2017
4563b13
refactor advertisements, part 2
floe Oct 23, 2017
6868505
update advertising data when startAdvertising is called
floe Oct 23, 2017
c0b1aff
first iteration for proper device event handlers
floe Oct 23, 2017
9d99fa2
Merge branch 'master' of https://github.com/sandeepmistry/arduino-BLE…
floe Nov 13, 2017
4820c0e
observer/advertiser example
floe Dec 7, 2017
5bbabed
add handler for local address
floe Dec 11, 2017
9289b66
update example
floe Dec 11, 2017
dcc385b
Update library.properties
floe Dec 18, 2017
f648e59
Update library.json
floe Dec 18, 2017
7f735ee
Update README.md
floe Dec 19, 2017
b3a29f1
Merge branch 'master' of https://github.com/sandeepmistry/arduino-BLE…
floe Feb 26, 2018
29b4b6d
rename include
floe Feb 27, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 5 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,12 @@
[![Build Status](https://travis-ci.org/sandeepmistry/arduino-BLEPeripheral.svg?branch=master)](https://travis-ci.org/sandeepmistry/arduino-BLEPeripheral) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/sandeepmistry/arduino-BLEPeripheral?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)


An [Arduino](http://arduino.cc) library for creating custom BLE peripherals with [Nordic Semiconductor](http://www.nordicsemi.com)'s [nRF8001](http://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF8001) or [nR51822](http://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822).
An [Arduino](http://arduino.cc) library for creating custom BLE peripherals and observers with [Nordic Semiconductor](http://www.nordicsemi.com)'s [nR51822](http://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822).

Enables you to create more customized BLE Peripheral's compared to the basic UART most other Arduino BLE libraries provide.

[nRFgo Studio](http://www.nordicsemi.com/chi/node_176/2.4GHz-RF/nRFgo-Studio) (and Windows) is not required when using the [nRF8001](http://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF8001).
This is heavily based on @sandeepmistry's [arduino-BLEPeripheral](https://github.com/sandeepmistry/arduino-BLEPeripheral) library. This fork adds support for the observer role (i.e. receiving Bluetooth advertisements), but consequently can't support the nRF8001 anymore.

## Compatible Hardware

### [Nordic Semiconductor nRF8001](http://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF8001)

* [Adafruit](http://www.adafruit.com)
* [Bluefruit LE - nRF8001 Breakout](http://www.adafruit.com/products/1697)
* [RedBearLab](http://redbearlab.com)
* [BLE Shield](http://redbearlab.com/bleshield/)
* [Blend Micro](http://redbearlab.com/blendmicro/)
* [Blend](http://redbearlab.com/blend/)
* [Femtoduino](http://www.femtoduino.com)
* [IMUduino BTLE](http://www.femtoduino.com/spex/imuduino-btle)
* [Olimex](https://www.olimex.com)
* [MOD-nRF8001](https://www.olimex.com/Products/Modules/RF/MOD-nRF8001/)
* [OLIMEXINO-NANO-BLE](https://www.olimex.com/Products/Duino/AVR/OLIMEXINO-NANO-BLE/)
* [Jaycon Systems](http://www.jayconsystems.com)
* [nRF8001 Bluetooth Breakout Board](http://www.jayconsystems.com/nrf8001-breakout-board.html)
* [TinyCircuits](https://www.tiny-circuits.com)
* [TinyShield Bluetooth Low Energy - Nordic](https://www.tiny-circuits.com/tiny-shield-bluetooth-low-energy-nordic.html)

**Note:** Does not require use of [nRFgo Studio](http://www.nordicsemi.com/chi/node_176/2.4GHz-RF/nRFgo-Studio)! However, uses more code space.

### [Nordic Semiconductor nRF51822](http://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822)

* [RedBearLab](http://redbearlab.com) with [Arduino Add-on](https://github.com/RedBearLab/nRF51822-Arduino)
Expand All @@ -44,39 +22,6 @@ Enables you to create more customized BLE Peripheral's compared to the basic UAR

* Various, see [arduino-nRF5 supported boards](https://github.com/sandeepmistry/arduino-nRF5#supported-boards) via [nRF5 Arduino Add-on](https://github.com/sandeepmistry/arduino-nRF5)

#### Pinouts

| Chip | Shield/Board | REQ Pin | RDY Pin | RST Pin |
| ---- | ------------ | ------- | ------- | ------- |
| nRF8001|
| | Bluefruit LE | 10 | 2 | 9 |
| | BLE Shield 1.x | 9 | 8 | UNUSED |
| | BLE Shield 2.x | 9 | 8 | UNUSED or 4/7 via jumper|
| | Blend | 9 | 8 | UNUSED or 4/5 via jumper |
| | Blend Micro | 6 | 7 | UNUSED or 4 |
| | IMUduino BTLE | 10 | 7 | 9 |
| | TinyShield Bluetooth Low Energy | 10 | 2 | 9 |
| nRF51822 |
| | RedBearLab nRF51822 | -1 (UNUSED) | -1 (UNUSED) | -1 (UNUSED) |
| | BLE Nano | -1 (UNUSED) | -1 (UNUSED) | -1 (UNUSED) |
| | RFduino | -1 (UNUSED) | -1 (UNUSED) | -1 (UNUSED) |

## Compatible IDE's and MCU's

* [Arduino IDE](http://arduino.cc/en/Main/Software#toc1)
* AVR (Uno, Lenoardo, Mega, etc.)
* SAM3X8E (Due)
* SAMD21G18A (Zero)
* [Teensy](https://www.pjrc.com/teensy/) (via [Teensyduino](https://www.pjrc.com/teensy/td_download.html))
* 2.0
* 3.0
* 3.1
* LC

**Warning**: For more advanced sketches an MCU with more than 2kB of RAM and 32kB of flash space is recommended. Advance sketches include:
* Multiple services and characteristics
* HID API usage

## Usage

### Download Library
Expand All @@ -86,20 +31,20 @@ Enables you to create more customized BLE Peripheral's compared to the basic UAR
#### Using the Arduino IDE Library Manager

1. Choose ```Sketch``` -> ```Include Library``` -> ```Manage Libraries...```
2. Type ```BLEPeripheral``` into the search box.
2. Type ```BLEPeripheralObserver``` into the search box.
3. Click the row to select the library.
4. Click the ```Install``` button to install the library.

#### Using Git
```sh
cd ~/Documents/Arduino/libraries/
git clone https://github.com/sandeepmistry/arduino-BLEPeripheral BLEPeripheral
git clone https://github.com/floe/BLEPeripheralObserver BLEPeripheralObserver
```

#### MPIDE
```
cd ~/Documents/mpide/libraries/
git clone https://github.com/sandeepmistry/arduino-BLEPeripheral BLEPeripheral
git clone https://github.com/floe/BLEPeripheralObserver BLEPeripheralObserver
```

### [arduino-nRF5x core](https://github.com/sandeepmistry/arduino-nRF5) users
Expand All @@ -120,15 +65,3 @@ See [examples](examples) folder.
## License

This libary is [licensed](LICENSE) under the [MIT Licence](http://en.wikipedia.org/wiki/MIT_License).

## Useful Links
* [@lizardo](https://github.com/lizardo)'s [nRF8001 Experiments](https://github.com/lizardo/nrf8001)
* used as a starting point to reverse engineer the proprietary setup message format for the chips
* [@NordicSemiconductor](https://github.com/NordicSemiconductor)'s [ble-sdk-arduino](https://github.com/NordicSemiconductor/ble-sdk-arduino)
* Original Arduino SDK for nRF8001
* [@guanix](https://github.com/guanix)'s [arduino-nrf8001](https://github.com/guanix/arduino-nrf8001)
* nRF8001 support for Arduino


[![Analytics](https://ga-beacon.appspot.com/UA-56089547-1/sandeepmistry/arduino-BLEPeripheral?pixel)](https://github.com/igrigorik/ga-beacon)

60 changes: 60 additions & 0 deletions examples/observer/observer.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) Sandeep Mistry. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#define NRF51
#undef __RFduino__
// Import libraries (BLEPeripheral depends on SPI)
#include <SPI.h>
#include <BLEPeripheral.h>
#include <BLEUtil.h>
#include <ble_gap.h>

//custom boards may override default pin definitions with BLEPeripheral(PIN_REQ, PIN_RDY, PIN_RST)
BLEPeripheral blePeripheral = BLEPeripheral();

void setup() {
Serial.begin(115200);
#if defined (__AVR_ATmega32U4__)
delay(5000); //5 seconds delay for enabling to see the start up comments on the serial board
#endif

blePeripheral.setLocalName("foobaz"); // optional

blePeripheral.setEventHandler(BLEAddressReceived, addrHandler);
blePeripheral.setEventHandler(BLEAdvertisementReceived, advHandler);

// begin initialization
blePeripheral.begin();
blePeripheral.setConnectable(false);
blePeripheral.setAdvertisingInterval(500);
blePeripheral.startAdvertising();
}

void addrHandler(const void* _addr) {
unsigned char* addr = (unsigned char*)_addr;
char address[18];
BLEUtil::addressToString(addr, address);
Serial.print(F("Got own addr: "));
Serial.println(address);
}

void advHandler(const void* adv) {
ble_gap_evt_adv_report_t* report = (ble_gap_evt_adv_report_t*)adv;
char address[18];
BLEUtil::addressToString(report->peer_addr.addr, address);
Serial.print(F("Evt Adv Report from "));
Serial.println(address);
Serial.print(F("got adv with payload "));
Serial.println(report->dlen);
}

void loop() {
if (Serial.available() > 0) {
Serial.read();
Serial.println("start scanning");
blePeripheral.startScanning();
blePeripheral.setLocalName("foobarg"); // optional
blePeripheral.startAdvertising();
}
blePeripheral.poll();
}
10 changes: 5 additions & 5 deletions library.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "BLEPeripheral",
"name": "BLEPeripheralObserver",
"version": "0.4.0",
"keywords": "BLE, bluetooth, peripheral",
"description": "Arduino library for creating custom BLE peripherals. Supports nRF8001 and nRF51822 based boards/shields.",
"keywords": "BLE, bluetooth, peripheral, observer",
"description": "Arduino library for creating custom BLE peripherals. Supports nRF51 based boards.",
"repository":
{
"type": "git",
"url": "https://github.com/sandeepmistry/arduino-BLEPeripheral.git"
"url": "https://github.com/floe/BLEPeripheralObserver.git"
},
"frameworks": "arduino",
"platforms": "nordicnrf51, atmelavr, atmelsam, teensy"
"platforms": "nordicnrf51"
}
14 changes: 7 additions & 7 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name=BLEPeripheral
name=BLEPeripheralObserver
version=0.4.0
author=Sandeep Mistry <[email protected]>
maintainer=Sandeep Mistry <[email protected]>
sentence=An Arduino library for creating custom BLE peripherals.
paragraph=Supports nRF8001 and nRF51822 based boards/shields
author=Sandeep Mistry <[email protected]>, Florian Echtler <[email protected]>
maintainer=Florian Echtler <[email protected]>
sentence=An Arduino library for creating custom BLE peripherals and observers.
paragraph=Supports nRF51 and nRF52 based boards
category=Communication
url=https://github.com/sandeepmistry/arduino-BLEPeripheral
url=https://github.com/floe/BLEPeripheralObserver
architectures=*
includes=BLEPeripheral.h
includes=BLEPeripheralObserver.h
9 changes: 9 additions & 0 deletions src/BLEDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class BLEDeviceEventListener
virtual void BLEDeviceAddressReceived(BLEDevice& /*device*/, const unsigned char* /*address*/) { }
virtual void BLEDeviceTemperatureReceived(BLEDevice& /*device*/, float /*temperature*/) { }
virtual void BLEDeviceBatteryLevelReceived(BLEDevice& /*device*/, float /*batteryLevel*/) { }
virtual void BLEDeviceAdvertisementReceived(BLEDevice& /*device*/, const unsigned char* /*advertisement*/) { }
};


Expand Down Expand Up @@ -65,13 +66,21 @@ class BLEDevice
BLERemoteAttribute** /*remoteAttributes*/,
unsigned char /*numRemoteAttributes*/) { }

virtual void updateAdvertisementData(unsigned char /*advertisementDataSize*/,
BLEEirData * /*advertisementData*/,
unsigned char /*scanDataSize*/,
BLEEirData * /*scanData*/) { }

virtual void poll() { }

virtual void end() { }

virtual bool setTxPower(int /*txPower*/) { return false; }

virtual void startAdvertising() { }
virtual void stopAdvertising() { }
virtual void startScanning() { }
virtual void stopScanning() { }
virtual void disconnect() { }

virtual bool updateCharacteristicValue(BLECharacteristic& /*characteristic*/) { return false; }
Expand Down
63 changes: 56 additions & 7 deletions src/BLEPeripheral.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ BLEPeripheral::BLEPeripheral(unsigned char req, unsigned char rdy, unsigned char
#endif

memset(this->_eventHandlers, 0x00, sizeof(this->_eventHandlers));
memset(this->_deviceEvents, 0x00, sizeof(this->_deviceEvents));

this->setDeviceName(DEFAULT_DEVICE_NAME);
this->setAppearance(DEFAULT_APPEARANCE);
Expand All @@ -68,12 +69,9 @@ BLEPeripheral::~BLEPeripheral() {
}
}

void BLEPeripheral::begin() {
unsigned char BLEPeripheral::updateAdvertismentData() {
unsigned char advertisementDataSize = 0;

BLEEirData advertisementData[3];
BLEEirData scanData;

scanData.length = 0;

unsigned char remainingAdvertisementDataLength = BLE_ADVERTISEMENT_DATA_MAX_VALUE_LENGTH + 2;
Expand Down Expand Up @@ -131,6 +129,11 @@ void BLEPeripheral::begin() {
memcpy(scanData.data, this->_localName, scanData.length);
}

return advertisementDataSize;
}

void BLEPeripheral::begin() {

if (this->_localAttributes == NULL) {
this->initLocalAttributes();
}
Expand Down Expand Up @@ -158,6 +161,7 @@ void BLEPeripheral::begin() {
this->addRemoteAttribute(this->_remoteServicesChangedCharacteristic);
}

int advertisementDataSize = updateAdvertismentData();
this->_device->begin(advertisementDataSize, advertisementData,
scanData.length > 0 ? 1 : 0, &scanData,
this->_localAttributes, this->_numLocalAttributes,
Expand Down Expand Up @@ -203,6 +207,26 @@ void BLEPeripheral::setBondStore(BLEBondStore& bondStore) {
this->_device->setBondStore(bondStore);
}

void BLEPeripheral::startAdvertising() {
int advertisementDataSize = updateAdvertismentData();
this->_device->updateAdvertisementData(
advertisementDataSize, advertisementData,
scanData.length > 0 ? 1 : 0, &scanData);
this->_device->startAdvertising();
}

void BLEPeripheral::stopAdvertising() {
this->_device->stopAdvertising();
}

void BLEPeripheral::startScanning() {
this->_device->startScanning();
}

void BLEPeripheral::stopScanning() {
this->_device->stopScanning();
}

void BLEPeripheral::setDeviceName(const char* deviceName) {
this->_deviceNameCharacteristic.setValue(deviceName);
}
Expand Down Expand Up @@ -263,6 +287,12 @@ void BLEPeripheral::setEventHandler(BLEPeripheralEvent event, BLEPeripheralEvent
}
}

void BLEPeripheral::setEventHandler(BLEDeviceEvent event, BLEDeviceEventHandler eventHandler) {
if (event < sizeof(this->_deviceEvents)) {
this->_deviceEvents[event] = eventHandler;
}
}

bool BLEPeripheral::characteristicValueChanged(BLECharacteristic& characteristic) {
return this->_device->updateCharacteristicValue(characteristic);
}
Expand Down Expand Up @@ -375,7 +405,7 @@ void BLEPeripheral::BLEDeviceRemoteCharacteristicValueChanged(BLEDevice& /*devic
remoteCharacteristic.setValue(this->_central, value, valueLength);
}

void BLEPeripheral::BLEDeviceAddressReceived(BLEDevice& /*device*/, const unsigned char* /*address*/) {
void BLEPeripheral::BLEDeviceAddressReceived(BLEDevice& device, const unsigned char* address) {
#ifdef BLE_PERIPHERAL_DEBUG
char addressStr[18];

Expand All @@ -384,12 +414,31 @@ void BLEPeripheral::BLEDeviceAddressReceived(BLEDevice& /*device*/, const unsign
Serial.print(F("Peripheral address: "));
Serial.println(addressStr);
#endif
BLEDeviceEventHandler eventHandler = this->_deviceEvents[BLEAddressReceived];
if (eventHandler) {
eventHandler(address);
}
}

void BLEPeripheral::BLEDeviceTemperatureReceived(BLEDevice& /*device*/, float /*temperature*/) {
void BLEPeripheral::BLEDeviceTemperatureReceived(BLEDevice& device, float temperature) {
BLEDeviceEventHandler eventHandler = this->_deviceEvents[BLETemperatureReceived];
if (eventHandler) {
eventHandler(&temperature);
}
}

void BLEPeripheral::BLEDeviceBatteryLevelReceived(BLEDevice& /*device*/, float /*batteryLevel*/) {
void BLEPeripheral::BLEDeviceBatteryLevelReceived(BLEDevice& device, float batteryLevel) {
BLEDeviceEventHandler eventHandler = this->_deviceEvents[BLEBatteryLevelReceived];
if (eventHandler) {
eventHandler(&batteryLevel);
}
}

void BLEPeripheral::BLEDeviceAdvertisementReceived(BLEDevice& device, const unsigned char* advertisement) {
BLEDeviceEventHandler eventHandler = this->_deviceEvents[BLEAdvertisementReceived];
if (eventHandler) {
eventHandler(advertisement);
}
}

void BLEPeripheral::initLocalAttributes() {
Expand Down
Loading