树莓派 ubuntu gpio_树莓派自动温控风扇

某天忘记把树莓派的电源断掉,然后第二天早上被它的风扇声音吵醒!!
严格来说在温度不高的时候风扇没必要打开,好在树莓派最不怕的就是各种折腾了。
动手把风扇改成温控的。

描述

raspbian的/sys/class/thermal/thermal_zone0/temp文件内存着CPU的温度,读出来处以1000就得到温度了,省了给它测温的麻烦,大赞。
另外需要用的一个三极管,我这里用的是S9013,网上很多教程用的是S8085。严格来说不同的三极管实现起来是有不同的,这里不深究哪种三极管更好了。
突然想复习一下三极管怎么工作的( ╯□╰ )

预备知识

首先要知道的是树莓派的引脚定义,将树莓派有网络接口的一端朝下,有GPIO接口(就是那四十个脚)的一面面向自己,从上到下,从左到右,为物理引脚1~40,像这样

但是具体到程序内,用的不是物理引脚,不同的库对引脚的定义也不同,这里提供一个对照图

本文将使用winringPi作为控制引脚的库。
可以使用命令

sudo apt install wiringpisudo apt purge wiringpi

来完成安装,可以使用

gpio -v

来验证。
目前没有查询到每个脚具体的电气参数,理论上是可以将风扇直接插在引脚上,然后控制引脚的电平来间接控制风扇的开关的,但是不清楚具体哪个脚能承受多大的电流,就没有贸然尝试了。用了比较保险的三极管。
将三极管平的一面面向自己,引脚向下,从左到右引脚分别是E(发射极Emitter)B(基极Basic)C(集电极collector)。
连接示意图参考如下

d0e39f2ec6c1aefe8a4c46075c2af15c.png

安装

按图连接好之后,安装控制软件了。

git clone https://github.com/BDZNH/AutoControlRaspberryFan.gitcd AutoControlRaspberryFanmakesudo make install

可以前往https://github.com/BDZNH/AutoControlRaspberryFan查看帮助。

源代码

/******************************************************************************-------------------------------------------------------------------------------        Project Name : AutoControlRaspberryfan                                         Author       : BDZNH                                                           Project URL  : https://github.com/BDZNH/AutoControlRaspberryFan                what is this : Auto control raspberry fan with 5V. Turn the fan                               when the temperaure is high than 45°C, turn off                                fan when the CPU temperature is lower than 39°C.        -------------------------------------------------------------------------------******************************************************************************/#include #include #include #include #include #include #define TEMP_PATH "/sys/class/thermal/thermal_zone0/temp"#define LOG_PATH "/tmp/RaspberrypiFanSpeed.log"#define PID_PATH "/var/run/autocontrolfan.pid"#define _FANPIN 8#define min(x,y) (x<=y?x:y)using namespace std;void GetCpuTempera(ifstream &fin,double &temp);int initWiringPi();void showInfo();void SaveLog(ofstream &log, double &temp, int FanSpeed, time_t &time_cur);int main(){showInfo();ofstream log(LOG_PATH);if (!log.is_open()){cout << "Can't open file : " << LOG_PATH << endl;}log.close();ifstream fin(TEMP_PATH, ios_base::in);if (!fin.is_open()){cout << "Can't open file : " << TEMP_PATH << endl;return -1;}ofstream pid(PID_PATH);if (!pid.is_open()){cout << "Can't open file : " << PID_PATH << endl;}pid << getpid() << endl;pid.close();pid.clear();time_t time_cur;double temp = 0;int Fan_Speed = 0;bool Forty_five_Flag = false;if (initWiringPi() < 0){return -1;}while (true){GetCpuTempera(fin,temp);if (temp >= 42)cout << "Cpu temperature is : 033[0;31m" << temp << "°C   033[0m" << flush;elsecout << "Cpu temperature is : 033[1;32m" << temp << "°C   033[0m" << flush;if (Forty_five_Flag){if (temp < 39.0){Forty_five_Flag = false;Fan_Speed = 0;softPwmWrite(_FANPIN, Fan_Speed);SaveLog(log, temp, Fan_Speed, time_cur);}else{SaveLog(log, temp, Fan_Speed, time_cur);}sleep(1);}else{if (temp < 39.0){sleep(1);Fan_Speed = 0;softPwmWrite(_FANPIN, Fan_Speed);SaveLog(log, temp, Fan_Speed, time_cur);}else if (temp >= 40.0 && temp <= 45.0){Fan_Speed = min(((((int)temp - 40) * 10) + 60),100);softPwmWrite(_FANPIN, Fan_Speed);SaveLog(log, temp, Fan_Speed, time_cur);sleep(2);}else if (temp > 45.0){Fan_Speed = 100;softPwmWrite(_FANPIN, Fan_Speed);Forty_five_Flag = true;SaveLog(log, temp, Fan_Speed, time_cur);sleep(5);}}sleep(1);cout << "";}return 0;}void GetCpuTempera(ifstream &fin, double &temp){fin >> temp;temp = temp / 1000.0;fin.clear();fin.seekg(0, ios::beg);}int initWiringPi(){if (wiringPiSetup() != 0){cout << "WiringPi setup failed" << flush << " ";return -1;}if (softPwmCreate(_FANPIN, 0, 100) != 0){cout << "softPwmcreat setup failed" << flush << " ";return -2;}return 0;}void showInfo(){cout << "-------------------------------------------------------------------------------" << endl;cout << "        Project Name : AutoControlRaspberryfan                                 " << endl;cout << "        Author       : BDZNH                                                   " << endl;cout << "        Project URL  : https://github.com/BDZNH/AutoControlRaspberryFan        " << endl;cout << "        what is this : Auto control raspberry fan with 5V. Turn the fan        " << endl;cout << "                       when the temperaure is high than 45°C, turn off         " << endl;cout << "                       fan when the CPU temperature is lower than 39°C.        " << endl;cout << "-------------------------------------------------------------------------------" << endl;cout << "" << endl;}void SaveLog(ofstream &log, double &temp, int Fan_Speed, time_t &time_cur){log.open(LOG_PATH,ios_base::out);if (!log.is_open()){cout << "Can't open file : " << LOG_PATH << endl;}time(&time_cur);log << ctime(&time_cur) << "CPU temperature is : " << temp << "°C Set fan speed to " << Fan_Speed << endl;log.close();log.clear();}

