夸克之书

  • 首页
  • 科普
  • 笔记
  • C#
  • 物联网
  • 算法
  • Linux
  • 树莓派
夸克之内,别有洞天
  1. 首页
  2. 默认
  3. 正文

树莓派PWM风扇控制

2021-02-26 5486点热度 1人点赞 5条评论

首先声明:极客物联吧帖子也是本人发布,非搬运。

马上夏天了,很多小伙伴的树莓派肯定也是热的不行了吧?我的也是,这代虽然说性能是增强了不少,但是发热也随之增大了不少。原来我是直接贴了几个散热片了事,正常使用情况下,冬天温度也才40-50度左右。最近想搞搞人脸识别,又入手了一个树莓派,也顺便买了一个散热小风扇,但是这个风扇是没有PWM调速的。本着生命不息,折腾不止的心态,既然本身不带,树莓派有这么好的条件,GPIO完全是可以用上的。

其实是以前就折腾过,不过再次翻出来来而已,顺便整理一下代码和文章。

某宝上面有这么一个小玩意儿,可以方便的用来控制风扇。嫌贵或者挡住了也可以自己用NPN三极管做一个,风扇+极直接接在5v上,-极接在三极管集电极C。三极管发射极E接0V,基极B接GPIO3。

%title插图%num

这玩意用到了GPIO3,wiringpi编码为8。

%title插图%num
PI GPIO

然后就是为风扇控制编写代码了,以下代码用C语言编写,直接拿来主义就是了。原理也很简单,就是获取CPU温度,然后判断CPU处于哪个阶段,再设置对应的PWM脉冲宽度即可。

/*
 *
 * main.c
 *
 * Created on: 2017年7月24日
 *
 * 说明:程序使用的是wiringPi。PWM接口为8
 *
 * Author: afirefish
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <wiringPi.h>
#include <softPwm.h>
#define _FANPIN 8
#define MAX_SIZE 32
#define TEMP_PATH "/sys/class/thermal/thermal_zone0/temp"

int initWiringPi();
float getCpuTemp();
void dieError( char *errors );

int main( void ) {
	/* 初始化 */
	if ( initWiringPi() < 0 ) {
		return(-1);
	}
	printf( "[ OK ]Start [quarkbook.com] fan controler.\n" );
	/* 启动时防止风扇卡死,全功率运行1s */
	softPwmWrite( _FANPIN, 99 );
	delay( 1000 );
	while ( 1 ) {
		/* 获取CPU温度 浮点数据 */
		float temp = getCpuTemp();
		printf( "CPU tempreture is %0.2f\n", temp );
		/* 如果小于0,说明获取失败,设置50%电压 */
		if ( temp < 0 ) {
			softPwmWrite( _FANPIN, 50 );
		} else if ( temp < 30 ) {
			softPwmWrite( _FANPIN, 0 );
		} else if ( temp > 30 && temp < 40 ) {
			softPwmWrite( _FANPIN, 30 );
		} else if ( temp > 40 && temp < 50 ) {
			softPwmWrite( _FANPIN, 40 );
		} else if ( temp > 50 && temp < 60 ) {
			softPwmWrite( _FANPIN, 50 );
		} else {
			softPwmWrite( _FANPIN, 80 );
		}
		delay( 1000 );
	}
	return(0);
}

/*
 *
 * 初始化wiringPi
 *
 */
int initWiringPi() {
	if ( wiringPiSetup() != 0 ) {
		dieError( "WiringPi setup failed!" );
		return(-1);
	}
	if ( softPwmCreate( _FANPIN, 0, 100 ) != 0 ) {
		dieError( "GPIO soft pwm setup failed!" );
		return(-2);
	}
	return(0);
}

/*
 *
 * 获取树莓派CPU温度
 *
 */
float getCpuTemp() {
	int fd;
	float temp = 0;
	char buf[MAX_SIZE];
	/* 打开/sys/class/thermal/thermal_zone0/temp */
	fd = open( TEMP_PATH, O_RDONLY );
	if ( fd < 0 ) {
		dieError( "Failed to open thermal_zone0/temp" );
		return(-1);
	}
	/* 读取内容 */
	if ( read( fd, buf, MAX_SIZE ) < 0 ) {
		fclose(fd);
		dieError( "Failed to read temp\n" );
		return(-1);
	}
	fclose(fd);
	/* 转换为浮点数打印 */
	temp = atoi( buf ) / 1000.0;
	return(temp);
}

/*
 *
 * 输出错误信息
 *
 */
void dieError( char *errors ) {
	if ( strlen( errors ) <= 0 ) {
		return;
	} else {
		printf( "[ FAILED ]%s\n", errors );
	}
}

很简单的C语言代码。创建一个.c的文件,然后将上述代码粘贴到创建的文件中。

nano fan_controler.c

然后编译。

sudo gcc fan_controler.c -o fan_controler -lwiringPi

