Arduino制作可调速电风扇

July 3, 2016
DIYComputerArduino

暑假到了,随之而来的是炎热的天气,这篇文章将会教大家使用一个电脑主板上淘汰下来的CPU散热风扇来制作一个电扇。

这个风扇可以通过按下一个开关来进行开,关,和调速。

用到的工具

  • 废旧的CPU风扇(我的是4pin的)
  • Arduino UNO
  • 面包板
  • 电阻(1-10千欧)
  • 12V 电源
  • 电脑(用来编程)
  • 按钮开关

既然是第一次在博客上发关于Arduino的文章,那么先来介绍一下吧。

Arduino 是一款开源的电子平台点击进入官网
可以使用这个硬件来进行物联网方面的DIY,制作飞行器,3D打印机等等都可以用到Arduino,售价低廉,某宝上20元就能拿下,总之,只有你想不到,没有Arduino做不到,今天的这个文章只会初步的来使用Arduino。

既然要做个风扇,那么首先要让这个风扇可以动起来,根据经验,任何电器只要给正负极通上电就可以工作,所以先来试一下。首先,这个风扇的正常工作电压是12V,坏消息是我手上并没有这么高电压的电源,只有一个10V输出的电源(一个笔记本电脑电池),不过没有关系,先凑合用吧。不过正负极怎么接呢?看下一般4pin
CPU风扇的规格:

Pin Name Color
1 GND black
2 +12VDC yellow
3 FAN_TACH green
4 FAN_CONTROL blue

所以首先把,电源正极和负极分别接到,pin2 和 pin1 上,风扇就可以工作了。

注:这样将导线直接接入电池两级的做法很危险,请不要模仿

既然大概的功能实现了,接下来就要开始调整转速了。通常调整电机转速使用了PWM技术,下面来科普一下PWM,

  • PWM

PWM(Pulse-width
modulation)脉冲宽度调制,这个技术可以利用微处理器的数字输出来对模拟电路进行控制。简单地说,PWM信号是一个方形波,在方波中,波峰代表高电平,波谷代表低电平,虽然这个方形波的频率是固定的,但是高电平的时间除以总时间的值是可以从0到100%改变的,这个值叫做
占空比 。 通过控制占空比,就可以对电路进行进一步控制。

  • Duty Cycle(占空比)

占空比就是一个脉冲周期内高电平所在整个周期中占得比例,比如一个脉冲周期10秒,其中9秒是高电平,那么占空比就是90%。具体点的话:如果一个脉冲周期由10个信号(0或1)组成,那么1111100000信号就代表50%的duty
cycle,因为整个信号由5个1,5个0组成.

  • PWM用途

PWM的用途很广,举几个例子

  • 调整LED亮度(在最高输出电压恒定的时候)
  • 控制电机,舵机转速(使用很广泛)
  • 生成声音信号
  • 调整信号

在Arduino中,很容易就能实现PWM,只要调用 analogWrite(pin,dutyCycle)
函数就行,其中,dutyCycle的值是从0到255中的任意一个,pin只能是PWM专用PIN(3,5 ,6,9, 10
或者11)。虽然这个函数已经提供了一个简单的方法来控制PWM,但是还不能通过频率来控制,不过对于这个项目来说够用了。想要更深层次的控制,可以使用ATmega的PWM寄存器来直接控制(Arduino的ATmega
168P/328P芯片拥有3个PWM计时器,可以控制6个PWM输出,通过这些可以实现比 analogWrite() 函数更强大的功能)

  • 调速按钮

知道了PWM,的功能与用法之后,现在开始做开关,这个开关充当调速的功能。

在这里使用一个很常见的四角开关:四个角分别为A,B,C,D,平时A,B是连通的,C,D是连通的,当开关被按下后,ABCD四个角就都会被连通。

通过以下方式接线,5V输出接AB脚,A5 pin接CD脚,A5pin可以读到当前电路的电压,当开关按下后,A5的度数会增高,从而知道开关被按下。

电路搭建好了之后测试试一下,编写以下代码:

其中,analogRead(int
pin),是模拟输入函数,他把5V电压分为1024份,也就是说,输出值为0-1023,我设定当这个值大于1000,也就是4.8V差不多的时候判定为开,否则视为开关为关。

  1. void setup(){
  2. Serial.begin(9600);
  3. }
  4. void loop(){
  5. handleSwitch();
  6. }
  7. void handleSwitch(){
  8. int i;
  9. i=analogRead(5); //读取5号pin
  10. if(i>1000){
  11. Serial.println("High");
  12. } else{
  13. Serial.println("Low");
  14. }
  15. }

