『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
查看: 1626|回复: 12

[经验分享] Linux系统下基于CPU核心温度的PWM温控散热风扇

[复制链接]

43

主题

202

帖子

925

积分

高级会员

Rank: 4

积分
925
金钱
723
HASS币
0
发表于 2024-5-16 09:01:40 | 显示全部楼层 |阅读模式
买了个小主机,安装了PVE做all in one,目前虚拟了爱快,以后还打算虚拟HA和其他系统。
这个小主机有12V风扇接口,但没有温控。所以我要加一个温控风扇。
屏幕截图 2024-05-16 01.png
屏幕截图 2024-05-16 0.png


一般的外挂温控风扇都是用外部温度探头,将探头贴在机器里面某个地方,cpu热量从内部传导到外面需要一定的时间,这样会导致CPU的温度不能及时反映到探头上,风扇转速不能及时改变。

解决方案:
在Linux系统里用sensors软件读取CPU温度,再用PHP部署一个WEB服务将温度数据发布出去,ESP模块接收到温度数据后,动态调整CPU转速。

元件:
屏幕截图 2024-05-16 1.png

我是使用esp8285,但我建议你们使用esp32,因为pwm性能更好。
还有就是一个小巧的12v降到3.3v的降压模块,随便买一个就好。
全部成本不到10元。

成品:
屏幕截图 2024-05-16 2.png

电路:
风扇接12V电源,然后风扇的测速线接esp的GPIO13脚,pwm控制线接esp的GPIO04脚。

Linux系统里安装sensors软件:

apt install sensors


Linux系统里安装php软件:

apt install php


将以下代码保存成文件temp.php放到根目录/root:
<?php
// 执行 sensors 命令
exec('sensors', $output, $return_var);

if ($return_var === 0) {
    $temperatures = []; // 存储温度数据的关联数组

    // 遍历输出数组,查找 Package id 0 和 Core 温度值
    foreach ($output as $line) {
        if (preg_match('/(Package id 0|Core \d+):\s+\+(\d+\.\d+)°C/', $line, $matches)) {
            $sensor_name = $matches[1];
            $temperature = (float) $matches[2];
            $temperatures[$sensor_name] = $temperature;
        }
    }

    // 找出最高温度
    $maxTemperature = max($temperatures);

    // 输出JSON格式的温度数据
    echo json_encode([
        'temperatures' => $temperatures,
        'max_temperature' => $maxTemperature
    ]);
} else {
    echo json_encode(['error' => '执行 sensors 命令失败']);
}


创建一个php webserver服务:
创建文件 /etc/systemd/system/temp-server.service:
[Unit]
Description=Temp Server
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/php -S 0.0.0.0:8000 /root/temp.php
Restart=always

[Install]
WantedBy=multi-user.target


启用服务:

systemctl daemon-reload
systemctl start temp-server


在另一台电脑浏览器试试访问:
http://你的linux主机ip:8000

如果这样显示就说明正确了:
屏幕截图 2024-05-16 8.png

ESP代码:

substitutions:
  device_name: "fan_pwm_01"
  friendly_name: "Fan Pwm 01"

esphome:
  name: "${device_name}"
  friendly_name: "${friendly_name}"
  on_boot:
    then:
      - delay: 2s
      - fan.turn_off:
          id: ${device_name}_fan
      - delay: 2s
      - fan.turn_on:
          id: ${device_name}_fan
          speed: "100"
      - delay: 2s
      - fan.turn_on:
          id: ${device_name}_fan
          speed: "1"

esp8266:
  board: esp8285

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "xxxxxxxxxxx"

ota:
  password: "xxxxxxxxxxxxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Fan-Pwm-01 Fallback Hotspot"
    password: ""

captive_portal:

fan:
  - platform: speed
    id: "${device_name}_fan"
    output: pwm_output
    speed_count: 100
    name: "${device_name} 开关"

output:
  - platform: esp8266_pwm
    pin: GPIO04
    frequency: 35000 Hz # 频率如果太低,我的风扇会吱吱响
    id: pwm_output

button:
  - platform: restart
    name: "${device_name} 重启"

sensor:
  - platform: wifi_signal
    name: "WiFi Signal"
    id: "sensor_wifi_signal"
    force_update: True
    update_interval: 5s

  - platform: template
    id: ${device_name}_sensor_fanspeed
    icon: "mdi:fan"
    name: "风扇速度"
    lambda: |-
      return id(${device_name}_fan).speed;
    accuracy_decimals: 0
    unit_of_measurement: "%"
    update_interval: 1s

  - platform: pulse_counter
    id: sensor_pulse_counter
    pin:
      number: GPIO13
      inverted: true
      mode:
        input: true
        pullup: true
    name: ${friendly_name} 风扇转速
    unit_of_measurement: 'RPM'
    filters:
      - multiply: 0.5
      - lambda: |-
          if (x <= 5000) return x;
          else return {};
    count_mode:
      rising_edge: INCREMENT
      falling_edge: DISABLE
    update_interval: 2s


text_sensor:
  - platform: template
    name: "温度"
    id: text_temp
    update_interval: 2s

  # 测试用的
  - platform: template
    name: "期望速度"
    id: text_expected_speed
    internal: True
    update_interval: 2s

http_request:
  id: http_request_data
  timeout: 10s

