本鱼拟成立工作室承接项目开发/软件定制/云设施开发运维/办公设备技术支持等,如您有相关需求,欢迎来询 | ::博客文章推荐::

用Arduino打造三路六输入的温控风扇

: 硬件/HW 木魚 3968℃ 7评论

在之前的《盘一下最近收到的二手DC非隔离降压模块》里,我有提到自建的简易NAS:

这个迷你NAS运行的是CentOS系统,拥有3*6TB HDD,2*3TB SSD,1*1TB SSD以及512GB NVME存储,16GB内存。CPU似乎是六代I5,工程品我不是很确定。

现在聊一聊这个自建NAS中的有趣玩意儿:散热风扇。

现状

这个自建NAS是用一个迷你的收纳箱来做机箱的,塑料材质,如下图所示:

当然,拿来做机箱的话,是要撇掉盖子的。

3个6TB硬盘,使用若干年前买的亚克力硬盘笼支架:

这个三盘位亚克力支架可以安装三块3.5寸的机械硬盘。安装后,我把NUC6的主板倒扣在支架最上面,这时候硬盘和主机之间还有大概4公分的高度,于是我用3D打印了一个三盘位的固态硬盘支架放在这里面。还有最后一块1TB的固态硬盘,使用双面胶贴在支架侧面。

 

由于NUC6有三个USB3.0接口,而SATA接口只有一个,因此这七块硬盘,有六块是通过SATA-USB3.0转接卡来挂到系统里的:

  • 一个USB3.0口通过一个四口的USB3.0 HUB挂载了三块3.5寸的HDD
  • 一个三星860EVO的SSD直接连接到主板上的SATA口,采用主板的供电
  • 两块SSD分别通过SATA-USB3.0转接卡直接挂到两个USB3.0口上
  • Realtek的2.5G USB网卡挂到第四个USB3.0口上
  • 一块1TB的SSD插在上述的四口HUB上

系统使用的是前面文章里提到的200W单路12V16A电源进行供电,这个电源的体积足够小正好放在盒子的缝隙中。2.5G的USB3.0网卡使用双面胶贴在壁上。

SSD的供电基本上可以直接由USB3.0口提供,三个机械硬盘由转接卡供电,而转接卡的12V供电统一由上述电源进行供电。

散热?

上面的支架仔细看看,会发现有一端有一个安装风扇的槽位,可以安装8cm的风扇。考虑到这台主机装完了就扔在客厅,而这三伏天气客厅气温在30度朝上,机械硬盘如果使用的话连续读写,那温度不可小觑,所以散热风扇是必须的。

除此以外,对于固态硬盘和电源,都有可能会有高温。所以,为了稳定可靠起见(也为了省空调电费),我最初设计了三路风扇,分别是:三块机械硬盘的8cm风扇;两块SSD的5cm风扇,开关电源的4cm风扇。

由于风扇么,大家懂的,还是有声音的,所以我对风扇做出了如下的设计要求:

  1. 不需要转的时候不转(比如机械硬盘都在休眠中,发热不高,没有必要散热)
  2. 需要的时候以最低要求转(能控制住温度即可,转速越低越好,省电+降噪+减灰)
  3. 能够多路输入源控制,比如三块硬盘其中任何一块硬盘温度升高达到散热要求,那么都启动

而备选方案有如下这些方案:

  1. 恒速恒开
  2. 温控开关控制开启
  3. DC调速
  4. PWM调速

恒速恒开方案很明显满足不了我的需求,所以此方案最先排除。

温控开关控制开启方案简单,成本低,但问题在于温控开关的温控精度不准(一般在5度的误差范围),且只有开或不开的两个状态,转速无法调节,所以排除。

DC调速在之前的将便携冷热杯的风扇改成温控风扇文章中已经出现过,优点么就是稳定简单。但DC温控的缺点在:

  1. DC调速做不到停转。如果为了让风扇停转调低最低输出电压,那么在风扇起转电压左右的时候风扇会不稳定,出现抖动
  2. DC调速如果使用NTC的话,那么温控范围不容易做窄

温控范围不容易做窄的意思是,如果你想要30-60摄氏度范围内线性可控,那么它很容易做,但想在很窄的范围内(比如我希望硬盘温度,到40摄氏度的时候开启散热,到55摄氏度全速),那么这15摄氏度的温差的NTC阻值变化不足以让风扇在这个区间内实现0%-100%的调速。

所以方案最终只剩下一个PWM调速了。

淘宝上有不少类似的模块,几块钱到十几块钱不等。考察了一番后都放弃了,虽然它们的功能很完善(比如转速和温度可调神马的),但是在我这个场景下,它们还是显得不太够用,而且成本也颇高。

所以,最终我选择自己DIY。

选型

考虑到整个主机采用12V电源供电,于是风扇我选择了台达的EFB0812HHB风扇,标称是12V0.4A,四线转速可控风扇,这是一个标准的PWM风扇,尺寸8cm,刚好装在支架上。

风扇选好了,那温控呢?这时候我想到了以前买的Arduino。翻出来看了一圈后,我最终决定使用Arduino mini pro来作为控制板。

