為了提高樹莓派的散熱效率,可以加一個小風扇,網上那種5v-dc 25x25的就可以。 我使用一個s9013三極管控制風扇的啟停,電路原理圖如下所示:
基極電阻的大小可以根據實際情況調整,如果電阻過大會導致基極電流太小,進而CE電流太?。?如果電阻過小,可能會燒壞三極管。 最佳狀態是三極管導通后ce電流剛好是風扇的額定電流,可以根據風扇額定電流和三極管放大倍數大概算出基極的電流,然后根據gpio電壓算出需要的電阻。
控制風扇可以有多種方式,c、python、shell腳本都可以,下面是我實現的代碼。
1、使用linux文件IO函數,實現開關風扇操作,這是最直接簡單的方式,不需要安裝其他東西,就是要頻繁開關文件。
#include
#include
#include
#include
#include
int get_temp()
{
char temp[8];
int fd = open("/sys/class/thermal/thermal_zone0/temp",O_RDONLY);
read(fd,&temp,5);
close(fd);
return atoi(temp);
}
uint8_t fan_on = 0;
void main()
{
char* buff = "18";
int fd = access("/sys/class/gpio/gpio18/value",F_OK);
if(fd<0)
{
fd = open("/sys/class/gpio/export",O_WRONLY);
write(fd,buff,1);
close(fd);
}
fd = open("/sys/class/gpio/gpio18/direction",O_WRONLY);
buff = "out";
write(fd,buff,3);
close(fd);
while(1)
{
int temp = get_temp();
// printf("temp:%f\\n",temp/1000.0);
temp /=1000;
if((fan_on == 1)&&(temp <= 40))
{
fd = open("/sys/class/gpio/gpio18/value",O_WRONLY);
buff = "0";
write(fd,buff,1);
close(fd);
printf("fan off\\n");
fan_on = 0;
}
else if((fan_on == 0)&&(temp >=45))
{
fd = open("/sys/class/gpio/gpio18/value",O_WRONLY);
buff = "1";
write(fd,buff,1);
close(fd);
printf("fan on\\n");
fan_on = 1;
}
sleep(1);
}
}
2、使用bcm2835庫,開關控制風扇,需要安裝bcm2835庫,編譯需要加上-lbcm2835選項,另外需要sudo管理員權限運行。
#include
#include
#include
#include
#include
#define PIN RPI_GPIO_P1_12
int get_temp()
{
char temp[8];
int fd = open("/sys/class/thermal/thermal_zone0/temp",O_RDONLY);
read(fd,&temp,5);
close(fd);
return atoi(temp);
}
int main(int argc,char **argv)
{
if (!bcm2835_init())
return 1;
// 輸出方式
bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_OUTP);
while (1)
{
int temp = get_temp();
// printf("temp:%f\\n",temp/1000.0);
temp /=1000;
if((fan_on == 1)&&(temp <= 40))
{
bcm2835_gpio_write(PIN, HIGH);
fan_on = 0;
}
else if((fan_on == 0)&&(temp >=45))
{
bcm2835_gpio_write(PIN, LOW);
fan_on = 1;
}
bcm2835_delay(1000);
}
bcm2835_close();
return 0;
}
3、使用bcm2835庫,pwm方式控制,可以更精細的控制轉速,不過pwm的頻率不宜太高,否則高頻噪音很大,還不如讓其全速運行。 另外pwm占空比過低風扇也不轉,所以我直接讓他從50%開始運轉,并且在停止和運轉有一個死區,避免在零界點頻繁啟停。 具體大家可以根據自己的需求調整。
#include
#include
#include
#include
#include
#include
// PWM output on RPi Plug P1 pin 12 (which is GPIO pin 18)
// in alt fun 5.
// Note that this is the _only_ PWM pin available on the RPi IO headers
#define PIN RPI_GPIO_P1_12
// and it is controlled by PWM channel 0
#define PWM_CHANNEL 0
// This controls the max range of the PWM signal
#define RANGE 200
int get_temp()
{
char temp[8];
int fd = open("/sys/class/thermal/thermal_zone0/temp",O_RDONLY);
read(fd,&temp,5);
close(fd);
return atoi(temp);
}
int temp;
int main(int argc, char **argv)
{
if (!bcm2835_init())
return 1;
// Set the output pin to Alt Fun 5, to allow PWM channel 0 to be output there
bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_ALT5);
bcm2835_pwm_set_clock(BCM2835_PWM_CLOCK_DIVIDER_2048);
bcm2835_pwm_set_mode(PWM_CHANNEL, 1, 1);
bcm2835_pwm_set_range(PWM_CHANNEL, RANGE);
while (1)
{
temp= get_temp()/100;
// printf("temp:%f\\n",temp/1000.0);
if((temp <= 400))
{
bcm2835_pwm_set_data(PWM_CHANNEL, 0);
}
else if(temp > 500)
{
bcm2835_pwm_set_data(PWM_CHANNEL, RANGE);
}
else if(temp > 450)
{
bcm2835_pwm_set_data(PWM_CHANNEL, (temp-450)*2+100);
}
//printf("temp:%d\\n",temp);
sleep(1);
}
bcm2835_close();
return 0;
}
4、python開關控制
import RPi.GPIO as gpio
from time import sleep
Temper_HI = 47 # 風扇啟動溫度
Temper_LO = 40 # 風扇關閉溫度
gpio_pin = 12
# 初始化GPIO針腳控制
gpio.setmode(gpio.BOARD)
gpio.setup(gpio_pin, gpio.OUT)
while True:
with open("/sys/class/thermal/thermal_zone0/temp", "r") as f:
temper = int(f.read()) // 100 / 10 # 計算溫度,保留一位小數
# print(temper)
if temper > Temper_HI:
gpio.output(gpio_pin, gpio.HIGH)
if temper < Temper_LO:
gpio.output(gpio_pin, gpio.LOW)
sleep(1)
5、python pwm控制
import RPi.GPIO as gpio
import time
fan_gpio_pin = 12
temp_max = 500
temp_on = 450
temp_min = 400
def get_cpu_temp():
with open('/sys/class/thermal/thermal_zone0/temp') as f:
cpu_temp = int(f.read())
return cpu_temp/100
def main():
gpio.setwarnings(False)
gpio.setmode(gpio.BOARD)
gpio.setup(fan_gpio_pin, gpio.OUT, initial=gpio.LOW)
pwm = gpio.PWM(fan_gpio_pin, 50)
hasFanStarted = False
while True:
temp = get_cpu_temp()
# print(temp)
if temp < temp_min:
if hasFanStarted:
pwm.start(0)
hasFanStarted = False
elif temp >= temp_on and temp <= temp_max:
pwm.start(temp-temp_on+50)
hasFanStarted = True
elif temp > temp_max:
pwm.start(100)
hasFanStarted = True
time.sleep(1)
if __name__ == '__main__':
main()
6、shell腳本開關控制(shell腳本語法有點麻煩,不熟悉不建議使用)
#! /bin/bash
fan_is_on=0
if [ ! -e "/sys/class/gpio/gpio18/value" ]
then
echo "export gpio 18"
echo "18" > "/sys/class/gpio/export"
fi
echo "out" > "/sys/class/gpio/gpio18/direction"
while ((1))
do
TEMP=$(cat /sys/class/thermal/thermal_zone0/temp)
echo $TEMP
if [[ $fan_is_on -eq 1 ]] && [[ $TEMP -lt 40000 ]]
then
fan_is_on=0
echo "fan off"
echo "0" > "/sys/class/gpio/gpio18/value"
elif [[ $fan_is_on -eq 0 ]] && [[ $TEMP -gt 45000 ]]
then
fan_is_on=1
echo "fan on"
echo "1" > "/sys/class/gpio/gpio18/value"
fi
sleep 1s
done
大家覺得哪種方式更好呢? 如果是你會選擇哪個?
-
三極管
+關注
關注
143文章
3619瀏覽量
122181 -
電流
+關注
關注
40文章
6913瀏覽量
132449 -
Linux
+關注
關注
87文章
11329瀏覽量
209969 -
風扇
+關注
關注
4文章
414瀏覽量
37462 -
樹莓派
+關注
關注
117文章
1710瀏覽量
105759
發布評論請先 登錄
相關推薦
評論