interval:
  - interval: 1s
    then:
      - http_request.get:
          url: "http://192.168.3.11:8000/"
          verify_ssl: false
          on_response:
            then:
              - lambda: |-
                  if( status_code == 200 ){
                    json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
                      float temp;
                      int speed;

                      temp = root["max_temperature"];

                      if(temp>=50){
                        speed = (temp - 50)/20*100;
                      }else{
                        speed = 1;
                      }

                      id(text_expected_speed).publish_state(to_string(speed) + "%");
                      id(text_temp).publish_state(to_string(temp));

                      auto call = id(${device_name}_fan).make_call();
                      call.set_speed(speed);
                      call.perform();
                    });
                  }else{
                    auto call = id(${device_name}_fan).make_call();
                    call.set_speed(50);
                    call.perform();
                    id(text_expected_speed).publish_state("temperature api error");
                    id(text_temp).publish_state("temperature api error");
                  }
代码参(抄)考(袭)自:https://bbs.hassbian.com/thread-25335-1-3.html

记得修改里面的密码、Linux主机网址等。
设置是当温度小于50度时,风扇以1%固定速度运行,70度时全速运行,50-70之间线性增加速度。如果获取不到温度数据就以50%的速度运行。可自行修改上面的速度调整代码。

实测:
当Linux主机的温度是43度时:
屏幕截图 2024-05-16 3.png

风扇速度是1%:
屏幕截图 2024-05-16 4.png

当Linux主机的温度是57度时:
屏幕截图 2024-05-16 7.png

风扇速度是35%:
屏幕截图 2024-05-16 6.png

----------------------------------------

费了九牛二虎之力做好了温控风扇,然后发现我这台小机子就算CPU持续100%运行,温度也不是很高,不需要散热,白费力气了。

----------------------------------------

真人真事:
我在PDD某家店买的这台小主机,发现BIOS里显示的CPU温度不正确,CPU温度比室温还低,我向商家反映这个问题,商家热心地接受了我的意见,然后发布了新版本的BIOS升级文件————把BIOS里显示CPU温度的功能去掉了!
这台机子没有厂家名称、地址、电话,所以我也不知道是哪家出产的,只知道叫4网口N4120软路由。





评分

参与人数 1金钱 +12 收起 理由
隔壁的王叔叔 + 12 以为是青铜,原来是王者!

查看全部评分

回复

使用道具 举报

12

主题

434

帖子

2340

积分

金牌会员

Rank: 6Rank: 6

积分
2340
金钱
1906
HASS币
0
发表于 2024-5-16 09:16:40 | 显示全部楼层
解决不了问题,就解决发现问题的
回复

使用道具 举报

0

主题

201

帖子

2713

积分

金牌会员

Rank: 6Rank: 6

积分
2713
金钱
2512
HASS币
0
发表于 2024-5-16 10:33:27 | 显示全部楼层
我的直接串联几个二极管降压,一直慢速转,没有噪音。
回复

使用道具 举报

56

主题

929

帖子

4075

积分

论坛元老

Rank: 8Rank: 8

积分
4075
金钱
3146
HASS币
0
发表于 2024-5-16 11:11:16 | 显示全部楼层
PVE里可以安装mqtt,可直接将温度数据发送至mqtt服务器
回复

使用道具 举报

43

主题

202

帖子

925

积分

高级会员

Rank: 4

积分
925
金钱
723
HASS币
0
 楼主| 发表于 2024-5-16 11:43:09 | 显示全部楼层
bainiu 发表于 2024-5-16 11:11
PVE里可以安装mqtt,可直接将温度数据发送至mqtt服务器

这样需要mqtt服务器中转数据,多了一份不稳定性,还是esp直接读取pve上的温度更好。
回复

使用道具 举报

16

主题

178

帖子

930

积分

高级会员

Rank: 4

积分
930
金钱
752
HASS币
0
发表于 2024-5-16 18:19:56 | 显示全部楼层
Linux系统里安装sensors软件

Linux系统是指在PVE下安装?
回复

使用道具 举报

43

主题

202

帖子

925

积分

高级会员

Rank: 4

积分
925
金钱
723
HASS币
0
 楼主| 发表于 2024-5-16 18:30:14 | 显示全部楼层
leung 发表于 2024-5-16 18:19
Linux系统是指在PVE下安装?

包括但不限于PVE,只要是debian、ubuntu等常见的linux系统都可以。
回复

使用道具 举报

16

主题

178

帖子

930

积分

高级会员

Rank: 4

积分
930
金钱
752
HASS币
0
发表于 2024-5-16 20:33:38 | 显示全部楼层
inevitab 发表于 2024-5-16 18:30
包括但不限于PVE,只要是debian、ubuntu等常见的linux系统都可以。

我有个问题,怎么把网页显示温度数据转化为ha实体?
回复

使用道具 举报

43

主题

202

帖子

925

积分

高级会员

Rank: 4

积分
925
金钱
723
HASS币
0
 楼主| 发表于 2024-5-16 21:26:09 | 显示全部楼层
leung 发表于 2024-5-16 20:33
我有个问题,怎么把网页显示温度数据转化为ha实体?

可以看代码,用esphome的http_request组件读取网上数据,然后赋值给text_sensor组件,自动就会在HA里显示成实体。
回复

使用道具 举报

3

主题

189

帖子

2049

积分

金牌会员

Rank: 6Rank: 6

积分
2049
金钱
1860
HASS币
0
发表于 2024-6-2 14:06:49 | 显示全部楼层
黑群晖可以这样吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-11-24 23:07 , Processed in 0.164350 second(s), 35 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表