利用 Simplicity Studio 从零建立一个 Environment Server
环境
- 板卡:ThunderBoard ERF32BG22
- IDE:SimplicityStudio v5
- SDK:3.1 版本
实验现象
ERF32BG22 作为一个 EnvironmentServer,手机端通过 nrf Connect 去连接板卡,可以读取板卡上 Si70xx 这个温湿度传感器测量的环境温度和湿度。
创建流程
添加 GATT 服务
打开工程的配置文件 .slcp 。然后选择 SOFTWARE COMPONENTS -> Bluetooth -> GATT -> Environment Sensing - Relative Humidity and Temperature GATT Service ,点击 Install 安装该服务。
添加传感器驱动
由于我们需要从板卡上的 Si70xx 读取温湿度信息,因此需要相应的驱动。选择 Bluetooth -> Sensor -> Relative Humidity and Temperature sensor ,点击 Install 安装该驱动。然后点击其右下角的 View Dependencies 查看依赖。
由于 Si70xx 需要由 I2C 来驱动,因此自动添加了 I2CSPM 这个驱动组件,但是其实例名字 inst0 不能与现有的软件包兼容,需要手动更改一下。
点击 I2CSPM 右侧的 View 。
此时跳转到了 I2CSPM 的配置界面,点击下方的 Add New Instances 。
在弹出的对话框里保证 INSTANCE NAME 为 sensor ,一般默认即可,点击 Done 。然后点击右上角 Configure (可能需要等一会才能点的动)。
在 I2CSPM 配置界面看见 SL_I2CSPM_SENSOR 的名字即配置正常。
添加日志系统
选择 Bluetooth -> Utility -> Log ,点击 Install 安装日志系统。
此处如果之前没有安装 IO Stream: USART Core ,会显示下图的错误,点击 IO Stream: USART Core 。
点击 Install 完成 IO Stream: USART Core 的安装。
添加应用代码
到了此处工程配置已经完成了,在 gecko_sdk_3.1.0 -> app -> bluetooth -> common 可以看见我们添加的 app_log, gatt_service_rht 和 sensor_rht 这三个组件。
- app_log:日志系统
- gatt_service_rht:Environment GATT Service 的实现
- sensor_rht:Si70xx 的驱动。
首先查看 sl_gatt_service_rth.h 文件里的接口:
/**************************************************************************//**
* Bluetooth stack event handler.
* @param[in] evt Event coming from the Bluetooth stack.
*****************************************************************************/
void sl_gatt_service_rht_on_event(sl_bt_msg_t *evt);
/**************************************************************************//**
* Getter for Humidity and Temperature characteristic values.
* @param[out] rh Relative humidity (in 0.001 percent).
* @param[out] t Temperature (in 0.001 Celsius).
* @return Status of the operation.
* @note To be implemented in user code.
*****************************************************************************/
sl_status_t sl_gatt_service_rht_get(uint32_t *rh, int32_t *t);
sl_gatt_service_rht_on_event()
函数是 BLE 协议栈的事件处理函数,由 BLE 协议栈调用,我们不用理会。
而 sl_gatt_service_rht_get()
则是获取温度和湿度这两个 GATT characteristic value 的地方,数值保存在 rh 和 t 指向的空间。
在 sl_gatt_service_rth.c 文件内部,定义了一个 weak 修饰的 sl_gatt_service_rht_get()
的函数,该函数什么都没做,因此该函数需要由用户根据实际的温湿度传感器来读取数据。
SL_WEAK sl_status_t sl_gatt_service_rht_get(uint32_t *rh, int32_t *t)
{
(void)rh;
(void)t;
// keep default values
return SL_STATUS_FAIL;
}
既然要读取温湿度传感器的数据,那就肯定要用到其驱动文件了,接口在 sl_sensor_rht_.h 里:
/**************************************************************************//**
* Initialize Relative Humidity and Temperature sensor.
*****************************************************************************/
void sl_sensor_rht_init(void);
/**************************************************************************//**
* Deinitialize Relative Humidity and Temperature sensor.
*****************************************************************************/
void sl_sensor_rht_deinit(void);
/**************************************************************************//**
* Getter for Relative Humidity and Temperature sensor measurement data.
* @param[out] rh Relative humidity (in 0.001 percent).
* @param[out] t Temperature (in 0.001 Celsius).
* @return Status of the operation.
*****************************************************************************/
sl_status_t sl_sensor_rht_get(uint32_t *rh, int32_t *t);
一共三个接口,有初始化函数,取消初始化函数,读取温湿度数据函数。
现在我们来在 app.c 里实现相应的代码。
在 app.c 里的 sl_bt_on_event()
函数里,BLE 成功连接事件处添加传感器初始化代码,BLE 断开连接处添加传感器取消初始化代码。
void sl_bt_on_event(sl_bt_msg_t *evt)
{
......
switch (SL_BT_MSG_ID(evt->header)) {
// -------------------------------
// This event indicates the device has started and the radio is ready.
// Do not call any stack command before receiving this boot event!
case sl_bt_evt_system_boot_id:
......
break;
// -------------------------------
// This event indicates that a new connection was opened.
case sl_bt_evt_connection_opened_id:
sl_sensor_rht_init();
break;
// -------------------------------
// This event indicates that a connection was closed.
case sl_bt_evt_connection_closed_id:
......
sl_sensor_rht_deinit();
break;
// -------------------------------
// Default event handler.
default:
break;
}
}
然后在 app.c 里实现 sl_status_t sl_gatt_service_rht_get(uint32_t *rh, int32_t *t)
函数,从传感器里读取出温湿度数据。
sl_status_t sl_gatt_service_rht_get(uint32_t *rh, int32_t *t)
{
sl_status_t sc;
sc = sl_sensor_rht_get(rh, t);
if (SL_STATUS_OK != sc) {
sl_app_log("[E: %#04x] RHT sensor measurement failed\n", sc);
}
return sc;
}
记得包含相应头文件。
#include "sl_gatt_service_rht.h"
#include "sl_sensor_rht.h"
#include "sl_app_log.h"
编译,下载代码。
演示效果
手机端打开 nrf Connect,可以看见 Empty Example 这个设备在发广播,点击 CONNECT 去连接它。
在 CLIENT 里选择 Environmental Sensing 这个 Service 。
点击右侧向下的箭头即可读取温湿度数据。
结果如下图所示:
至此,Funpack 第四期活动的任务 Server 端已经完成,
通过蓝牙读取开发板上的温度传感器数值,超过一定门槛后,再通过蓝牙控制开发板上的LED灯点亮以作报警
本篇文章 + 利用 Simplicity Studio 从零建立一个 LED Server 实现了添加 LED Service 和 Environment Service ,之后只需实现一个 GATT Client 客户端即可。