0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

树莓派控制风扇的几种方式

CHANBAEK 来源:头条号科G栈 作者:头条号科G栈 2023-03-22 15:22 次阅读

为了提高树莓派的散热效率,可以加一个小风扇,网上那种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

大家觉得哪种方式更好呢? 如果是你会选择哪个?

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 三极管
    +关注

    关注

    141

    文章

    3491

    浏览量

    119053
  • 电流
    +关注

    关注

    40

    文章

    5986

    浏览量

    129868
  • Linux
    +关注

    关注

    87

    文章

    10986

    浏览量

    206718
  • 风扇
    +关注

    关注

    4

    文章

    397

    浏览量

    36873
  • 树莓派
    +关注

    关注

    113

    文章

    1637

    浏览量

    104712
收藏 人收藏

    评论

    相关推荐

    炫酷实用的树莓外壳

    了一个“手握式”的树莓支架。这个支架就采用一个废弃的木块,配合树莓的接口雕刻成“手握”的形状,同时在树莓派上加挂了散热
    发表于 09-03 14:44

    树莓新作!使用树莓红外控制空调和风扇

    树莓派发展至今,出过的作品已经很多了,今天就和大家分享一下一个树莓新作.使用树莓红外控制空调
    发表于 09-11 15:59

    树莓能不能加个可以根据CPU使用情况变风速的风扇

    树莓能不能加个可以根据CPU使用情况变风速的风扇?怎么加?
    发表于 12-17 21:14

    树莓自动散热风扇

    控制一个迷你5V风扇,不需要用到电路实验板和晶体管之类的。只需要一些电缆和通道继电器。这里推荐2通道继电器。一个脚本执行每小时检查树莓温度和开/关
    发表于 01-06 15:20

    树莓网络控制的船

    一个使用webiopi框架的基本的简单的Python代码建立的。第一步:零件和工具零件[树莓(任何型号)L298N电机驱动模块TP-Link USB WiFi遥控船电池组USB电源树莓
    发表于 01-20 15:24

    树莓派系列教程3:访问树莓

    。二、外接LCD显示屏 如果你觉得抱着鼠标键盘麻烦,那么你可以接LCD触摸屏,触摸控制树莓,像平板一样玩三、SSH 更常用的方式是通过ssh控制
    发表于 03-28 11:09

    树莓3 b 风扇自动运行 改装

    树莓3 b买来的壳子带风扇风扇大部分时间是不需要工作的,但是也没个开关,插拔杜板线也甚是麻烦,好不方便。想到这事树莓
    发表于 02-10 15:31

    控制树莓板载 LED 的几种方式

    所有的树莓型号或多或少都自带了一些]
    发表于 05-23 07:00

    请问树莓管脚有哪几种编码方式

    树莓40Pin引脚对照表树莓管脚有三种编码方式
    发表于 11-10 07:11

    树莓与Arduino UNO是怎样对接的

    树莓与Arduino UNO是怎样对接的?有哪几种方式?最容易实现的方式是哪一种?
    发表于 09-07 06:08

    【.NET 与树莓】小风扇模块 精选资料分享

    想,这种小风扇直接上电源就行了,还用得着单片机和树莓?确实,不过,搭配 L9110 驱动芯片,再用单片机发出...
    发表于 09-08 07:33

    树莓4B Ubuntu 21.04自动温控开关风扇

    树莓4B Ubuntu 21.04 自动温控开关风扇以及RPi.GPIO避坑指南本人对树莓有一些了解,虽然学过模电数电,但也只是学过,过
    发表于 09-08 07:38

    树莓是怎样控制风扇散热的

    树莓9层外壳自带一个散热风扇风扇是2针的,不能控制,插上电源后就一直全速运转,晚上噪音很大。而且,一直运行,
    发表于 09-08 07:47

    树莓能做什么

    按键实验第八课:树莓Python开发 PWM实验第九课:树莓Python开发 电机实验视频链接我们要干什么在学一个知识点的时候,特别是硬件相关的,选一个好的实验
    发表于 09-10 07:28

    树莓3B/4B散热风扇

    描述树莓 4 风扇树莓 3B/3B+/4B 散热风扇帽适用于 Raspberry 3 及以
    发表于 07-27 06:02