Skip to content

BLE central Role implementation and peripheral refactor #255

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

Merged
merged 2 commits into from
Sep 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,21 @@ them to the [support forum](https://forum.arduino.cc/index.php?board=103).
> "How do I use this library?"

> "I can't get this example sketch to work. What am I doing wrong?"

# Enable debug interface on Serail1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be Serial1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the typo


* Default disable the debug interface.

If you want to enable debug trace on Serial1 to debug corelib, follow these instructions.

1. Shut down the IDE
2. Go to Arduino15 directory
* Windows: `C:\Users\<user>\AppData\Roaming\Arduino15`
* OS X: `~/Library/Arduino15`
* Linux: `~/.arduino15`
3. Modify the platform.txt
* Find `compiler.c.flags` and add `-DCONFIGURE_DEBUG_CORELIB_ENABLED` at the end of this line
* Find `compiler.cpp.flags` and add `-DCONFIGURE_DEBUG_CORELIB_ENABLED` at the end of this line
4. Initial Serial1 in your sketch
* Add `Serial1.begin(115200);` in your `setup()`
5. Adjust the output level at log_init function in log.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,25 @@
* POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef NORDIC_INTERFACE_H
#define NORDIC_INTERFACE_H
#include "infra/ipc_uart.h"
#include <stdarg.h>
#include <cstdio>
#include "UARTClass.h"

void uart_ipc_message_cback(uint8_t cpu_id, int channel, int len, void * p_data);
int send_message_ipc_uart(struct message * message);
void free_message_ipc_uart(struct message * message);
int nordic_interface_init(T_QUEUE queue);
extern "C" void printk(const char *fmt, va_list args);
Copy link
Contributor

@eriknyquist eriknyquist Jul 29, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is printk/vsnprintf really needed for BLE central?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for central. Only for debug.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'm just not sure why we need a new function to print formatted strings, when there are already some options for that available. Which specific features of vsnprintf are required to debug BLE Central?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this function and use vsnprintf in cstdio.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just want debug corelib easier.

extern UARTClass Serial1;
#define PRINTK_BUFSIZ 256

void printk(const char *fmt, va_list args)
{
#ifdef CONFIGURE_DEBUG_CORELIB_ENABLED
int len = 0;

char tmp[PRINTK_BUFSIZ];

len = vsnprintf(tmp, PRINTK_BUFSIZ, fmt, args);

tmp[len] = '\0';
Serial1.println(tmp);
#endif
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"cores/arduino/wiring_shift.c" this file has a permission mode change, and nothing else, committed. Can you remove it please? (Sorry, I couldn't leave a comment on the permission change itself, so I'm leaving it here on an unrelated file)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't change this file. It should be referenced from merge or rebase. I will fix this.


#endif // NORDIC_INTERFACE_H
108 changes: 108 additions & 0 deletions libraries/CurieBLE/examples/BatteryAdvChange/BatteryAdvChange.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/* Please see code cpyright at the bottom of this example code */
/*
This sketch illustrates how to change the advertising data so that it is visible but not
connectable. Then after 10 seconds it changes to being connectable
This sketch example partially implements the standard Bluetooth Low-Energy Battery service.
*/

#include <CurieBLE.h>

BLEPeripheral blePeripheral; // BLE Peripheral Device (the board you're programming)
BLEService batteryService("180F"); // BLE Battery Service
int count = 0;
// BLE Battery Level Characteristic"
BLEUnsignedCharCharacteristic batteryLevelChar("2A19", // standard 16-bit characteristic UUID
BLERead | BLENotify); // remote clients will be able to
// get notifications if this characteristic changes

void setup() {
Serial.begin(9600); // initialize serial communication
pinMode(13, OUTPUT); // initialize the LED on pin 13 to indicate when a central is connected
while (!Serial) {
//wait for Serial to connect
}
/* Set a local name for the BLE device
This name will appear in advertising packets
and can be used by remote devices to identify this BLE device
The name can be changed but maybe be truncated based on space left in advertisement packet */
blePeripheral.setLocalName("BatteryAdvChangeSketch");
blePeripheral.setAdvertisedServiceUuid(batteryService.uuid()); // add the service UUID
blePeripheral.addAttribute(batteryService); // Add the BLE Battery service
blePeripheral.addAttribute(batteryLevelChar); // add the battery level characteristic

/* Now activate the BLE device. It will start continuously transmitting BLE
advertising packets and will be visible to remote BLE central devices
until it receives a new connection */

blePeripheral.begin();
Serial.println("Bluetooth device active, waiting for connections...");
Serial.println("Starts in Connectable mode");
}

void loop() {
// listen for BLE peripherals to connect:
BLECentralHelper central = blePeripheral.central();
// wait
Serial.print(". ");
if (count == 10) {
Serial.print("\nReached count ");
Serial.println(count);

}
delay (1000);
count++;
// Switch from Connectable to Non Connectable and vice versa
if (count > 10 ) {
static bool change_discover = false;
Serial.println("Stop Adv and pausing for 10 seconds. Device should be invisible");
// Some central devices (phones included) may cache previous scan inofrmation
// restart your central and it should not see this peripheral once stopAdvertising() is called
blePeripheral.stopAdvertising();
delay(10000);

if (change_discover)
{

// Using the function setAdvertisingParam we specify that it now NOT connectable
// The loop is for 10 seconds. Your central device may timeout later than that
// and may eventually connect when we set it back to connectable mode below
blePeripheral.setConnectable(false);
Serial.println("In Non Connectable mode");

}
else
{

//using the function setAdvertisingParam we specify that it now connectable
blePeripheral.setConnectable(true);
Serial.println("In Connectable mode");
}
Serial.println("Start Adv");
blePeripheral.startAdvertising();
if (change_discover) {
Serial.println("Adding 5 second delay in Non Connect Mode");
delay(5000);
}
change_discover = !change_discover;
count = 0;
}
}

/*
Copyright (c) 2016 Intel Corporation. All rights reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

35 changes: 34 additions & 1 deletion libraries/CurieBLE/examples/BatteryMonitor/BatteryMonitor.ino
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ void setup() {

void loop() {
// listen for BLE peripherals to connect:
BLECentral central = blePeripheral.central();
BLECentralHelper central = blePeripheral.central();

// if a central is connected to peripheral:
if (central) {
Expand All @@ -63,6 +63,14 @@ void loop() {
if (currentMillis - previousMillis >= 200) {
previousMillis = currentMillis;
updateBatteryLevel();

static unsigned short count = 0;
count++;
// update the connection interval
if(count%5 == 0){
delay(1000);
updateIntervalParams(central);
}
}
}
// when the central disconnects, turn off the LED:
Expand All @@ -87,6 +95,31 @@ void updateBatteryLevel() {
}
}

void updateIntervalParams(BLECentralHelper &central) {
// read and update the connection interval that peer central device
static unsigned short interval = 0x60;
ble_conn_param_t m_conn_param;
// Get connection interval that peer central device wanted
central.getConnParams(m_conn_param);
Serial.print("min interval = " );
Serial.println(m_conn_param.interval_min );
Serial.print("max interval = " );
Serial.println(m_conn_param.interval_max );
Serial.print("latency = " );
Serial.println(m_conn_param.latency );
Serial.print("timeout = " );
Serial.println(m_conn_param.timeout );

//Update connection interval
Serial.println("set Connection Interval");
central.setConnectionInterval(interval,interval);

interval++;
if(interval<0x06)
interval = 0x06;
if(interval>0x100)
interval = 0x06;
}
/*
Copyright (c) 2016 Intel Corporation. All rights reserved.

Expand Down
6 changes: 3 additions & 3 deletions libraries/CurieBLE/examples/CallbackLED/CallbackLED.ino
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,19 @@ void loop() {
blePeripheral.poll();
}

void blePeripheralConnectHandler(BLECentral& central) {
void blePeripheralConnectHandler(BLEHelper& central) {
// central connected event handler
Serial.print("Connected event, central: ");
Serial.println(central.address());
}

void blePeripheralDisconnectHandler(BLECentral& central) {
void blePeripheralDisconnectHandler(BLEHelper& central) {
// central disconnected event handler
Serial.print("Disconnected event, central: ");
Serial.println(central.address());
}

void switchCharacteristicWritten(BLECentral& central, BLECharacteristic& characteristic) {
void switchCharacteristicWritten(BLEHelper& central, BLECharacteristic& characteristic) {
// central wrote new value to characteristic, update LED
Serial.print("Characteristic event, written: ");

Expand Down
143 changes: 143 additions & 0 deletions libraries/CurieBLE/examples/IMUBleCentral/IMUBleCentral.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
Copyright (c) 2016 Intel Corporation. All rights reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <CurieBLE.h>

/*
This sketch example partially implements the standard Bluetooth Low-Energy Battery service.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove this comment and replace it with something that describes what this sketch does?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the comments.

For more information: https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx
*/

#define MAX_IMU_RECORD 1

struct bt_le_conn_param conn_param = {0x18, 0x28, 0, 400};
typedef struct {
int index;
unsigned int slot[3];
} imuFrameType;

imuFrameType imuBuf[MAX_IMU_RECORD];
BLECentral bleCentral; // BLE Central Device (the board you're programming)

BLEService bleImuService("F7580001-153E-D4F6-F26D-43D8D98EEB13");
BLECharacteristic bleImuChar("F7580003-153E-D4F6-F26D-43D8D98EEB13", // standard 128-bit characteristic UUID
BLERead | BLENotify, sizeof(imuBuf)); // remote clients will be able to
// get notifications if this characteristic changes

void ble_connected(BLEHelper &role)
{
BLEPeripheralHelper&peripheral = *(BLEPeripheralHelper*)(&role);
Serial.println("Connected");

// Start discovery the profiles in peripheral device
peripheral.discover();
}

void bleImuCharacteristicWritten(BLEHelper& central, BLECharacteristic& characteristic)
{
// Peripheral wrote new value to characteristic by Notification/Indication
const unsigned char *cvalue = characteristic.value();
const imuFrameType *value = (const imuFrameType *)cvalue;
Serial.print("\r\nCharacteristic event, written: ");
Serial.print(value->index);
Serial.print("\t");
Serial.print(value->slot[0]);
Serial.print("\t");
Serial.print(value->slot[1]);
Serial.print("\t");
Serial.println(value->slot[2]);
}

bool adv_found(uint8_t type,
const uint8_t *data,
uint8_t data_len,
void *user_data)
{
bt_addr_le_t *addr = (bt_addr_le_t *)user_data;
int i;

Serial.print("[AD]:");
Serial.print(type);
Serial.print(" data_len ");
Serial.println(data_len);

switch (type)
{
case BT_DATA_UUID128_SOME:
case BT_DATA_UUID128_ALL:
{
if (data_len % MAX_UUID_SIZE != 0)
{
Serial.println("AD malformed");
return true;
}
struct bt_uuid * serviceuuid = bleImuService.uuid();
for (i = 0; i < data_len; i += MAX_UUID_SIZE)
{
if (memcmp (((struct bt_uuid_128*)serviceuuid)->val, &data[i], MAX_UUID_SIZE) != 0)
{
continue;
}

// Accept the advertisement
if (!bleCentral.stopScan())
{
Serial.println("Stop LE scan failed");
continue;
}
Serial.println("Connecting");
// Connect to peripheral
bleCentral.connect(addr, &conn_param);
return false;
}
}
}

return true;
}

void setup() {
Serial.begin(115200); // initialize serial communication
pinMode(13, OUTPUT); // initialize the LED on pin 13 to indicate when a central is connected

bleImuChar.setEventHandler(BLEWritten, bleImuCharacteristicWritten);

/* Set a local name for the BLE device
This name will appear in advertising packets
and can be used by remote devices to identify this BLE device
The name can be changed but maybe be truncated based on space
left in advertisement packet */
bleCentral.addAttribute(bleImuService); // Add the BLE IMU service
bleCentral.addAttribute(bleImuChar); // Add the BLE IMU characteristic

/* Setup callback */
bleCentral.setAdvertiseHandler(adv_found);
bleCentral.setEventHandler(BLEConnected, ble_connected);

/* Now activate the BLE device. It will start continuously transmitting BLE
advertising packets and will be visible to remote BLE central devices
until it receives a new connection */
bleCentral.begin();
}


void loop()
{
delay(2000);
}

Loading