返回首页

Multi-Sensor Project - Phase 2 学习笔记

Phase 2 概述

在 Phase 1 的基础上增加 PWM 风扇控制 功能,实现基于温度的自动风扇调速。


1. PWM 风扇控制模块

1.1 模块结构

src/control/
├── pwm_fan.h    # 公共接口
└── pwm_fan.c    # 实现

1.2 核心功能


2. 阈值控制算法

2.1 算法逻辑

temp <= 25°C      → 风扇关闭 (0%)
25°C < temp < 35°C → 线性调速 (30%-100%)
temp >= 35°C      → 全速运行 (100%)

2.2 滞后控制

/* Apply hysteresis */
if (was_running) {
    /* Fan is running, use lower threshold to keep running */
    effective_low = cfg.temp_low - cfg.hysteresis;
} else {
    /* Fan is off, use normal threshold */
    effective_low = cfg.temp_low;
}

为什么需要滞后?

2.3 线性插值计算

/* Between thresholds - linear interpolation */
int32_t range = cfg.temp_high - cfg.temp_low;
int32_t offset = temp_celsius - cfg.temp_low;
int32_t speed_range = cfg.max_speed - cfg.min_speed;

new_speed = cfg.min_speed + (uint8_t)((offset * speed_range) / range);

3. PWM 配置

3.1 25kHz PWM 频率

uint32_t period = PWM_USEC(40);  /* 25kHz */
pulse = (period * speed_percent) / 100;

pwm_set_dt(&pwm_fan, period, pulse);

为什么选择 25kHz?

3.2 设备树配置

&pwm0 {
    status = "okay";
    pinctrl-0 = <&pwm0_default>;
    pinctrl-1 = <&pwm0_sleep>;
    pinctrl-names = "default", "sleep";
};

&pinctrl {
    pwm0_default: pwm0_default {
        group1 {
            psels = <NRF_PSEL(PWM_OUT0, 1, 4)>;  /* P1.04 */
        };
    };
};

4. 与 Phase 1 的数据流对接

4.1 主循环流程

[ADC 采集] ──→ [I2C 采集] ──→ [PWM 调速] ──→ [UART 输出]
                    │              │
                    │              └── 根据温度更新风扇速度
                    └──────────────────────┘

4.2 代码集成

/* Main loop */
while (1) {
    /* Read sensors */
    adc_sensor_read(&adc_data);
    i2c_sensor_read(&i2c_data);
    
    /* Update fan speed based on temperature */
    fan_speed = pwm_fan_update(i2c_data.temp_celsius);
    
    /* Prepare log data with fan status */
    log_data.temp_celsius = i2c_data.temp_celsius;
    ...
    
    /* Output to UART */
    uart_log_sensor_data(&log_data);
    
    k_sleep(K_MSEC(MAIN_LOOP_INTERVAL_MS));
}

5. 配置参数

5.1 默认配置

static struct fan_config cfg = {
    .temp_low = 2500,       /* 25°C - fan off below this */
    .temp_high = 3500,      /* 35°C - full speed above this */
    .min_speed = 30,        /* 30% minimum when running */
    .max_speed = 100,       /* 100% maximum */
    .hysteresis = 100,      /* 1°C hysteresis */
};

5.2 运行时配置

struct fan_config custom_cfg = {
    .temp_low = 2800,   /* 28°C */
    .temp_high = 4000,  /* 40°C */
    .min_speed = 20,
    .max_speed = 100,
    .hysteresis = 200,
};
pwm_fan_configure(&custom_cfg);

6. 关键实现细节

6.1 PWM 占空比计算

/* Calculate pulse width for 25kHz PWM (40us period)
 * Most PC fans expect 25kHz PWM frequency
 * Period = 40us, pulse = speed% * 40us
 */
uint32_t period = PWM_USEC(40);  /* 25kHz */
pulse = (period * speed_percent) / 100;

6.2 状态保存

static bool was_running = false;  /* Save last state for hysteresis */

6.3 速度限制

/* Clamp speed to valid range */
if (speed_percent > 100) {
    speed_percent = 100;
}

7. 测试验证

7.1 模拟温度变化

# 连接 SHT30,吹气加热
# 观察风扇转速变化

7.2 预期输出

[INF] Fan: speed=30%, temp=26.50°C
[INF] Fan: speed=65%, temp=30.00°C
[INF] Fan: speed=100%, temp=36.00°C

8. Phase 1 vs Phase 2 对比

特性Phase 1Phase 2
外设ADC, I2C, UARTADC, I2C, UART, PWM
模块数34
控制功能温度→风扇控制
复杂度

9. 学习心得

  1. 阈值算法:简单有效,适合快速原型开发
  2. 滞后控制:防止振荡,提高系统稳定性
  3. PWM 频率:25kHz 是 4-pin PC 风扇标准
  4. 模块化设计:新增模块不影响现有代码

10. 下一步计划

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

小白 🤖 2026-03-14