之后运行一下程序,看一下串口监视器,情况并不是我们想象的那样乐观:

在输出结果里居然有很多High,可是我并没有按下开关,这是由于外界信号对开关的干扰导致的。

需要并联一个 下拉电阻 来克服这个问题

  • 下拉电阻

在开关的接口与GND之间接一个1K-10K Ω的电阻。其作用是当外界有干扰源的时候(不确定信号),在断开状态下,这个信号会通向GND从而被被电阻消耗掉。

这样连接电阻后,再运行代码,会发现一直输出Low,按下时输出High,没有干扰问题了。

之后就可以去连接电扇了,CPU风扇的Pin 1,Pin2,还是连接电池的正极,负极,pin 3,连接到Arduino的Pin 6, Pin 4连接到
Arduino的Pin 3 。我又加了3个LED等分别代表低档,中档,高档三个档位的指示灯。(图中的电机是我随便放的部件,代指CPU风扇)

代码如下:

  1. int lastStatus = 0; //储存上一次开关的状态
  2. int counter = 0; //计数器
  3. int fanPulse = 6; //风扇数据读取pin
  4. unsigned long pulseDuration;
  5. int pin_low_speed_led = 13;
  6. int pin_mid_speed_led = 12;
  7. int pin_high_speed_led = 11;
  8. void setup(){
  9. pinMode(pin_low_speed_led, OUTPUT);
  10. pinMode(pin_mid_speed_led, OUTPUT);
  11. pinMode(pin_high_speed_led, OUTPUT);
  12. Serial.begin(9600);
  13. pinMode(fanPulse, INPUT);
  14. digitalWrite(fanPulse,HIGH);
  15. counter++;
  16. shift();
  17. }
  18. void loop(){
  19. while(1)
  20. {
  21. handleSwitch();
  22. }
  23. }
  24. void updateLED(){ //更新led指示灯
  25. switch(counter%3){
  26. case 0: digitalWrite(pin_low_speed_led, HIGH);digitalWrite(pin_mid_speed_led, LOW);digitalWrite(pin_high_speed_led, LOW);break;
  27. case 1: digitalWrite(pin_mid_speed_led, HIGH);digitalWrite(pin_high_speed_led, LOW);digitalWrite(pin_low_speed_led, LOW);break;
  28. case 2: digitalWrite(pin_high_speed_led, HIGH);digitalWrite(pin_mid_speed_led, LOW);digitalWrite(pin_low_speed_led, LOW);break;
  29. }
  30. }
  31. void handleSwitch(){ //处理开关
  32. int i;
  33. i=analogRead(5);
  34. if(i>1000){
  35. if (lastStatus == 0){
  36. // Serial.println("High");
  37. counter++;
  38. shift();
  39. }
  40. lastStatus = 1;
  41. } else{
  42. if (lastStatus == 1){
  43. // Serial.println("Low");
  44. }
  45. lastStatus = 0;
  46. }
  47. delay(10);
  48. }
  49. void shift(){ //换挡
  50. Serial.println("Current Fan Speed Mode:");
  51. switch(counter%3){
  52. case 0: Serial.println("LOW");analogWrite(3,0); delay(500);readPulse();break;
  53. case 1: Serial.println("MID");analogWrite(3,150); delay(500);readPulse();break;
  54. case 2: Serial.println("HIGH"); analogWrite(3,255);delay(500);readPulse();break;
  55. }
  56. updateLED();
  57. }
  58. void readPulse() { //读取相关信息
  59. pulseDuration = pulseIn(fanPulse, LOW);
  60. double frequency = 1000000/pulseDuration;
  61. Serial.print("pulse duration:");
  62. Serial.println(pulseDuration);
  63. Serial.println("");
  64. }

之后烧录程序,风扇就可以调速了,每次按下按钮就会调速,不同的指示灯会根据不同的速度亮。

好了,这次就介绍到这里,不过CPU风扇的扇叶是反的,必须对着底部才能吹到风哦~

我的博客MikeTech app现已登陆iPhone和Android

iPhone版下载
Android版下载

Comments

July 21, 2018 at 10:52 am

There are no comments

keyboard_arrow_up