香橙派5 PWM风扇脚本:10-100%占空比一键调速与温度联动

香橙派5智能温控风扇开发实战:从PWM基础到闭环控制

香橙派5作为一款高性能单板计算机,在持续高负载运行时会产生大量热量。传统散热方案要么噪音过大,要么效率低下。本文将带你深入PWM风扇控制技术,实现从10%到100%占空比的精确调速,并最终构建一个完整的温度联动智能控制系统。

1. 硬件准备与PWM基础配置

在开始编写脚本前,我们需要确保硬件连接正确并完成基础PWM配置。香橙派5的26针GPIO接口中,有多个引脚支持PWM输出功能,但默认处于关闭状态。

首先确认你的风扇类型:

  • 4线PWM风扇 :直接使用PWM信号线控制转速
  • 2线电压调速风扇 :需要通过MOSFET或三极管进行信号转换

对于最常见的4线PWM风扇,接线方式如下:

香橙派5 GPIO引脚 → 风扇对应接口
PWM输出引脚 → 风扇PWM线(通常为蓝色)
5V → 风扇红色电源线
GND → 风扇黑色地线

关键硬件检查清单

  • 确认风扇工作电压(常见5V/12V)
  • 检查PWM频率兼容性(通常20-25kHz为最佳)
  • 确保接线牢固,避免接触不良

接下来启用PWM功能。编辑/boot/orangepiEnv.txt文件:

sudo nano /boot/orangepiEnv.txt

在overlays行添加对应的PWM配置,例如使用pwm13-m2:

overlays=pwm13-m2

保存后重启系统使配置生效。

验证PWM通道是否成功启用:

ls /sys/class/pwm/

应该能看到新增的pwmchipX目录(X为数字编号)。

2. PWM手动调速脚本开发

我们先实现基础的手动调速功能,为后续的温控系统打下基础。以下是一个健壮的Bash脚本,支持10-100%的占空比调节:

#!/bin/bash
# pwm_fan_control.sh

PWM_CHIP="pwmchip2"  # 根据实际pwmchip编号修改
PWM_NUM="0"          # PWM通道号
PWM_PATH="/sys/class/pwm/${PWM_CHIP}/${PWM_NUM}"

# 初始化PWM通道
init_pwm() {
    if [ ! -d "$PWM_PATH" ]; then
        echo "Exporting PWM channel..."
        echo $PWM_NUM > /sys/class/pwm/${PWM_CHIP}/export
        sleep 1  # 等待设备初始化
        echo "normal" > ${PWM_PATH}/polarity
    fi
    
    # 设置PWM频率为25kHz(周期40000ns)
    echo 40000 > ${PWM_PATH}/period
}

# 设置风扇转速(百分比)
set_fan_speed() {
    local speed=$1
    
    # 输入验证
    if [[ ! $speed =~ ^[0-9]+$ ]] || [ $speed -lt 10 ] || [ $speed -gt 100 ]; then
        echo "Error: Speed must be between 10 and 100"
        return 1
    fi
    
    # 计算实际占空比时间(单位:ns)
    local duty_cycle=$((40000 * speed / 100))
    
    echo $duty_cycle > ${PWM_PATH}/duty_cycle
    echo 1 > ${PWM_PATH}/enable
    
    echo "Fan speed set to ${speed}% (Duty cycle: ${duty_cycle}ns)"
}

# 主程序
init_pwm

