抬头仰望星空,是否能发现自己的渺小。

伪斜杠青年

人们总是混淆了欲望和理想

树莓派 PWM 温控风扇脚本

树莓派之树莓派-差不多两年前整了个树莓派。。。

之前刚买的时候为了酷炫搞了个带灯光的有风扇有 oled 小屏幕的扩展板,上几个月风扇开始出现异响,oled 也模模糊糊的看不清了,自己动手折腾来折腾去整了整给整坏了,于是干脆直接换了,经验告诉我,我需要只是一个散热,7*24小时运行要的是稳定不需要啥花里胡哨的,就去 TB 找了下风扇,然后确实被我找到了,20块钱便宜实惠。

只是用起来还是得自己写脚本,因为说明书上的这一行在 Ubuntu 系统上不生效:

dtoverlay=gpio-fan,gpiopin=18,temp=55000

当然为了让其生效我也安装了比如 userland(https://2byt.es/post/vcgencmd/)、libraspberrypi-bin(https://command-not-found.com/dtoverlay),括号后面都是安装方法,有需要的自取,不过最后还是没整好。

于是不想再浪费时间,因为诸与此类本质都是 GPIO 的高低电平控制,便直接检索了上面的配置,找到了一位老哥的脚本,仅一个 PIN 值的差别(12 换成了 18),原版代码如下:

#!/bin/bash

GPIO_PIN=12

HIGH_TEMP=50000
SAVE_TEMP=45000

function get_temp() {
  cat /sys/class/thermal/thermal_zone0/temp
}

function gpio_enable() {
  echo $1 > /sys/class/gpio/export
}

function gpio_disable() {
  echo $1 > /sys/class/gpio/unexport
}

function gpio_set_output() {
  echo out > /sys/class/gpio/gpio$1/direction
}

function gpio_set_input() {
  echo in > /sys/class/gpio/gpio$1/direction
}

function gpio_set_on() {
  echo 1  > /sys/class/gpio/gpio$1/value
}

function gpio_set_off() {
  echo 0 > /sys/class/gpio/gpio$1/value
}

function cleanup() {
  QUIT=1
}

QUIT=0

#echo "Enable GPIO ${GPIO_PIN}"
gpio_enable $GPIO_PIN

#echo "Set GPIO ${GPIO_PIN} Output"
gpio_set_output $GPIO_PIN

#echo "set GPIO ${GPIO_PIN} on"
#gpio_set_on $GPIO_PIN

LASTSTATUS=0


trap cleanup SIGINT SIGTERM

while [ 1 ]; do
  cputemp=$(get_temp)
  #echo "CPU TEMP = $cputemp"
  if [ $LASTSTATUS = 0 ]; then
    if [ $cputemp -gt $HIGH_TEMP ]; then
      echo "FAN ON"
      echo "CPU TEMP = $cputemp"
      gpio_set_on $GPIO_PIN
      LASTSTATUS=1
    fi
  else
    if [ $cputemp -lt $SAVE_TEMP ]; then
      echo "FAN OFF"
      echo "CPU TEMP = $cputemp"
      gpio_set_off $GPIO_PIN
      LASTSTATUS=0
    fi
  fi
  if [ "$QUIT" = "1" ]; then break; fi
  sleep 1
done

#echo "set GPIO ${GPIO_PIN} off"
gpio_set_off $GPIO_PIN

#echo "Disable GPIO ${GPIO_PIN}"
gpio_disable $GPIO_PIN

当然这肯定无法直接满足我的需求,需要按需配置,最后我改成了这样(temp_montior):

#!/bin/bash

GPIO_PIN=18

HIGH_TEMP=55000
SAVE_TEMP=45000

function get_temp() {
  cat /sys/class/thermal/thermal_zone0/temp
}

function gpio_enable() {
  echo $1 >/sys/class/gpio/export
}

function gpio_disable() {
  echo $1 >/sys/class/gpio/unexport
}

function gpio_set_output() {
  echo out >/sys/class/gpio/gpio$1/direction
}

# function gpio_set_input() {
#   echo in > /sys/class/gpio/gpio$1/direction
# }

function gpio_set_on() {
  echo 1 >/sys/class/gpio/gpio$1/value
}

function gpio_set_off() {
  echo 0 >/sys/class/gpio/gpio$1/value
}

# function cleanup() {
#   QUIT=1
# }

# QUIT=0

#echo "Enable GPIO ${GPIO_PIN}"
gpio_enable $GPIO_PIN

#echo "Set GPIO ${GPIO_PIN} Output"
gpio_set_output $GPIO_PIN

#echo "set GPIO ${GPIO_PIN} on"
#gpio_set_on $GPIO_PIN


# trap cleanup SIGINT SIGTERM

function get_date() {
  date +%Y-%m-%d
}

function trash_log() {
  echo "" > /root/init/temp.log
}

function clean_log() {
  date=$(get_date)
  if [ $LAST_DATE != $date ]; then
    trash_log
    LAST_DATE=$date
    echo "LCKISS-INIT: DATE = $LAST_DATE"
  fi
}

LAST_DATE=$(get_date)

echo "LCKISS-INIT: DATE = $LAST_DATE"

LAST_STATUS=0

function format_temp() {
  temp_f=$(echo "$1/1000" | bc -l)
  printf "LCKISS-INIT: CPU TEMP = %.2f°C\n" $temp_f
}

while [ 1 ]; do
  cputemp=$(get_temp)
  clean_log
  # format_temp $cputemp
  if [ $LAST_STATUS = 0 ]; then
    if [ $cputemp -gt $HIGH_TEMP ]; then
      echo "LCKISS-INIT: FAN ON"
      format_temp $cputemp
      gpio_set_on $GPIO_PIN
      LAST_STATUS=1
    fi
  else
    if [ $cputemp -lt $SAVE_TEMP ]; then
      echo "LCKISS-INIT: FAN OFF"
      format_temp $cputemp
      gpio_set_off $GPIO_PIN
      LAST_STATUS=0
    fi
  fi
  # if [ "$QUIT" = "1" ]; then break; fi
  sleep 5
done

#echo "set GPIO ${GPIO_PIN} off"
gpio_set_off $GPIO_PIN

#echo "Disable GPIO ${GPIO_PIN}"
gpio_disable $GPIO_PIN

再配合 nohup 后台运行:

nohup /root/init/temp_montior > /root/init/temp.log 2>&1 &

主要做了俩事儿,每天清空一次日志,以及大于55℃时开风扇,小于45℃时关风扇。

最后我再搞了个 service 丢在了 systemd (/etc/systemd/system/lckiss-init.service)

[Unit]
Description=rpi-fans-server
After=network.service

[Service]
Type=forking
User=root
Group=root
ExecStart=/root/init/temp_montior

[Install]
WantedBy=multi-user.target

然后启用这个服务,就可以使用 systemctl 进行管理了。

systemctl enable/disable/start/stop/status lckiss-init.service

这不比那些花里胡哨的板子香多了?

参考:

Control a cooling fan with gpio-fan (Device Tree Overlays)

其他:

CMake错误No CMAKE_CXX_COMPILER could be found.

vcgencmd for Ubuntu 20.04 aarch64 on RPi 4B

为shell布置陷阱:trap捕捉信号方法论


本站由以下主机服务商提供服务支持:

0条评论

发表评论