65.9K
CodeProject 正在变化。 阅读更多。
Home

Arduino 101 蓝牙低功耗

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2016年11月16日

CPOL

5分钟阅读

viewsIcon

29122

在本文中,我们将讨论如何创建 BLE 服务并与 Android 设备进行通信。

获取新的英特尔® 物联网开发套件,这是一个完整的硬件和软件解决方案,允许开发人员使用英特尔® Galileo 和英特尔® Edison 开发板创建令人兴奋的新解决方案。请访问英特尔® 物联网开发人员专区

引言

蓝牙* 低功耗(Bluetooth LE 或 BLE)是一种低功耗、短距离无线通信技术,非常适合用于物联网 (IoT)。BLE 专为小规模和独立数据传输而设计,提供客户端和服务器之间快速连接以及简单的用户界面,这使其非常适合控制和监控应用。Arduino 101* 包含板载蓝牙 LE,使开发人员能够与支持蓝牙的设备(例如手机和平板电脑)进行交互。我们将讨论如何创建 BLE 服务并与 Android 设备进行通信。我们还设置了一个 BLE 血压监测系统,以展示 Arduino 101* 的 BLE 功能。

硬件组件

此项目中使用的硬件组件如下所示

此项目将使用 Grove 套件中的角度旋转传感器,如图 1 所示,以及其他组件。

有关安装英特尔® Curie 开发板和为 Arduino 101* 平台设置软件开发环境的详细信息,请访问https://software.intel.com/en-us/articles/fun-with-the-arduino-101-genuino-101

图 1:带旋转角度传感器的 Arduino 101*。

中央设备和外围设备

蓝牙 LE 支持网络设备的两个主要角色:中央设备和外围设备。

中央设备:一种蓝牙设备,例如智能手机、平板电脑或 PC,它向正在广播的外围设备发起传出连接请求。连接到外围设备后,中央设备可以交换数据、从外围设备读取值以及在外围设备上执行命令。

外围设备:一种 BLE 设备,在广播后接受传入连接请求。它收集并发布数据供其他设备使用。

中央设备通过广播包与外围设备通信。外围设备发出广播,中央设备扫描广播。

图 2:中央设备和外围设备通信。

通用属性配置文件 (GATT)

Arduino 101* 蓝牙 LE 基于通用属性配置文件 (GATT) 架构。GATT 定义了一个分层数据结构,该结构暴露给连接的蓝牙 LE 设备。GATT 配置文件是一种通过 BLE 链路指定小传输数据的方式。这些通过 BLE 链路的小数据传输称为属性。GATT 构建在属性协议 (ATT) 之上。ATT 传输属性,属性格式化为特征和服务。要了解有关蓝牙 LE 和 GATT 的更多信息,请参阅https://www.bluetooth.com/what-is-bluetooth-technology/bluetooth-technology-basics/low-energyhttps://www.bluetooth.com/specifications/gatt

外围数据结构

在 GATT 架构中,数据被组织成服务和特征。服务是封装外围设备行为的一组功能。特征是服务的定义属性,提供有关它的额外信息。例如,血压服务的特征是血压测量、中间袖带压力和血压特征。

图 3:蓝牙服务和特征关系。

创建血压 BLE 服务

要创建 BLE 服务,您需要知道服务号和相应的特征号。在蓝牙页面上,选择 GATT 规范 -> 服务 以获取 GATT 服务的完整列表。

图 4:蓝牙 GATT 规范下拉菜单。

选择血压服务并获取 BLEService 构造函数的服务号。

图 5:蓝牙服务。

蓝牙页面上,选择 GATT 规范 -> 特征 以访问血压特征号。

图 6:蓝牙特征。

接下来,包含 Arduino 101* CurieBLE 库组件,以启用与其他蓝牙* 设备的通信和交互。您可以在https://github.com/01org/corelibs-arduino101 找到开源 CurieBLE 库。

#include <CurieBLE.h>
BLEPeripheral blePeripheral;                // BLE Peripheral Device
BLEService bloodPressureService("1810");    // Blood Pressure Service 
// BLE Blood Pressure Characteristic"
BLECharacteristic bloodPressureChar("2A35",  // standard 16-bit characteristic UUID
BLERead | BLENotify, 2);     // remote clients will be able to
// get notifications if this characteristic changes

为外围 BLE 设备设置本地名称。当手机(中央设备)连接到此外围蓝牙* 设备时,本地名称将显示在手机上以识别连接的外围设备。

blePeripheral.setLocalName("BloodPressureSketch");
blePeripheral.setAdvertisedServiceUuid(bloodPressureService.uuid());  // add the service UUID
blePeripheral.addAttribute(bloodPressureService);   // Add the BLE Blood Pressure service
blePeripheral.addAttribute(bloodPressureChar);       // add the blood pressure characteristic

将血压设备连接到 Arduino 101* 平台的模拟引脚 A0。在此示例中,使用角度旋转传感器模拟血压设备。

int pressure = analogRead(A0);
int bloodPressure = map(pressure, 0, 1023, 0, 100);

