OpenHarmony鸿蒙硬件-Kaihong_Hi3861_温湿度感应板-当温度超过阈值时,让风扇自动转动(优化) 作者:马育民 • 2026-03-29 22:09 • 阅读:10001 # 介绍 优化 [OpenHarmony鸿蒙硬件-Kaihong_Hi3861温湿度感应板-当温度超过阈值时,让风扇自动转动](https://www.malaoshi.top/show_1GW32Hv8m7Gu.html "OpenHarmony鸿蒙硬件-Kaihong_Hi3861_温湿度感应板-当温度超过阈值时,让风扇自动转动") 的缺点 ### 优化思路 1. **双阈值迟滞核心** - 开启阈值:`TEMP_ON 25.0f`(超这个立刻开风扇) - 关闭阈值:`TEMP_OFF 23.0f`(只有风扇已开启,且降温低于这个才关) 2. **新增状态标志变量** 定义全局/静态变量记录:当前风扇是 **开启 / 关闭** 状态 3. **判断逻辑重写** - 风扇当前关闭:只判断 `温度 > 开启阈值` → 才打开 - 风扇当前开启:只判断 `温度 < 关闭阈值` → 才关闭 - 中间区间:保持原有状态不变,不切换 4. 额外辅助优化(可选保留) 传感器多次均值滤波、延时防抖,进一步弱化小幅温度跳动干扰 # 代码调整 1. 宏区新增关闭阈值宏; 2. 主循环内定义静态状态标记; 3. 替换原来单一if判断,改用**状态机+双阈值**逻辑; 4. 保留原有所有硬件、读取、驱动代码不动,只改判断业务层。 ### 代码 ``` // 标准输入输出头文件:用于 printf 打印 #include // 延时头文件:用于 usleep、sleep 延时函数 #include // 标准数据类型头文件:定义 uint8_t 等类型 #include // 老版本 Hi3861 GPIO 驱动头文件 #include "wifiiot_gpio.h" // 老版本 Hi3861 GPIO 复用功能配置头文件 #include "wifiiot_gpio_ex.h" // 老版本 Hi3861 I2C 驱动头文件 #include "wifiiot_i2c.h" // OpenHarmony 系统初始化头文件 #include "ohos_init.h" // ==================== 宏定义配置区 ==================== // 风扇开启阈值(温度高于此值 → 打开风扇) #define TEMP_ON 25.0f // 风扇关闭阈值(温度低于此值 → 关闭风扇) #define TEMP_OFF 24.0f // SHT40 传感器配置 #define SHT40_ADDR 0x88 #define SHT40_MEASURE_HIGH 0xFD // ==================== I2C 初始化函数 ==================== static void I2C_Init(void) { // GPIO13 复用为 I2C0_SDA 数据引脚 IoSetFunc(WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA); // GPIO14 复用为 I2C0_SCL 时钟引脚 IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL); I2cInit(WIFI_IOT_I2C_IDX_0, 400 * 1000); } // ==================== 风扇 GPIO 初始化函数 ==================== static void Fan_Init(void) { GpioInit(); // 配置 GPIO8:风扇使能 IoSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_GPIO); GpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_GPIO_DIR_OUT); // 配置 GPIO12:风扇电源 / 继电器 IoSetFunc(WIFI_IOT_IO_NAME_GPIO_12, WIFI_IOT_IO_FUNC_GPIO_12_GPIO); GpioSetDir(WIFI_IOT_IO_NAME_GPIO_12, WIFI_IOT_GPIO_DIR_OUT); } // ==================== 风扇开启 ==================== static void Fan_On(void) { GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 1); GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_12, 1); } // ==================== 风扇关闭 ==================== static void Fan_Off(void) { GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 0); GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_12, 1); } // ==================== SHT40 读取温湿度 ==================== static int SHT40_Read(float *temp, float *humi) { uint8_t cmd = SHT40_MEASURE_HIGH; uint8_t data[6] = {0}; WifiIotI2cData i2cData; // 发送测量命令 i2cData.sendBuf = &cmd; i2cData.sendLen = 1; i2cData.receiveBuf = NULL; i2cData.receiveLen = 0; I2cWrite(WIFI_IOT_I2C_IDX_0, SHT40_ADDR, &i2cData); usleep(20000); // 读取数据 i2cData.sendBuf = NULL; i2cData.sendLen = 0; i2cData.receiveBuf = data; i2cData.receiveLen = 6; I2cRead(WIFI_IOT_I2C_IDX_0, SHT40_ADDR, &i2cData); // 计算温度、湿度 *temp = -45.0f + 175.0f * ((data[0] << 8) | data[1]) / 65535.0f; *humi = -6.0f + 125.0f * ((data[3] << 8) | data[4]) / 65535.0f; if (*humi < 0) *humi = 0; if (*humi > 100) *humi = 100; return 0; } // ==================== 主任务:自动温控(带迟滞防抖) ==================== void AutoFanTask(void) { float temp, humi; // 静态变量:记录风扇当前状态(0=关闭,1=开启) // 静态变量:只初始化一次,函数退出不丢失值 static uint8_t fan_running = 0; I2C_Init(); Fan_Init(); printf("=== Auto Fan Control (Hysteresis) ===\r\n"); printf("Fan ON : > %.1f C\r\n", TEMP_ON); printf("Fan OFF : < %.1f C\r\n\r\n", TEMP_OFF); while (1) { SHT40_Read(&temp, &humi); printf("Temp: %.1f C | Humi: %.1f %%RH\r\n", temp, humi); // ============================================== // 核心:迟滞控制逻辑(彻底解决震荡) // ============================================== if (fan_running == 0) { // 当前风扇关闭 → 只判断是否需要开启 if (temp > TEMP_ON) { Fan_On(); fan_running = 1; printf("Status: Fan ON\r\n\r\n"); } else { printf("Status: Fan OFF\r\n\r\n"); } } else { // 当前风扇开启 → 只判断是否需要关闭 if (temp < TEMP_OFF) { Fan_Off(); fan_running = 0; printf("Status: Fan OFF\r\n\r\n"); } else { printf("Status: Fan ON\r\n\r\n"); } } sleep(1); } } // 系统启动入口 SYS_RUN(AutoFanTask); ``` ### BUILD.gn ``` # static_library中指定业务模块的编译结果.为静态库文件libmyapp.a,开发者根据实际情况完成填写。 #sources中指定静态库.a所依赖的.c文件及其路径,若路径中包含"//"则表示绝对路径(此处为代码根路径),若不包含"//"则表示相对路径。 #include_dirs中指定source所需要依赖的.h文件路径。 static_library("app") { sources = [ "main.c" ] include_dirs = [ "//utils/native/lite/include", "//base/iot_hardware/interfaces/kits/wifiiot_lite", "//kernel/liteos_m/components/cmsis/2.0", ] } ``` # 运行 - 当温度高于 `25°` 时,风扇开始转动 - 当温度低于 `24°`时,风扇才停止 ### 打印 可以查看温湿度 [](https://www.malaoshi.top/upload/0/0/1GW32HodfMbb.png) 原文出处:http://www.malaoshi.top/show_1GW32HhN3EC9.html