返回首页

Multi-Sensor Project - Phase 3 学习笔记

Phase 3 概述

在 Phase 2 的基础上增加 BLE NUS(Nordic UART Service) 功能,实现手机无线查看传感器数据。


1. BLE NUS 服务简介

1.1 什么是 NUS?

Nordic UART Service (NUS) 是 Nordic 定义的 BLE 服务:

1.2 优点


2. BLE 服务模块实现

2.1 模块结构

// ble_service.h
struct ble_sensor_data {
    int16_t temp_celsius;
    int16_t hum_percent;
    uint8_t light_percent;
    uint8_t fan_speed;
    uint32_t timestamp;
};

int ble_service_init(void);
int ble_service_send(const struct ble_sensor_data *data);
bool ble_service_is_connected(void);

2.2 初始化流程

int ble_service_init(void)
{
    // 1. 注册连接回调
    bt_conn_cb_register(&conn_callbacks);
    
    // 2. 初始化 NUS 服务
    err = bt_nus_init(&nus_cb);
    
    // 3. 启用 BLE
    err = bt_enable(NULL);
    
    // 4. 开始广播
    k_work_submit(&adv_work);
}

2.3 连接回调

static void connected(struct bt_conn *conn, uint8_t err)
{
    current_conn = bt_conn_ref(conn);
    is_connected = true;
    
    if (on_connected) {
        on_connected();
    }
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
    bt_conn_unref(current_conn);
    is_connected = false;
    
    if (on_disconnected) {
        on_disconnected();
    }
}

3. 广播配置

3.1 广播数据

static const struct bt_data ad[] = {
    BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
    BT_DATA(BT_DATA_NAME_COMPLETE, BLE_DEVICE_NAME, sizeof(BLE_DEVICE_NAME) - 1),
};

static const struct bt_data sd[] = {
    BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_NUS_VAL),
};

3.2 快速广播模式

BT_LE_ADV_CONN_FAST_2  // 30ms-60ms 间隔,持续 30 秒

4. 数据发送

4.1 JSON 格式

int ble_service_send(const struct ble_sensor_data *data)
{
    char json_buf[128];
    
    int len = snprintf(json_buf, sizeof(json_buf),
        "{\"temp\":%d.%02d,\"hum\":%d.%02d,\"light\":%u,\"fan\":%u}",
        data->temp_celsius / 100,
        data->temp_celsius % 100,
        data->hum_percent / 100,
        data->hum_percent % 100,
        data->light_percent,
        data->fan_speed);
    
    return bt_nus_send(NULL, json_buf, len);
}

4.2 输出示例

{"temp":25.50,"hum":45.00,"light":75,"fan":30}

5. 与主程序集成

5.1 主循环流程

[传感器采集] → [风扇控制] → [UART输出] → [BLE发送]
                                   │
                                   └── 仅在连接时发送

5.2 代码集成

/* Send data over BLE if connected */
if (ble_service_is_connected()) {
    ble_data.temp_celsius = i2c_data.temp_celsius;
    ble_data.hum_percent = i2c_data.hum_percent;
    ble_data.light_percent = adc_sensor_get_light_percent();
    ble_data.fan_speed = fan_speed;
    
    err = ble_service_send(&ble_data);
}

5.3 LED 状态指示

static void on_ble_connected(void)
{
    gpio_pin_set_dt(&led2, 1);  /* LED2 亮表示已连接 */
}

static void on_ble_disconnected(void)
{
    gpio_pin_set_dt(&led2, 0);  /* LED2 灭表示断开 */
}

6. 配置要点

6.1 prj.conf

# BLE 配置
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="MultiSensor"
CONFIG_BT_MAX_CONN=1
CONFIG_BT_NUS=y

6.2 设备树

/* BLE 使用内置射频,无需额外引脚配置 */

7. 手机端使用

7.1 nRF Connect APP

  1. 打开 nRF Connect
  2. 扫描 "MultiSensor" 设备
  3. 连接设备
  4. 找到 NUS 服务 (UUID: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E)
  5. 启用通知
  6. 接收 JSON 数据

7.2 自定义 APP

可以使用 Nordic 的 nRF Toolbox 或自己开发 APP。


8. 错误处理

8.1 连接状态检查

if (!ble_service_is_connected()) {
    return -ENOTCONN;  /* 未连接时不发送 */
}

8.2 发送失败处理

err = ble_service_send(&ble_data);
if (err < 0) {
    LOG_WRN("BLE send failed: %d", err);
    /* 继续运行,不影响其他功能 */
}

9. Phase 1/2/3 对比

特性Phase 1Phase 2Phase 3
外设ADC, I2C, UART+ PWM+ BLE
模块数345
控制功能风扇控制无线数据
复杂度

10. 学习心得

  1. BLE NUS:简单易用的无线通信方案
  2. 连接管理:使用回调函数处理连接状态变化
  3. JSON 格式:通用数据格式,易于解析
  4. 模块化:BLE 服务独立封装,不影响现有代码

11. 下一步计划

Phase功能状态
Phase 1ADC + I2C + UART✅ 完成
Phase 2PWM 风扇控制✅ 完成
Phase 3BLE NUS 集成✅ 完成
Phase 4低功耗优化⏳ 待实现

小白 🤖 2026-03-14