简介
蓝牙* LE (BLE) 通信因其低成本和低能耗等优势,被越来越多的用于商用产品和娱乐性应用。 如果希望实现 Android* 手机或平板电脑与英特尔l® Edison 或英特尔® Galileo 项目之间的通信,蓝牙* LE (BLE) 无疑是最佳选择。
本文旨在为您介绍如何使用免费的软件工具和低成本、即时可用的硬件编写代码和连接硬件,以构建英特尔 Edison 与配备蓝牙 4.0 的 Android 设备之间的 BLE 通信。
什么是 BLE?
蓝牙低能耗 (BLE),蓝牙 LE,或 BLE (也称智能蓝牙)是一种无线个域网技术,由蓝牙特别兴趣小组设计和市场推广。 它主要针对健康医疗、健身、安全、自动化和家庭娱乐等行业的应用。
蓝牙 LE 最初由诺基亚于 2006 年推出,当时称为 Wibree。 2010 年,通过蓝牙版本 4.0 ,蓝牙 LE 加入了蓝牙标准的行业。
相比于标准蓝牙连接,BLE 可显著降低设备的能耗,同时提供常规蓝牙的大部分连接性以及约一半的连接范围(大约 15 米/50 英尺)。 安装电池的设备如果使用蓝牙 LE,可在不充电或更换电池的情况下运行数年。 比如,Estimote 推出的 Beacon 设备宣称,其电池寿命可长达三 (3) 年(www.estimote.com)。
硬件
尽管我们的专注点在于英特尔 Edison,但本篇文章的大部分内容也适用于英特尔 Galileo。 就物联网项目而言,我们使用的物理传感器和控制来自于 Seeed Studio 的 Grove 系统。 具体来说,我们将使用:
- 带有 Arduino breakout 开发板的英特尔 Galileo
- Seeed Grove – Starter Kit Plus Intel® IoT Edition For Galileo GEN 2
- Seeed Grove BLE
- 运行 Android 4.3 或更高版本的 Android 设备(我使用 Lenovo TAB S8-50)
- 面向开发且运行 Windows* 7 或 8 的 PC(我使用 Dell XPS12)
关于硬件的几点说明:
- Grove Starter Kit标注为针对英特尔 Galileo 而设计,但它同时也适用于 Edison。 您还可以单独购买 Grove 组件,但套件更加划算。
- 在开发过程中我使用的是 Lenovo Android 平板电脑,但其他运行 Android 4.3 并支持蓝牙 4.0 的 Android 设备也均可行。
- 我使用 Dell XPS12 为英特尔 Edison 和 Android 项目(以及本文)编写代码。 采用 Mac* 或 Linux* 系统也可进行开发。
软件
我使用下列几款免费的软件工具。 如欲查看本示例,您应根据需要下载并安装下列软件工具:
- 面向英特尔® Edison 的 Arduino IDE : https://software.intel.com/zh-cn/articles/install-arduino-ide-on-intel-iot-platforms
- Android Studio: https://developer.android.com/sdk/installing/studio.html
- Android SDK: https://developer.android.com/sdk/index.html?hl=i
Windows、Mac 和 Linux 均可提供上述软件,不过我将特别介绍基于 Windows 的安装。
硬件详情
英特尔® Edison
英特尔® Edison 是低成本、通用型计算平台系列计划的首款硬件。 经过专门设计,它有助于快速、轻松地构建物联网项目的原型,同时还可提供面向商业化的产品就绪型路径。
英特尔® Edison 使用 22 纳米英特尔® SoC,后者包含运行速度高达 500MHz 的双核英特尔® 凌动™ 处理器。 它支持 40 个 GPIO,并以微小外形集 1GB LPDDR3 RAM、4 GB EMMC 存储,以及双频 Wi-Fi* 和蓝牙于一身。
就内在系统而言,Edison 运行完整 Linux 内核。为了发挥 Edison 的最佳性能,您可能希望编写硬件级 Linux 代码。
但 Edison Linux 还以 Linux 程序的形式包含 Arduino 实施。 简单来说,这意味着您可以编写熟悉的 Arduino sketch,并在 Edison 开发板上运行这些 sketch。 这就是我们下面要进行的操作。
如欲了解更多有关英特尔 Edison 的信息,请访问: http://www.intel.com/content/www/us/en/do-it-yourself/edison.html
Arduino Breakout 开发板
面向英特尔 Galileo 的 Arduino breakout 开发板包含两种用途。 第一,它提供更大的原型构建平台,以轻松访问 IO 针脚。 第二,它提供可兼容 Arduino 的硬件平台,这意味着我们能够同时使用标准 Arduino 屏蔽器和英特尔 Edison (与英特尔 Galileo 的用法类似)。 图 1 所示为安装于 Arduino breakout 开发板的 Edison。
图 1.安装于 Arduino breakout 开发板的英特尔® Edison
Grove Starter Kit Plus
该套件的全称为 “Grove Starter Kit Plus - Intel® IoT Edition for Intel® Galileo Gen 2 Developer Kit”,最初针对英特尔 Galileo 第二代开发板而设计。 幸运的是,它通过 Arduino breakout 开发板可完全兼容英特尔 Edison。
该套件(如图 2 所示)旨在借助传感器、制动器和屏蔽器简化运行和原型构建。 它包含一个可兼容 Arduino 的屏蔽器以及四 (4) 个标准化针脚连接器。 这些连接器供应给可连接线缆的 IO 端口,其中的线缆也可轻松连接套件内的传感器和控制器。 这意味着,您可轻松构建项目,无需摆弄小型电线,上拉/下拉电阻,也无需担心极性问题。
如欲了解更多信息或购买套件,请访问: http://www.seeedstudio.com/depot/Grove-starter-kit-plus-Intel-IoT-Edition-for-Intel-Galileo-Gen-2-p-1978.html
Grove 套件的生产商 Seeed Studios 在线提供许多有用资源。
具体而言,我推荐克隆或下载 Sketchbook Starter 库,具体请访问: http://Github.com/Seeed-Studio/Sketchbook_Starter_Kit_V2.0
请访问下列链接,为 Grove Wiki 页面设置书签: http://www.seeedstudio.com/wiki/index.php?title=Main_Page#Grove
图 2. Grove Starter Kit Plus - Intel® IoT Edition for Intel® Galileo Gen 2 Developer Kit
Grove BLE V1
我们将使用 Grove 蓝牙低能耗 v1 模块,该模块不包含在入门套件中,但可通过 Grove 屏蔽器和连接器线缆兼容针脚。 它还是一种成本相对较低的 BLE 附件,在本文撰写过程中,它的成本最低。
Grove BLE v1 的开发基于行业标准德州仪器 CC2540。 许多其他设备均使用这种芯片。 如果您有其他的 TI CC2540 BLE 模块,比如 RedBear BLE Mini,您可以轻松修改示例代码。
更多 Grove BLE v1 详情,请访问: http://www.seeedstudio.com/wiki/index.php?title=Grove_BLE_v1&uselang=en
请注意,英特尔® Edison 确实包含支持 Wi-Fi 和 蓝牙 4.0/BLE 的板载无线模块,但 Grove BLE 模块可大大简化软硬件的设置。 使用 Grove BLE(图 3)还意味着这些项目可轻松适应英特尔 Edison。
图 3. Grove BLE V1 模块
调试 Android 设备
BLE 支持已添加至Android 4.3(API 级别:18)。 您需要运行 4.3 或更高版本的设备来通过 BLE 进行通信。
如欲了解更多有关 Android BLE 的信息,请访问: https://developer.android.com/guide/topics/connectivity/bluetooth-le.html
如果之前没有 Android 开发经验,您需要在手机或平板电脑上启用开发人员选项,然后将其用于运行和调试软件。 打开设置应用,滚动至底部,选择 “About device”,然后点击构建编号七 (7) 次,以解锁开发人员选项。
现在,设置下方应显示 Developer Options,请务必确认 “USB debugging”。
如欲了解更多有关 Android 开发人员选项的信息,请访问: http://developer.android.com/tools/device.html
安装软件并开始编写代码!
面向英特尔® Galileo 的 Arduino IDE
您需要下载专门准备的 Arduino IDE 版本,以将 Sketch 部署至英特尔 Edison 或 Galileo。 本文撰写之时,当前的版本为 1.5.3,位于:
https://software.intel.com/zh-cn/articles/install-arduino-ide-on-intel-iot-platforms
英特尔® Edison 驱动程序
您还需要从上述链接下载和安装英特尔 Edison 驱动程序。 它应该位于 “Driver Software” 下方页面的最后一个链接。 本文撰写之时,其版本为 1.0.0。
如需其他说明,下列链接提供了有用的入门指南:
software.intel.com/iot/getting-started
Android Studio
Android Studio 是一款面向 Android 开发的全新 Java* IDE,基于 IntelliJ IDEA* (https://www.jetbrains.com/idea/)。 尽管目前还只是测试版,但它性能稳定,功能齐全。 如果您习惯使用面向 Android 开发的 Eclipse* 或 IntellliJ IDEA,那您应该可以轻松理解下列关于两者用法的演示。
Android Studio 包含 Android SDK,可大幅简化安装流程。 只需下载、从压缩文件中提取内容,然后在 bin 文件夹中运行 studio.exe 即可。
如欲了解更多有关 Android Studio 的信息,请访问: https://developer.android.com/sdk/installing/studio.html
Android SDK
你可能需要下载其他 SDK 软件包。 为此,请在 Android Studio 的工具栏中点击 "SDK Manager"。 关于配置 Android SDK,我们在此不做介绍,请访问下列链接,了解更多详情:
https://developer.android.com/sdk/installing/adding-packages.html
如果之前安装过 Android SDK,您可以配置 Android Studio,并将其指向正确的路径,如图 4 所示
在 Android Studio 中,点击 Configure -> Project Defaults -> Project Structure,并设置路径。
图 4.在 Android* Studio 中设置 SDK 路径
测试英特尔® Edison
在开始演示之前,请确保您能够运行 Blink示例 sketch。 它位于 examples -> 01.Basics -> Blink文件夹中的 Arduino IDE 下载软件包。
如欲了解更多信息,请参阅 Edison 入门指南:
https://communities.intel.com/community/makers/edison/getting-started
Android Hello World
安装 Android Studio 后,请确保您能够创建新项目,并在 Android 设备上运行该项目。
- 连接 Android 设备和 PC
- 打开 Android Studio
- 选择 "New Project…"
- 选择名称和位置,并点击 "Next" 3 次 (API 15/Blank Activity)
- 点击 Finish,并等待项目创建完成(可能耗时 20 多秒)
- 移动工具栏中的绿色 Play 图标
- 选择您的设备,并按下 "OK"
如果所有步骤都正确,您的 Android 屏幕应显示 “Hello world!”(图 5)
图 5. Android* Studio Hello World 应用
BLE 工作原理?
BLE 根据需要提供短数据包,然后关闭链路。 这是蓝牙 LE 实现低能耗的原因之一。 相比于常规蓝牙的传统配对方法,BLE 设备仅在需要收发信息时进行链接。
BLE 的通信方式极其严密。 设备显示收发数据的服务,后者包含称之为特征的内容,以定义可共享的数据。 如需获取更多详情,特征可包含描述符,帮助定义数据。 例如,您可以拥有一项标记为 "Heart Rate Monitor"的服务,该服务包含 "heart rate measurement"等特征。
大多数蓝牙 LE API 都支持搜索本地设备和发现有关这些设备的服务、特征和描述符。
BLE 关键术语和概念
下面简单介绍启动 BLE 项目之前应该了解的关键 BLE 术语和概念。
通用属性配置文件 (GATT)
GATT 配置文件是关于通过蓝牙低能耗链路收发短数据片(称为 "属性")的通用规范。 当前所有的 LE 应用配置文件均以 GATT 为基础。 蓝牙特别兴趣小组 (SIG) (https://www.bluetooth.org) 对 BLE 设备的配置文件数量进行了预定义。 这些配置文件是关于描述设备使用方法的规范。
属性协议 (ATT)
属性协议 (ATT) 指 GATT 的构建基础。 ATT 是专门针对 BLE 设备而设计的优化型协议。 ATT 通信发送字节尽可能少的数据。 所有属性均带有通用唯一标识符 (UUID),后者为标准的 128 位字符串 ID,以唯一的方式识别信息。 ATT 传输的属性被格式化为特征和服务(定义如下)。
特征
特征包含一个单独数值以及 0 或多个描述符(见下文)以描述特征的值。
描述符
描述符指定义了的属性,可描述特征值。 它们可能是人类可读的描述,可注明单位或测量,或定义可接受的数值范围。
服务
服务指特征的集合。 下列链接提供了基于现有 GATT 的配置文件列表: https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx
将数据从 Android 发送至英特尔® Edison
前提条件
本文余下内容将假设您有一个面向英特尔 Edison 和 Android 开发而设置和配置的开发系统。 请确保您已完成下列步骤,并根据需要检查之前的内容。
- 安装英特尔 Arduino* IDE
- 安装英特尔 Edison 驱动程序
- 安装 Android Studio
- 安装 Android SDK
- 在英特尔 Edison上部署和运行 Blink 演示
- 部署和运行空白 Hello world Android 项目
Android 中的 BLE
您可以访问下列链接,从 GitHub 下载完整的项目:
https://github.com/adrianstevens/Edison_to_Android_BLE/tree/master/Android/BLEConnect
但我建议您构建自己的项目,并参考上述链接逐行写入代码。
创建新项目
打开 Android Studio(或选择的 IDE),创建新的空白 Android 应用,并将其命名为 BLEConnect。 请务必将最低 SDK 设置为至少 API 18。 否则,您将无法使用 BLE API。
图 6.创建一个新的 Android 应用:
接下来打开 AndroidManifest.xml,并在 <application>
标签上方添加下列内容,以添加所需的权限:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
设置 UI
为了简单起见,我们只使用默认布局,但我们需要为 TextView 设置一个 ID。 打开 layout -> activity_main.xml,选择 TextView,并将 ID 设置为 mainText
,以便我们在代码中引用该 ID。
图 7.设置 TextView 的资源 id
MainActivity
就该项目而言,代码其余部分将进入 MainActivity。 如果您逐行添加代码,那么请注意,Android Studio 将自动检测丢失的输入,并提示您添加。
示例代码将:
- 检查 Android 设备中的 BLE 支持
- 搜索附近的 BLE 设备
- 识别和连接 Grove BLE 模块
- 为已知通信服务搜索可用的服务
- 查找通信服务的传输特征
- 通过将数值写入特征来发送消息
我在此不一一介绍每行代码,仅介绍一些核心概念。
类别层变量和静态值
我们在连接 BLE 模块、搜索服务和发送消息的过程中保存了一些数值。 我们还将为 Grove BLE v1 (TI CC2540) 添加部分已知静态值。 如果您使用其他模块,可能需要进行调整。 具体而言,我建议定义收发特征,例如:
CHARACTERISTIC_TX = "0000ffe1-0000-1000-8000-00805f9b34fb"
CHARACTERISTIC_RX = "0000ffe1-0000-1000-8000-00805f9b34fb"
状态辅助方法
为了简单起见,我们在之前标记的 TextView 上显示我们的进度。 代码包含一种简单的辅助方法,名为 statusUpdate
,帮助我们将状态消息写入屏幕和控制台。 它还可返回至 UI 线程,以便我们安全从任一线程调用该方法。
连接 BLE 设备
为引用 Bluetooth Manager,我们首先应查看设备是否提供 BLE,调用 getSystemService
以引用 Bluetooth Manager (BluetoothManager
),然后调用 getAdapter()
方法,以引用 BluetoothAdapter
项目。 或者,您还可以直接从 Bluetooth Manager 类使用静态帮助方法 getDefaultAdapter
。
搜索附近的 BLE 设备
搜索设备时,我们使用计时器搜索特定时间段。 我们调用 Bluetooth manager 项目中的 startLeScan
,并传入至回调项目,以知晓是否搜索到设备。
API 持续扫描设备,因此,我们可能会在每台设备的 LeScanCallback
中接收到多个通知,所以在保存之前,我们应确认该设备入口的唯一性。 我们还要检查模块的设备名称,并保存引用。 就本示例而言,我们实际上不需要将设备保存在列表中。
@Override
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord)
{…
}
查找通信服务
大多数 BLE 设备都会显示一个或多个服务以供通信/互动。 Grove BLE 中的 TI CC2540 包含一个 ID 为 “0000ffe0-0000-1000-8000-00805f9b34fb” 的关键服务。 接下来,我们将查找引用,并将其保存至该服务。
首先,我们需要连接设备。 为了知晓连接时间或查找到服务的时间,我们需要 BluetoothGattCallback
项目,并覆盖 onConnectionStateChanged
和 onServicesDiscovered
。
请注意,使用 onConnectionStateChanged
方法时,如果获悉连接成功,我们可调用 mBluetoothGatt.discoverServices()
搜索服务。 识别到所需的服务后,我们可以继续发送消息。
@Override
public void onConnectionStateChange (BluetoothGatt gatt, int status, int newState)
{…
}
@Override
public void onServicesDiscovered (BluetoothGatt gatt, int status)
{
…
}
许多其他方法可以被覆盖。 请访问此处参阅其中的文档:
https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback.html
发送消息
示例代码提供了一种 sendMessage
方法。 我们通过 UDID 识别到所需的特征后,调用该特征的 setValue
。 最后,我们调用 BluetoothGatt 引用中的 writeCharacteristic
,从而输入特征值,以发送数据。
有许多 setValue
过载,但实际上可用一种更简单的过载来发送字符串,不过由于大多数 BLE 通信以字节的形式发送命令,因此这种示例更加有用。
现在开始设置英特尔 Edison。
采用 Grove Breakout 开发板和 BLE 模块设置英特尔® Edison
首先组装基础硬件。 如果没有准备硬件,那么请将英特尔 Edison 安装至 Arduino breakout 开发板。
接下来,将屏蔽器底部的针脚对准 Arduino breakout 开发板,安装 Grove 屏蔽器。 然后连接 Grove BLE v1 和串行 UART 端口。
图 8. Grove 屏蔽器和 BLE 模块相连后的英特尔® Edison
我们的首个 Sketch
我们现在要在 Android 设备和英特尔 Edison 之间进行简单的串行通信。 但我们还希望看到收发的内容,因此我们使用 Arduino IDE 的内置 Serial Monitor。
下列链接将为您显示完整版 sketch:
https://github.com/adrianstevens/Edison_to_Android_BLE/tree/master/Sketches/SimpleSerial
打开英特尔 Arduino IDE,创建新的 sketch。 保存并将其命名为 “SimpleSerial”。 与其他 Arduino 兼容开发板不同,英特尔 Edison 提供两个串行端口。 在 Edison 通过 Grove BLE 收发数据的同时,这有助于我们实现 PC 与 Edison 的通信。 通过连接 PC 的 microUSB 可访问主串行 UART。我们使用连接至 BLE 模块的 Grove 屏蔽器上的 UART 连接器。
在英特尔 Edison 上部署后,我们的 sketch 可自动运行。 它首先运行 setup()
函数,然后无限地连续调用 loop()
函数。 这有助于我们读取和响应串行连接的输入。
初始化串行连接
Grove BLE 的默认通信速度为 9600 波特,因此,我们从该默认值开始。 我们需要配置两个串行端口,以使用该速度。 我们还需向 Grove BLE 发送多个 AT 命令,以将其重置为最新状态。 这些均可显示在 sketch 的 setup()
函数中。
请注意,我们要首先配置 “Serial”,即 microUSB 端口 UART,然后是 “Serial1”,即连接至 Grove BLE 的 UART。
循环
我们在该 sketch 的所有操作均为读取一个串行端口的数据,然后将该数据发送至另一端口。 为此,我们将调用串行端口的 read()
函数(为我们提供单一字符),然后调用另一串行端口的 print()
。
Edison 循环的速度非常快,因此我们可轻松达到 9600 波特。
部署 Sketch
现在请点击 Arduino IDE 的确认按钮(选框),设置好所有 typo。 确认后,请确保英特尔 Edison 已连接至 PC,并上传 sketch(右箭头)。 传输完成后,sketch 启动循环,然后我们可连接 Android 应用。 现在请打开 Arduino IDE 的 Serial Monitor(右上角的放大镜图标),然后可以开始收发数据了。
Sketch 基于英特尔 Edison 运行后,运行 Android BLEConnect 应用。 您应该可以看到 serial monitor 中显示消息 “Hello Grove BLE”。
如果无法运行,可能是 Android 应用的问题。 检查状态显示,它会告知故障点。
GitHub repo 中有一个 sketch,前者也可将消息显示于 Grove LCD。 请确保您 Grove 屏蔽器设置为 5V,并将 LCD 显示屏连接至任一 I2C 连接。
图 9.运行于 Android* 手机的 BLEConnect
图 10. Adruino IDE Serial Monitor 接收 BLEConnect 消息
展望未来
创建相对复杂的项目意味着将须将架构融入 Android 代码和 sketch。 我建议将大部分 Android BLE 代码移入服务,以从 UI 中提取,并简化多个活动和项目的使用。 创建高级 sketche 时,您将希望开始使用 Arduino Time Library,以便模拟运行多个循环,并同时接收数据 (http://playground.arduino.cc/Code/Time)。 我将有关示例添加至 GitHub 存储库 (https://github.com/adrianstevens/Edison_to_Android_BLE),并在下一篇文章中讨论这些概念。
关于作者
Adrian Stevens 拥有 14 年的移动应用开发经验,尤其擅长于 C# 和 C++ 交叉平台开发。 Adrian 精通用户界面架构、音频/信号处理、传感器和数学等领域。 Adrian 长期供职于加拿大温哥华,他对技术研究抱有极大的热情,并极具创业精神。 他同时还在 Meetup 上进行 C# 交叉平台开发。
Adrian 从 2001 开始为 Palm Pilot 和 Pocket PC 等平台开发移动应用。 后来成功创立了精品移动开发工作室。 目前,Adrian 担任移动和交叉平台应用方面的讲师,教授架构和开发策略。