if [ $# -eq 1 ]; then
    set_fan_speed $1
else
    echo "Usage: $0 <speed_percentage (10-100)>"
fi

脚本功能说明

  1. 自动检测并初始化PWM通道
  2. 设置25kHz的PWM频率(人耳不可闻范围)
  3. 提供输入参数验证,防止错误设置
  4. 支持10-100%的精确调速(低于10%可能导致风扇停转)

使用示例:

# 设置风扇转速为50%
sudo ./pwm_fan_control.sh 50

# 设置风扇全速运转
sudo ./pwm_fan_control.sh 100

3. 温度监测与动态调速

实现温度联动的关键在于实时获取CPU温度并据此调整PWM占空比。香橙派5的温度传感器数据通常位于:

/sys/class/thermal/thermal_zone0/temp

以下是温度读取函数(返回摄氏度):

get_cpu_temp() {
    local temp_raw=$(cat /sys/class/thermal/thermal_zone0/temp)
    echo $((temp_raw / 1000))
}

我们需要定义温度-转速映射关系。推荐使用分段线性控制策略:

温度范围(℃) 风扇转速(%) 说明
<50 10 静音模式
50-60 30 轻度散热
60-70 50 平衡模式
70-80 70 加强散热
>80 100 全速降温

将手动调速脚本升级为自动温控版本:

#!/bin/bash
# auto_fan_control.sh

# 配置参数
PWM_CHIP="pwmchip2"
PWM_NUM="0"
INTERVAL=5  # 温度检测间隔(秒)
MIN_SPEED=10 # 最低转速(%)

# 初始化PWM
init_pwm() {
    # ...同前文init_pwm函数...
}

# 获取CPU温度
get_cpu_temp() {
    # ...同前文get_cpu_temp函数...
}

# 根据温度计算目标转速
calculate_speed() {
    local temp=$1
    local speed
    
    if [ $temp -lt 50 ]; then
        speed=$MIN_SPEED
    elif [ $temp -lt 60 ]; then
        speed=30
    elif [ $temp -lt 70 ]; then
        speed=50
    elif [ $temp -lt 80 ]; then
        speed=70
    else
        speed=100
    fi
    
    echo $speed
}

# 主控制循环
main_loop() {
    while true; do
        local temp=$(get_cpu_temp)
        local target_speed=$(calculate_speed $temp)
        
        set_fan_speed $target_speed
        
        echo "$(date '+%Y-%m-%d %H:%M:%S') - CPU: ${temp}℃, Fan: ${target_speed}%"
        sleep $INTERVAL
    done
}

# 启动程序
init_pwm
main_loop

优化建议

  1. 添加温度变化率检测,提前响应温度快速上升
  2. 实现转速变化平滑过渡,避免频繁调速
  3. 添加异常温度报警功能

4. 系统服务化与高级配置

为了让温控脚本在系统启动时自动运行,我们需要将其设置为systemd服务。

创建服务配置文件:

sudo nano /etc/systemd/system/fan-control.service

添加以下内容:

[Unit]
Description=Orange Pi 5 PWM Fan Control Service
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/local/bin/auto_fan_control.sh
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

部署步骤:

# 将脚本复制到系统目录
sudo cp auto_fan_control.sh /usr/local/bin/
sudo chmod +x /usr/local/bin/auto_fan_control.sh

# 启用并启动服务
sudo systemctl daemon-reload
sudo systemctl enable fan-control.service
sudo systemctl start fan-control.service

# 检查服务状态
sudo systemctl status fan-control.service

高级配置选项

  1. 动态调参 :通过配置文件实现控制策略热更新
# /etc/fan-control.conf
INTERVAL=3
MIN_SPEED=20
TEMP_THRESHOLDS="50:30 60:50 70:70 80:100"
  1. 日志记录 :添加日志轮转配置
sudo nano /etc/logrotate.d/fan-control

添加内容:

/var/log/fan-control.log {
    weekly
    missingok
    rotate 4
    compress
    delaycompress
    notifempty
    create 644 root root
}
  1. Web监控界面 (可选): 使用Python Flask创建简单的状态监控页面:
from flask import Flask
import subprocess

app = Flask(__name__)

@app.route('/status')
def status():
    temp = subprocess.getoutput("cat /sys/class/thermal/thermal_zone0/temp")[:-3]
    speed = subprocess.getoutput("cat /sys/class/pwm/pwmchip2/pwm0/duty_cycle")
    return f"CPU Temp: {temp}℃, Fan Speed: {int(int(speed)/400)}%"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

5. 故障排查与性能优化

在实际部署中可能会遇到各种问题,以下是常见问题及解决方案:

问题1:PWM通道无法导出

  • 检查/boot/orangepiEnv.txt配置是否正确
  • 确认没有其他进程占用PWM通道
  • 尝试不同的PWM引脚组合

问题2:风扇转速不稳定

  • 检查电源供应是否充足
  • 尝试调整PWM频率(通常20-25kHz最佳)
  • 添加滤波电容(如100nF)到PWM信号线

问题3:温度读取异常

  • 验证thermal_zone路径:
ls /sys/class/thermal/
  • 尝试其他thermal_zone编号

性能优化技巧

  1. 响应速度优化
# 减少温度检测间隔(但会增加系统负载)
INTERVAL=2
  1. 动态频率调整 : 根据负载情况自动调整检测频率:
get_cpu_load() {
    local load=$(awk '{print $1}' /proc/loadavg)
    echo ${load%.*}
}

# 在主循环中
local load=$(get_cpu_load)
local dynamic_interval=$((INTERVAL + load/10))
sleep $dynamic_interval
  1. 温度预测算法 : 实现简单的移动平均滤波:
# 初始化温度历史数组
declare -a temp_history=()

# 在计算目标转速前
temp_history+=($temp)
if [ ${#temp_history[@]} -gt 5 ]; then
    temp_history=("${temp_history[@]:1}") # 移除最旧的值
fi

# 计算平均温度
local sum=0
for t in "${temp_history[@]}"; do
    sum=$((sum + t))
done
local avg_temp=$((sum / ${#temp_history[@]}))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值