Skip to content
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

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

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
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 <sandeep.mistry@gmail.com>
maintainer=Sandeep Mistry <sandeep.mistry@gmail.com>
sentence=An Arduino library for creating custom BLE peripherals.
paragraph=Supports nRF8001 and nRF51822 based boards/shields
author=Sandeep Mistry <sandeep.mistry@gmail.com>, Florian Echtler <floe@butterbrot.org>
maintainer=Florian Echtler <floe@butterbrot.org>
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