OpenHarmony鸿蒙硬件-Kaihong_Hi3861_温湿度感应板-当温度超过阈值时,让风扇自动转动(优化)

介绍

优化 OpenHarmony鸿蒙硬件-Kaihong_Hi3861温湿度感应板-当温度超过阈值时,让风扇自动转动 的缺点

优化思路

  1. 双阈值迟滞核心

    • 开启阈值:TEMP_ON 25.0f(超这个立刻开风扇)
    • 关闭阈值:TEMP_OFF 23.0f(只有风扇已开启,且降温低于这个才关)
  2. 新增状态标志变量
    定义全局/静态变量记录:当前风扇是 开启 / 关闭 状态

  3. 判断逻辑重写

    • 风扇当前关闭:只判断 温度 > 开启阈值 → 才打开
    • 风扇当前开启:只判断 温度 < 关闭阈值 → 才关闭
    • 中间区间:保持原有状态不变,不切换
  4. 额外辅助优化(可选保留)
    传感器多次均值滤波、延时防抖,进一步弱化小幅温度跳动干扰

代码调整

  1. 宏区新增关闭阈值宏;
  2. 主循环内定义静态状态标记;
  3. 替换原来单一if判断,改用状态机+双阈值逻辑;
  4. 保留原有所有硬件、读取、驱动代码不动,只改判断业务层。

代码

// 标准输入输出头文件:用于 printf 打印
#include <stdio.h>
// 延时头文件:用于 usleep、sleep 延时函数
#include <unistd.h>
// 标准数据类型头文件:定义 uint8_t 等类型
#include <stdint.h>

// 老版本 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°时,风扇才停止

打印

可以查看温湿度


原文出处:/show_1GW32HhN3EC9.html