因为用到了wiringPi,所以需要引用wiringPi。如果没有任何错误提示,即表示编译成功。先来测试一下,运行编译好的代码:

sudo ./fan_controler

可以看到控制台已经输出温度了,如果接线正确,风扇转速应该也随之降低了。

%title插图%num

然后就来配置后台运行和开机启动,我们将刚刚编译好的代码作为服务运行。

sudo cp fan_controler /usr/bin/
sudo nano /etc/systemd/system/fan-control.service  #编写服务

将下面的代码粘贴到fan-control.service中:

[Unit]
Description=Fan Controller

[Service]
WorkingDirectory=/usr/bin/
ExecStart=/usr/bin/fan_controler
Restart=always
SyslogIdentifier=Fan Controller
User=root

[Install]
WantedBy=multi-user.target

启动服务。

sudo systemctl start fan-control.service  #启动

查看服务的运行状态

sudo systemctl status fan-control.service  #状态

显示Active即表示服务已经正常启动了。然后设置服务开启自动启动。

sudo systemctl enable fan-control.service  #设置开机启动

到此,PWM小风扇就打造完成了,是不是so easy啦~

附录:

1、服务管理命令

sudo systemctl stop fan-control.service  #停止
sudo systemctl disable fan-control.service  #关闭开机启动

本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2021-03-22

afirefish

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

文章评论

  • qcgzxw

    sudo下执行 无法控制小风扇
    普通用户却可以 这是可能是什么原因 :redface:

    2021-03-19
    登录以回复
  • qcgzxw

    闹了半天找到问题了 原来是gpio版本问题
    pi@raspberrypi:~/Desktop $ gpio readall
    Oops - unable to determine board type... model: 17
    pi@raspberrypi:~/Desktop $ gpio -v
    gpio version: 2.50

    gpio默认最新版本为2.50
    我的设备是Raspberry Pi 4B 会报错“Oops - unable to determine board type... model: 17”
    解决方法:手动更新到gpio最新版2.52即可
    https://project-downloads.drogon.net/wiringpi-latest.deb

    2021-03-19
    登录以回复
    • 管理员

      @qcgzxw 这个倒没有注意,好想我的树莓派上面没有遇到这个问题。或者也可以通过apt dist-upgrade解决?

      2021-03-22
      登录以回复
  • qcgzxw

    function getCpuTemp()
    函数结束之前使用close关闭 文件流
    不关闭的话长时间运行可能会有问题

    2021-03-21
    登录以回复
    • 管理员

      @qcgzxw 感谢指出问题,已经修改。

      2021-03-22
      登录以回复
  • 您需要 登录 之后才可以评论
    放松一下
    https://www.quarkbook.com/wp-content/uploads/2021/05/凤凰传奇-海底(Live).flac
    分类
    • C#
    • Linux
    • 树莓派
    • 物联网
    • 科普
    • 笔记
    • 算法
    • 默认
    最新 热点 随机
    最新 热点 随机
    Windows移除多余输入法'Unknown Locale (qaa-Latn)' 【算法】具有层级关系的城市,例如"中国 广州","中国 浙江 杭州" 一个 List 最后应该是转成树状图输出 树莓派安装Golang环境 树莓派 Zero USB/以太网方式连接配置教程 树莓派Zero 2 w超频 PVE使用山克UPS(ViewPower)
    解决Visual Studio 2022中无法编译 .NET Framework 4.5/4.5.1项目(Visual Studio 2022安装.NET Framework 4.5)PVE使用山克UPS(ViewPower)树莓派Zero 2 w超频树莓派 Zero USB/以太网方式连接配置教程树莓派安装Golang环境【算法】具有层级关系的城市,例如"中国 广州","中国 浙江 杭州" 一个 List 最后应该是转成树状图输出
    PostgreSQL重置所有表Sequence 在.NET 6中System.Drawing.Common引发的“The type initializer for 'Gdip' threw an exception.”异常 树莓派PWM风扇控制 批处理器(BAT)自动请求管理员权限 Debian 9开启Google BBR EF第一次加载较慢的原因以及解决方法(汇)(转)
    最近评论
    去月球 发布于 4 个月前(01月17日) 如果使用CSI的摄像头应该怎么修改命令呢
    Me 发布于 5 个月前(12月31日) 好像还得写启动项 要不重启就还原了。
    十三 发布于 5 个月前(12月23日) 大神,网盘链接失效了,重新分享一下吧,
    一键快乐 发布于 11 个月前(07月09日) 老哥 我替换之后能进去了但是网络和声音上有两个×怎么办
    翩翩蒯公子 Maxwell 发布于 1 年前(05月15日) 赞一个,挺好的文章。
    书签
    • 打赏
    • 毒鸡汤(有点意思)
    • 米店
    • 金鱼直播间

    COPYRIGHT © 2022 quarkbook.com. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang

    蜀ICP备15036129号-9

    登录
    注册|忘记密码?