代码内设定的是超过45°C时开启风扇,低于39°C时关闭风扇。处于[40°C,45°C]时按需调节,温度越高,转速越快。
后边会让程序支持指定阈值和工作模式,不知道是不是我的错觉,不是满速旋转的时候风扇有怪怪的声音。

生命重在折腾


参考资料

https://blog.newnius.com/raspberry-control-fan-with-transistor.html
树莓派wiringPi库详解
PS:链接一内的脚本用Python实现,无奈Python会占用大量CPU,对树莓派来说并不合适。后来虽然在百度也找到一些python脚本,占用资源也很少,但是还是写了这个练手。

百度贴吧找到的python脚本

#!/usr/bin/env python# encoding: utf-8import RPi.GPIOimport timeRPi.GPIO.setwarnings(False)RPi.GPIO.setmode(RPi.GPIO.BCM)RPi.GPIO.setup(2, RPi.GPIO.OUT)pwm = RPi.GPIO.PWM(2,100)RPi.GPIO.setwarnings(False)speed = 0prv_temp = 0try:while True:tmpFile = open( '/sys/class/thermal/thermal_zone0/temp' )cpu_temp = int(tmpFile.read())tmpFile.close()if cpu_temp>=34500 :if prv_temp<34500 :#启动时防止风扇卡死先全功率转0.1秒pwm.start(0)pwm.ChangeDutyCycle(100)time.sleep(.1)speed = min( cpu_temp/125-257 , 100 )pwm.ChangeDutyCycle(speed)else :pwm.stop()prv_temp = cpu_temptime.sleep(5)except KeyboardInterrupt:passpwm.stop()
树莓派4BGPIO_NUM对应地址如下: | GPIO_NUM | BCM GPIO | Physical Pin | Address (BCM2835) | | -------- | -------- | ------------ | ----------------- | | 2 | GPIO 2 | Pin 3 | 0x7e215008 | | 3 | GPIO 3 | Pin 5 | 0x7e21500c | | 4 | GPIO 4 | Pin 7 | 0x7e215010 | | 5 | GPIO 5 | Pin 29 | 0x7e215014 | | 6 | GPIO 6 | Pin 31 | 0x7e215018 | | 7 | GPIO 7 | Pin 26 | 0x7e21501c | | 8 | GPIO 8 | Pin 24 | 0x7e215020 | | 9 | GPIO 9 | Pin 21 | 0x7e215024 | | 10 | GPIO 10 | Pin 19 | 0x7e215028 | | 11 | GPIO 11 | Pin 23 | 0x7e21502c | | 12 | GPIO 12 | Pin 32 | 0x7e215030 | | 13 | GPIO 13 | Pin 33 | 0x7e215034 | | 14 | GPIO 14 | Pin 8 | 0x7e215038 | | 15 | GPIO 15 | Pin 10 | 0x7e21503c | | 16 | GPIO 16 | Pin 36 | 0x7e215040 | | 17 | GPIO 17 | Pin 11 | 0x7e215044 | | 18 | GPIO 18 | Pin 12 | 0x7e215048 | | 19 | GPIO 19 | Pin 35 | 0x7e21504c | | 20 | GPIO 20 | Pin 38 | 0x7e215050 | | 21 | GPIO 21 | Pin 40 | 0x7e215054 | | 22 | GPIO 22 | Pin 15 | 0x7e215058 | | 23 | GPIO 23 | Pin 16 | 0x7e21505c | | 24 | GPIO 24 | Pin 18 | 0x7e215060 | | 25 | GPIO 25 | Pin 22 | 0x7e215064 | | 26 | GPIO 26 | Pin 37 | 0x7e215068 | | 27 | GPIO 27 | Pin 13 | 0x7e21506c | | 28 | GPIO 28 | Pin 27 | 0x7e215070 | | 29 | GPIO 29 | Pin 28 | 0x7e215074 | | 30 | GPIO 30 | Pin 3 | 0x7e215078 | | 31 | GPIO 31 | Pin 5 | 0x7e21507c | 其中,BCM GPIO是BCM2835芯片上GPIO的编号,Physical Pin是树莓派4B引脚的物理编号。地址是BCM2835芯片中GPIO寄存器的地址,可以通过访问这些地址来控制树莓派4BGPIO
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值