为了实现风扇的停转,还额外使用了一枚D882三极管来控制风扇电源,这是一枚30V3A的NPN三极管。

除此以外还需要电阻若干。

🤣现在当真啥芯片都是理财产品。这块Arduino板子是我五年前买的,当时价格是十块钱左右。今年年初都还是这个价格,组装这台机器的时候价格已经是十五块了,而写本文的时候再去瞄了两眼,发现价格已经是25块了。

电路

简易图纸如下(非专业人士,画的图粗糙,给点面子不要嘲笑哈)。

Arduino一共有8路的模拟AD输入,从A0一直到A7。根据这里的需要,使用的是A0~A5一共六路输入(分别是硬盘三路+固态硬盘两路+电源一路)。

温度测量采用NTC+上拉电阻来实现,选用的规格均为10KΩ。由于Arduino的AD模拟精度是10位的(也就是1024级),Arduino会根据模拟端口的输入电压读出一个0-5V ~ 0-1023 的映射数值。

根据NTC的温度特性,可知A0~A5的电压对温度的电压以及AD读数大概如下表所示:

预期设计的温度控制范围是40到52摄氏度,也就是温度达到40摄氏度的时候期望启动风扇散热,直到52摄氏度达到满速,而40摄氏度以下的时候,关闭风扇。根据上面的表格可知,我们当AD输入读数低于336的时候打开风扇、低于256的时候让风扇达到满速即可。

那风扇转速如何控制呢?自然是PWM。我们这里使用的是四线PWM风扇,除电源正负引线外,还有两根线,分别是转速感应及转速控制。对于一个风扇来说,一般4Pin插头,黑线是电源负极,红线(或挨着黑线的)是电源正极,第三根线是转速感应,而第四根线是PWM控制线。

如果不确定转速感应和PWM控制线也好办,风扇供电转起来后另外两根线分别对地短路下,哪个短路了转速很低哪个就是PWM控制线。

PWM控制是通过控制方波脉冲的占空比来实现的,对于PWM风扇来说,占空比从0%到100%,对应着转速从0%到100%。所以对地短路后相当于一个0%占空比的信号,自然恒定低速。

Arduino单片机有六个PWM输出口,参考下图。

可见六个PWM口分别是1/9/10/13/14/15这六个端口。我们三个风扇,意味着只用到其中三个PWM端口。后面需要的话可以再搞几个风扇来……

那要实现关断呢?就靠切断风扇电源了。这里选的是2SD882(不要问我为啥,我就是随便选的🤣),它是一枚NPN三极管,Ic是3A,足够这个风扇了。

B极通过一枚2K的电阻(限流)接到Arduino的数字输出引脚上。这个2K的阻值……也是拍脑袋的🤣,虽然有大致计算。使用的三极管为NPN管,hfe测了下大概在270,取Ic为0.5A(实际上风扇标称为0.4A),取饱和时Vbe0.7V,B极所需电流为 0.5A/270=1.85ma,则限流电阻大概阻值为 (高电平5v-Vbe0.7V/1.85ma)=2324KΩ,留点空间取了个2K。

LED为对应通道的启动指示,通过一个1KΩ的限流电阻到开关引脚上。

供电

Arduino的供电电压为5V。由于整台机器没有5V的供电,所以原来我还在琢磨着是不是得加个DC-DC的降压模块搞出来5V。后来想了想……这个NUC6的板子上有个USB2.0的接线座空着不用,我直接用它的5V不就好了……

💥Pro Mini的板子上有个RAW脚(参考上面的图),据说可以直接输入6-12V的电压,板载了降压芯片给单片机供电。但是事实是这个降压芯片很不靠谱……我的两个Pro Mini板子上的降压芯片都是从这个引脚上供电的时候莫名其妙烧了,还好单片机还是正常的。

风扇的电压是12V,这个就简单了,直接干在主供电上就好。

搭板子

画PCB?太麻烦了吧?本鱼还不会(主要是也还没学,以后再学)。

先用双面胶把Arduino和三极管直接贴在硬盘笼侧面(靠近风扇那边),然后直接开始搭棚(请忽略乱七八糟的布局和狗啃式的焊功,随便搞搞了,不讲究这些)。

💥💥注意 图中10KΩ电阻写成10Ω了,手动修正下,懒得重新搞图了。

💡 图中只有一路,因为我经过评估,感觉另外两路暂时不接温度也hold得住,后面再看了,需要再搭。另外上图中也没有风扇的指示LED,因为Pro Mini的板子引脚13自带了一枚指示LED,刚好用上,不用另接了。

NTC那边有三个,四根线,其中地线公用,另外三根线分别接一个10KΩ的NTC。

NTC用的是火柴头那种小的,用导热胶直接贴在硬盘钢壳上(远离风扇那一端,散热时这边是热端),再用704硅橡胶固定。

最后完成后大概样子是这样的。

程序

还好Arduino的程序简单。

void control(int* status, uint8_t ledPin, uint8_t fanPin, int val, int low, int high);

