这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【Zephyr|瑞萨RA6E2】6、基于蓝牙的远程二氧化碳在线监测系统

共1条 1/1 1 跳转至

【Zephyr|瑞萨RA6E2】6、基于蓝牙的远程二氧化碳在线监测系统

高工
2025-12-28 21:49:47     打赏

【目标】

体验环境监测功能,实现室内二氧化碳监测远程监测

【开发环境】

1、wsl2

2、west

【硬件】

1、FPB-RA6E2

2、STCC4二氧化碳传感器

3、BT24-IIC低功耗蓝牙模块

【基础工程】

在原来我已有的stcc4采集程序基础之上添加蓝牙模块。

【Zephyr|瑞萨RA6E2】5二氧化碳监测系统-电子产品世界论坛

【实现步骤】

1、将蓝牙模块接入与OLED、STCC4的SDA与SCL总线。

2、在dts中添加节点,指定IIC地址为0x25

        dx_bt25: bluetooth@25 {
            compatible = "dx,bt25-i2c";
            reg = <0x25>;
            status = "okay";
        };

3、在man.c中添加代码,定义节点

#define BT25_NODE    DT_NODELABEL(dx_bt25)

4、由于蓝牙的模块每次只能发送32Byte,因此定一次最长发送数据:

#define BT25_MAX_LENGTH 32  // FIFO 最大长度
#define BT25_I2C_ADDR   DT_REG_ADDR(DT_NODELABEL(dx_bt25))

5、定义蓝牙发送命令函数:

int bt25_send_at_command(const char *cmd)
{
    if (!cmd) return -EINVAL;

    size_t total_len = strlen(cmd);
    if (total_len == 0) {
        return -EINVAL;
    }

    // 分段发送:每段最多 32 字节
    uint8_t buffer[BT25_MAX_LENGTH];
    int offset = 0;

    while (offset < total_len) {
        size_t chunk_len = total_len - offset;
        if (chunk_len > BT25_MAX_LENGTH) {
            chunk_len = BT25_MAX_LENGTH;
        }

        memcpy(buffer, &cmd[offset], chunk_len);

        int ret = i2c_write(i2c_dev, buffer, chunk_len, BT25_I2C_ADDR);
        if (ret != 0) {
            // LOG_ERR("I2C write failed at offset %d: %d", offset, ret);
            return ret;
        }

        offset += chunk_len;
        k_sleep(K_MSEC(1)); // 短延时确保模块处理完
    }

    return 0;
}

6、定义透传发送数据

int bt25_send_sensor_data(int co2_ppm, int16_t temp_x100, uint16_t rh_x100)
{
    uint8_t frame[16];
    const uint8_t data_len = 10; // 4 (CO2) + 2 (Temp) + 2 (RH) + 2 (预留?) → 实际 4+2+2=8? 等等!

    const uint8_t actual_data_len = 8;

    frame[0] = 0x5A;                     // Header
    frame[1] = actual_data_len;          // Data length = 8

    // 小端写入
    sys_put_le32((uint32_t)co2_ppm, &frame[2]);      // int → uint32_t 安全转换
    sys_put_le16((uint16_t)temp_x100, &frame[6]);    // int16_t → uint16_t(位模式不变)
    sys_put_le16(rh_x100,             &frame[8]);    // 湿度

    frame[10] = 0xA5;                    // Footer

    return i2c_write(i2c_dev, frame, 11, BT25_I2C_ADDR); // 1+1+8+1 = 11 字节
}

7、在程序运行时,发送开启透传AT指令:

bt25_send_at_command("AT+TRANSPORT=1\r\n");

8、在采集好数据后,发送数据指令:

bt25_send_sensor_data(co2_ppm, (int16_t)(temperature * 100), (int16_t)(humidity * 100));

【上位机程序】

我的win11电脑上面是有蓝牙模块的,使用python编写一个简单的可视化程序,代码如下:

# bt24_display.py
import asyncio
import struct
import threading
import tkinter as tk
from datetime import datetime
from bleak import BleakScanner, BleakClient

# ===== 配置 =====
TARGET_NAME = "BT24-IIC"
CHAR_UUID = "0000FFE1-0000-1000-8000-00805F9B34FB"

# 全局变量(用于 GUI 更新)
latest_data = {
    'co2_ppm': '--',
    'temperature_c': '--',
    'humidity_pct': '--',
    'last_update': 'Never'
}

# 解析函数(与你的协议一致)
def parse_sensor_frame(data: bytes):
    if len(data) != 11:
        return None
    if data[0] != 0x5A or data[-1] != 0xA5:
        return None
    if data[1] != 8:
        return None
    try:
        co2, temp_raw, rh_raw = struct.unpack('<i h H', data[2:10])
        return {
            'co2_ppm': co2,
            'temperature_c': temp_raw / 100.0,
            'humidity_pct': rh_raw / 100.0,
        }
    except Exception as e:
        print(f"Parse error: {e}")
        return None

# BLE 通知回调
def notification_handler(sender, data: bytearray):
    parsed = parse_sensor_frame(bytes(data))
    if parsed:
        latest_data['co2_ppm'] = parsed['co2_ppm']
        latest_data['temperature_c'] = f"{parsed['temperature_c']:.2f}"
        latest_data['humidity_pct'] = f"{parsed['humidity_pct']:.2f}"
        latest_data['last_update'] = datetime.now().strftime("%H:%M:%S")

# 异步 BLE 任务
async def ble_task():
    while True:
        try:
            print("	



关键词: Zephyr     RA6E2     蓝牙     二氧化碳     在线         

共1条 1/1 1 跳转至

回复

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