背景
树莓派因为性能和自身散热能力,容易在做一些复杂工作时温度升高,例如看个在线视频。而长期高温工作自然是不好的。淘宝上买来的小风扇,有很明显的降温效果,但是结构简单,两根线一根接5V,一根接地,所以插上之后只能一直运行。而且风扇声音很吵,比较烦。所以需要搞一个基于温度自动调整风扇转动的功能。
原理
树莓派:
+5v/0v 和一个引脚作为输出,用来控制风扇的开关即可。这里用到的是21号引脚(BCM列)
可以使用gpio readall命令查看对应的引脚编号与功能。实物设备右下角的最后一个引脚。
继电器:
1.选择高电平触发
2.输入三个端口:DC+/DC- 分别接树莓派的直流+5v/0v. 树莓派输出21引脚接继电器IN端口
3.输出选择公共端COM和常开端口NO,两个端口之间正常情况下处于断开状态,IN端口输入为高点平时,两个端口可以看做是一根导线的两端。将其与电扇串联构成电扇工作电路。
原理图
略丑。
为什么不直接用pin引脚接到风扇?
pin引脚电压输出3.3v,达不到风扇的标准工作电压,风扇虽然能转,但是基本没有风量,转速极慢。看到网上有人是用三极管不是继电器实现的,这里继电器本身价格不贵,而且电路结构稍微简单点,所以用继电器就好。
实物图:
我这里用的继电器是2路5v的。
代码目录结构:
目录设计的稍微复杂了一点是为了日后的可扩展性。真正涉及编写的只有用红线标明的四个文件。
1.detector.c
这个实现的功能是为了在后台持续运行,定时调用mainShell.sh进行温度检查,并做相应处理。定时的最小周期是1分钟,具体多久检查一次,还可以在脚本里用环境变量控制为1分钟的倍数。detector是这个.c文件编译出来的可执行文件。
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{
while (1) {
sleep(60);//检测最小时间单位:1分钟
system("~/work/script/mainShell.sh");
}
return;
}
2.mainShell.sh
脚本侧总入口,后续有其他新增的检测功能,直接修改这个脚本即可。不需要改C码,作为解释型语言,省去重新编译的麻烦。调用的autoCtrlTemp.sh即为真正的风扇调温处理。
#!/bin/bash
#监控系统脚本侧总入口
cd ~/work/script
#1.风扇温度检测自动调节
./autofan/autoCtrlTemp.sh
3.autoCtrlTemp.sh
这里设计的逻辑也很简单。
a.获取当前cpu温度。
b.温度高于55度,开启风扇,温度低于45度,关闭风扇。这里如果低于55度就关闭风扇的话,风扇会反复开启关闭次数太频繁,所以关闭温度设置为45度。
c.如果风扇状态发生了变化,则用日志记录发生变化时的温度与时间。
#!/bin/bash
temp=$(cat /sys/class/thermal/thermal_zone0/temp)
#echo $temp
let temp=temp/1000
#echo $temp
fanPath="/sys/class/gpio/gpio21/value"
if [ ! -e $fanPath ];
then
cd /sys/class/gpio
echo 21 > export
fi
beforeValue=$(cat $fanPath)
if [ $temp -gt 55 ]; #如果温度高于55,开启风扇
then
echo out > /sys/class/gpio/gpio21/direction
echo 1 > /sys/class/gpio/gpio21/value
elif [ $temp -lt 45 ]; #如果温度低于45,关闭风扇
then
echo out > /sys/class/gpio/gpio21/direction
echo 0 > /sys/class/gpio/gpio21/value
fi
afterValue=$(cat $fanPath)
if [ $beforeValue -ne $afterValue ];
then
cd ~/work/script/autofan
if [ $beforeValue -eq 0 ];
then
echo -e "\n####################################" >> autofan.log
echo Start Time: $(date) >> autofan.log
echo Current Temperature:$temp >> autofan.log
else
echo End Time: $(date) >> autofan.log
echo Current Temperature:$temp >> autofan.log
echo -e "####################################\n" >> autofan.log
fi
fi
4.start.sh
a.启动该功能,需要作为后台程序运行,日志也需要按照我们的预期来记录,所以启动命令有一点小麻烦,所以放到了脚本中,省力些。
b.如果修改C码,那么还需要重新编译,所以把这些麻烦的工作都封装到脚本中,省力高效。
c.顺便记录了启动日志。
#!/bin/bash
cd ~/work
if [ ! -e "./detector" ];
then
cd c_code
gcc detector.c -o detector
mv detector ../detector
fi
cd ~/work
nohup ./detector 1> /dev/null &
echo -e "\n################################" >> log.log
date >> log.log
echo ProcessId: $(pgrep detector) >> log.log
echo -e "################################\n" >> log.log
5.日志文件效果:
log.log 记录了启动时间与进程ID,方便kill。
################################
2018年 12月 31日 星期一 19:48:38 CST
ProcessId: 13945 14480
################################
################################
2018年 12月 31日 星期一 20:06:27 CST
ProcessId: 15010
################################
################################
2018年 12月 31日 星期一 20:58:50 CST
ProcessId: 1390
################################
autofan.log
记录状态发生变化的时间与温度。
####################################
Start Time: 2018年 12月 31日 星期一 19:07:50 CST
Current Temperature:52
End Time: 2018年 12月 31日 星期一 19:08:41 CST
Current Temperature:47
####################################
####################################
Start Time: 2018年 12月 31日 星期一 19:41:40 CST
Current Temperature:70
End Time: 2018年 12月 31日 星期一 19:52:00 CST
Current Temperature:44
####################################
####################################
Start Time: 2018年 12月 31日 星期一 19:57:40 CST
Current Temperature:61
End Time: 2018年 12月 31日 星期一 19:59:33 CST
Current Temperature:47
####################################
至此,这个温度自动控制的简单系统搭好了,后续如果增加其他功能,比如根据土壤湿度传感器检测来自动控制浇花的系统,也可以在这个基础上添加,扩展方便。