void setup() {
	// 设置各引脚模式
	pinMode(11, OUTPUT);
	pinMode(13, OUTPUT);
	pinMode(12, OUTPUT);
	pinMode(10, OUTPUT);
	pinMode(9, OUTPUT);
	pinMode(8, OUTPUT);

	// 全速运转保持三秒
	analogWrite(11, 255);
	analogWrite(10, 255);
	analogWrite(9, 255);
	digitalWrite(13, HIGH);
	digitalWrite(12, HIGH);
	digitalWrite(8, HIGH);

	delay(3000);

	// 关断风扇
	analogWrite(11, 0);
	analogWrite(10, 0);
	analogWrite(9, 0);
	digitalWrite(13, LOW);
	digitalWrite(12, LOW);
	digitalWrite(8, LOW);
}

long lastTempControlTime;
int fan1Status = 0, fan2Status = 0, fan3Status = 0;
int aGap = 20;

void loop() {
	long time = millis();

	if (time - lastTempControlTime > 500)
	{
		//500ms控制1次风扇
		lastTempControlTime = time;

		//硬盘		3路输入/1路输出
		//温度输入	A0/A1/A2
		//温度源		SATA HDD
		//低温		42(335)
		//高温		52(255)
		//LED		13
		//FAN PWM	11
		int temp = min(analogRead(A1), min(analogRead(A2), analogRead(A0)));
		control(&fan1Status, 13, 11, temp, 255, 335);

		//硬盘		2路输入/1路输出
		//温度输入	A3/A4
		//温度源		NVME SSD+SATA SSD
		//低温		52(250)
		//高温		70(150)
		//LED		12
		//FAN PWM	10
		temp = min(analogRead(A3), analogRead(A4));
		control(&fan2Status, 12, 10, temp, 150, 250);

		//电源		1路输入/1路输出
		//温度输入	A5
		//温度源		电源
		//低温		52(250)
		//高温		70(150)
		//LED		8
		//FAN PWM	9
		temp = analogRead(A5);
		control(&fan3Status, 8, 9, temp, 150, 250);
	}
}

void control(int* status, uint8_t ledPin, uint8_t fanPin, int val, int low, int high)
{
	if (*status == 0 && val >= high - aGap)
	{
		//如果当前关闭,且温度没有比最高值低一个gap值,则不改变当前状态
		return;
	}

	if (val > high)
	{
		*status = 0;
		analogWrite(fanPin, 0);
		digitalWrite(ledPin, LOW);
	}
	else if (val < low)
	{
		*status = 1;
		analogWrite(fanPin, 255);
		digitalWrite(ledPin, HIGH);
	}
	else
	{
		*status = 1;
		val = map(high - val, 0, high - low, 0, 255);
		digitalWrite(ledPin, HIGH);
		analogWrite(fanPin, val);
	}
}

为了防止风扇转速抖动,设定了每500毫秒检测一次温度。

中间有个aGap的设计,大概值是20,相当于2.5摄氏度。之所以设计了这个变量(其实是后面迭代出来的,因为发现了问题了嘛),是因为在测试中发现了一种情况,就是当温度在启动温度附近时,由于风扇一转读数就变,导致风扇会快速地在转和不转之间徘徊,导致抖动,一方面有噪音,一方面我觉得这样对风扇不好,所以设计了这么个变量。

这个变量会延迟启动,如原定在42摄氏度启动,则会延迟到44.5摄氏度启动,但是一旦启动,则会等到温度降回42摄氏度以下时才会关闭,从而解决这个风扇在临界温度时跳动的问题。

最后

最后的系统大概是这样的。

最后电源的温度大概在50-60摄氏度,其实还没有那块2.5G的有线网卡烫手,我也就懒得管了。

值得一提的是图上的USB3.0-SATA桥接模块我全部拆了外壳,因为我发现这个芯片其实还是蛮热的,所以为了长时间高温下的稳定工作,我把外壳都拆了,并给芯片加了一块小散热片。

喜欢 (15)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(7)个小伙伴在吐槽
  1. 其实,arduino有pid库的,可以参考一下控制风扇的时候用上。

    紫倩傻乎乎2024-11-03 10:14 回复
    • 嗯,不过这里要求不高,就将就了(其实现在我已经不这么玩了。。。)

      木魚2024-11-08 14:39 回复
  2. 高端玩家

    小天才2024-06-17 09:31 回复
  3. 可否贴出你的nas配置

    lengtong2021-09-22 11:28 回复
  4. 有3tb的固态硬盘吗?一般家用都是2tb和4tb,企业版有3.84tb的不过一般是u2接口。通风的话需要考虑风道,这个收纳箱的散热还是有点困难。3个同容量的机械+3个不同容量的固态+1个nvme,没做raid吗?

    kevin2021-08-24 00:22 回复
    • 1,没有,固态盘成本比较高,没上那么高容量的,而且主要是用来读写热数据的也不需要那么高的;2,通风还可以,这个风扇满速5w风量还是有点大的,而且大多数时候机械硬盘(存放冷数据)在休眠态,发热量没那么高;3,没有用raid,因为硬盘实际运行的时间不多(上电时间长就是)。

      木魚2021-08-24 10:48 回复
  5. 匪夷所思……太牛了~

    路过2021-08-12 10:47 回复