这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【e起DIY】低功耗蓝牙温湿度计:最后的效果

共2条 1/1 1 跳转至

【e起DIY】低功耗蓝牙温湿度计:最后的效果

高工
2026-06-11 00:07:35     打赏

        实际上我们这里就算已经完成了基本功能了,变化的数据已经有了,那么我们就加入使用的传感器,实际上就是SHT40,我们在SDK中\zephyr\zephyr\drivers\sensor\sensirion\sht4x就有对应的驱动,我们直接融合到现在的工程就行,然后通过蓝牙透传。

        接下来我们看一下如何实现,首先将传感器连接到开发板:

651fe8c5-8c9f-4572-8ce0-092e3ade8e52.png

        之前我们搭好了"连接后每2s透传一个数字"的蓝牙骨架。但说实话,光推编号没意思——谁要看 MCU在那数数呢?真正的物联网节点得有"感官",能采集真实数据。我们本次的最终要完成的也是蓝牙温湿度计。最后阶段的目标:让板子读SHT40温湿度传感器的数据,然后通过同一个BLE Notify特征把数据推出来。最终效果:手机连上BLE test设备 → 订阅特征 → 收到形如T:25.3,H:60.1的字符串,每2s一帧。

        SHT40是Sensirion推出的一款高精度温湿度传感器,I2C 接口,典型地址 0x44。重复精度±0.2°C / ±1.8%RH,I2C速率最高1MHz。我们的板子(FRDM-MCXW72)默认只开了lpi2c1(上面挂着板载的 FXLS8974 加速度计),lpi2c0 是关的而且引脚和 PWM LED 冲突。所以SHT40外接的话,最稳的方案是直接挂lpi2c1——和加速度计共用总线,地址0x44不冲突。

Zephyr 这边怎么改

        跟阶段一一样,整个改动落三个文件:

peripheral/ ├── boards/ │   └── frdm_mcxw72.overlay   ← 新增:把 SHT40 挂到 lpi2c1 ├── prj.conf                  ← 追加:I2C、Sensor、Float printf └── src/    └── main.c                ← 改造:把"数数"换成"读传感器"

设备树 overlay:告诉板子"我有 SHT40"

        Zephyr跟硬件打交道全靠设备树。我们新建一个boards/frdm_mcxw72.overlay,把SHT40节点塞到 lpi2c1下面:

&lpi2c1 {    status = "okay";    sht40: sht4x@44 {        compatible = "sensirion,sht4x";        reg = <0x44>;        repeatability = <2>;   /* 高精度模式(单次测量约 8.3 ms)*/    }; };

prj.conf:开 I2C、传感器、浮点打印

# 阶段一就有的 CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_LOG=y CONFIG_BT_DEVICE_NAME="BLE test" # 这阶段新增的 CONFIG_I2C=y CONFIG_SENSOR=y CONFIG_PICOLIBC_IO_FLOAT=y

        最后一行是大坑,先记住:Picolibc(Zephyr 默认的精简 libc)默认不开启 %f 浮点打印支持,不显式打开的话snprintf("%.1f", ...) 会输出乱七八糟的东西。

        CONFIG_SHT4X 你可能注意到我没写。这是因为SHT4X驱动的 Kconfig 写了 default y + depends on DT_HAS_SENSIRION_SHT4X_ENABLED,只要设备树里有 sht4x@44 节点,构建系统就自动把这个驱动编进去。

main.c:读传感器 + 蓝牙通知

        代码结构跟阶段一几乎一样,只改"工作回调"里那个原本数数的部分:

#include <zephyr/drivers/sensor.h>   /* 新增 */ static const struct device *const sht =    DEVICE_DT_GET(DT_NODELABEL(sht40));   /* 一行拿到 sensor device */ static void sensor_work_handler(struct k_work *work) {    struct sensor_value temp, hum;    int err;    err = sensor_sample_fetch(sht);   /* 触发一次测量,等结果 */    if (err) {        printk("sensor_sample_fetch failed (err %d)\n", err);        goto reschedule;    }    if (sensor_channel_get(sht, SENSOR_CHAN_AMBIENT_TEMP, &temp) ||        sensor_channel_get(sht, SENSOR_CHAN_HUMIDITY, &hum)) {        goto reschedule;    }    /* 拼成短字符串,最大 12 字节,能塞进默认 ATT MTU 的 20 字节值字段 */    sensor_len = (uint16_t)snprintf((char *)sensor_buf, sizeof(sensor_buf),                                    "T:%.1f,H:%.1f",                                    sensor_value_to_double(&temp),                                    sensor_value_to_double(&hum));    printk("Notify: %s\n", sensor_buf);    if (notify_enabled) {        err = bt_gatt_notify(NULL, &sensor_svc.attrs[2],                             sensor_buf, sensor_len);        if (err) {            printk("bt_gatt_notify failed (err %d)\n", err);        }    } reschedule:    if (streaming) {        k_work_schedule(&sensor_work, K_MSEC(NOTIFY_INTERVAL_MS));    } }

演示效果

        小程序扫描 → 找到 BLE test → CONNECT,找到未知服务(UUID 末段 ...9abcdef0)→ 进去,订阅 Notify 特征(UUID 末段 ...9abcdef1),这个时候就可以看到无线传输的效果了:

ca1bf599-8890-415d-8234-4e4e492a3d44.png

        中途我把手指放在了传感器上,可以看到传感器反应还是挺快的,温度就上升上来了。





关键词: 效果     湿度计     蓝牙    

高工
2026-06-11 05:56:50     打赏
2楼

NXP的自学门槛很高,

甚至要改焊点,



共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]