更新血压测量特征。中央设备将看到此更新的血压值。例如,如果手机连接到外围血压设备,手机可以通过 Android 应用读取更新的血压值。

bloodPressureChar.setValue(bloodPressureCharArray, 2);

Android 设备与 Arduino 传感器通信

外围设备通过蓝牙* 广播与中央 Android 设备通信。在广播中,外围设备向周围的每个设备广播数据包。中央设备扫描并连接到外围设备以接收数据并获取更多信息。请按照以下步骤启用 Android 设备与 Arduino 传感器之间的通信。

  • 在 Android 设备上启用蓝牙。
  • Google Play 上有许多免费的 BLE Android 应用。在 Google Play 上搜索 BLE 并在 Android 设备上安装 BLE Android 应用。
  • 启动 BLE Android 应用。
  • 扫描并连接到 BloodPressureSketch 外围设备。
  • 读取或写入血压值。

图 7 显示了 Android 设备扫描 BloodPressureSketch 外围设备的示例。

图 7:Android 设备扫描 BLE 服务。

转动旋转角度传感器,在 Android 设备屏幕上查看血压值变化。

开发 Android 应用程序

访问https://developer.android.com.cn/guide/topics/connectivity/bluetooth-le.html,获取有关开发自己的 Android 应用以通过 Arduino 101* 平台与外围设备通信的详细信息。如果您是 Android 新手,请访问https://developer.android.com.cn/training/basics/firstapp/index.html,获取创建 Android 项目和构建您的第一个 Android 应用的说明。

Arduino IDE 示例草图

下面的代码示例 1 提供了血压测量示例代码。打开串行控制台以查看结果输出。

#include <CurieBLE.h>

/*
   This sketch example partially implements the standard Bluetooth Low-Energy Battery service.
   For more information: https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx
*/

/*  */
BLEPeripheral blePeripheral;                // BLE Peripheral Device (the board you're programming)
BLEService bloodPressureService("1810");    // Blood Pressure Service


// BLE Blood Pressure Characteristic"
//BLECharacteristic bloodPressureChar("2A49",  // standard 16-bit characteristic UUID
BLECharacteristic bloodPressureChar("2A35",  // standard 16-bit characteristic UUID
    BLERead | BLENotify, 2);     // remote clients will be able to
// get notifications if this characteristic changes

int oldBloodPressure = 0;   // last blood pressure reading from analog input
long previousMillis = 0;    // last time the blood pressure was checked, in ms

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

  /* 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("BloodPressureSketch");
  blePeripheral.setAdvertisedServiceUuid(bloodPressureService.uuid());  // add the service UUID
  blePeripheral.addAttribute(bloodPressureService);   // Add the BLE Blood Pressure service
  blePeripheral.addAttribute(bloodPressureChar); // add the blood pressure characteristic
  
  const unsigned char charArray[2] = { 0, (unsigned char)0 };
  bloodPressureChar.setValue(charArray, 2);   // initial value for this 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...");
}

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

  // if a central is connected to peripheral:
  if (central) {
    Serial.print("Connected to central: ");
    // print the central's MAC address:
    Serial.println(central.address());
    // turn on the LED to indicate the connection:
    digitalWrite(13, HIGH);

    // check the blood pressure mesurement every 200ms
    // as long as the central is still connected:
    while (central.connected()) {
      long currentMillis = millis();
      // if 200ms have passed, check the blood pressure mesurement:
      if (currentMillis - previousMillis >= 200) {
        previousMillis = currentMillis;
        updateBloodPressure();
      }
    }
    // when the central disconnects, turn off the LED:
    digitalWrite(13, LOW);
    Serial.print("Disconnected from central: ");
    Serial.println(central.address());
  }
}

void updateBloodPressure() {
  /* Read the current voltage mesurement on the A0 analog input pin.
     This is used here to simulate the blood pressure.
  */
  int pressure = analogRead(A0);
  int bloodPressure = map(pressure, 0, 1023, 0, 100);

  // If the blood pressure has changed
  if (bloodPressure != oldBloodPressure) {      
    Serial.print("The current blood pressure is: ");
    Serial.println(bloodPressure);
    const unsigned char bloodPressureCharArray[2] = { 0, (unsigned char)bloodPressure };
    // Update the blood pressure measurement characteristic
    bloodPressureChar.setValue(bloodPressureCharArray, 2);
    // Save the measurement for next comparison  
    oldBloodPressure = bloodPressure;           
  }
}
代码示例 1:Arduino IDE 的血压示例代码。

摘要

本文总结了 Arduino 101* 平台如何与 Android 设备通信,并描述了创建 BLE 服务的步骤。有关在 Arduino IDE 中使用 BLE 的更多示例,请参阅https://www.arduino.cc/en/Reference/CurieBLE。如果您对 Arduino 101* 平台感兴趣,请访问http://www.intel.com/buy/us/en/product/emergingtechnologies/intel-arduino-101-497161 获取更多信息。

有用参考

关于作者

Nancy Le 是英特尔公司软件和服务部门的软件工程师,从事英特尔® 凌动™ 处理器规模化项目

© . All rights reserved.