在之前的《盘一下最近收到的二手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风扇。
由于风扇么,大家懂的,还是有声音的,所以我对风扇做出了如下的设计要求:
- 不需要转的时候不转(比如机械硬盘都在休眠中,发热不高,没有必要散热)
- 需要的时候以最低要求转(能控制住温度即可,转速越低越好,省电+降噪+减灰)
- 能够多路输入源控制,比如三块硬盘其中任何一块硬盘温度升高达到散热要求,那么都启动
而备选方案有如下这些方案:
- 恒速恒开
- 温控开关控制开启
- DC调速
- PWM调速
恒速恒开方案很明显满足不了我的需求,所以此方案最先排除。
温控开关控制开启方案简单,成本低,但问题在于温控开关的温控精度不准(一般在5度的误差范围),且只有开或不开的两个状态,转速无法调节,所以排除。
DC调速在之前的将便携冷热杯的风扇改成温控风扇文章中已经出现过,优点么就是稳定简单。但DC温控的缺点在:
- DC调速做不到停转。如果为了让风扇停转调低最低输出电压,那么在风扇起转电压左右的时候风扇会不稳定,出现抖动
- 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一共有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
),取饱和时Vbe
为0.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不就好了……
风扇的电压是12V,这个就简单了,直接干在主供电上就好。
搭板子
画PCB?太麻烦了吧?本鱼还不会(主要是也还没学,以后再学)。
先用双面胶把Arduino和三极管直接贴在硬盘笼侧面(靠近风扇那边),然后直接开始搭棚(请忽略乱七八糟的布局和狗啃式的焊功,随便搞搞了,不讲究这些)。
💥💥注意 图中10KΩ电阻写成10Ω了,手动修正下,懒得重新搞图了。
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桥接模块我全部拆了外壳,因为我发现这个芯片其实还是蛮热的,所以为了长时间高温下的稳定工作,我把外壳都拆了,并给芯片加了一块小散热片。
其实,arduino有pid库的,可以参考一下控制风扇的时候用上。
嗯,不过这里要求不高,就将就了(其实现在我已经不这么玩了。。。)
高端玩家
可否贴出你的nas配置
有3tb的固态硬盘吗?一般家用都是2tb和4tb,企业版有3.84tb的不过一般是u2接口。通风的话需要考虑风道,这个收纳箱的散热还是有点困难。3个同容量的机械+3个不同容量的固态+1个nvme,没做raid吗?
1,没有,固态盘成本比较高,没上那么高容量的,而且主要是用来读写热数据的也不需要那么高的;2,通风还可以,这个风扇满速5w风量还是有点大的,而且大多数时候机械硬盘(存放冷数据)在休眠态,发热量没那么高;3,没有用raid,因为硬盘实际运行的时间不多(上电时间长就是)。
匪夷所思……太牛了~