Arduino利用红外传感器控制风扇原理
在上篇文章:如何使用TV遥控器和Arduino传感器来控制电器发布后,一些朋友发邮件询问PWM控制电路的相关元件参数和工作原理,本文将对相关知识和电路配置做进一步讨论和测试。
电路元件介绍
一、TV遥控器
本次测试采用的电视遥控器为东芝LCD电视遥控器,型号为:CT-90301。具体如图所示:

二、红外传感器TSOP34838

TSOP34838是 Vishay 公司推出的一款用于红外遥控系统的小型红外接收模块。其内部封装了二极管、前置放大器和红外滤波器,它解调后的输出信号可以直接连接到微处理器进行解码。TSOP34838的主要电气特性如下:
- 载波频率为38KHz;
- 方向角为 45° ;
- 供电电压范围 2.5V~5.5V;
- 工作电流450µA;
- 工作距离最大 45m;
- 工作温度范围 -25℃~ 85℃;
- 检测灵敏度 0.08mW/m²;
- 遥控编码:RC-5, RC-6, Panasonic, NEC, Sharp, r-step, Thomson RCA。
三、Arduino UNO

本次采用的Arduino板为常见的UNO,从上图可以看到UNO的3、5、6、9、10、11针脚是PWM针,但由于10和11针同时兼具SPI引脚功能,因此为了预留电路的扩展性,不建议采用。
四、测试电路图和配套元件

除了主要的CT-90301遥控器、TSOP34838红外传感器和Arduino UNO外,电路还需要一些配套元件才能完成工作,R1为1K电阻,Q1采用9013 NPN型三极管,C1采用1uf / 16V 电解电容,D1采用的是1N4007普通整流二极管,12V风扇和12V电源。如果采用电脑3 PIN散热风扇,其引脚判断方式为,风扇插头缺口向上,插孔面对自己,3孔从左到右分别为GND、+12V和sense。
电路工作原理
从电路图可知,电路的工作原理为:当TSOP34838接收到红外信号后,将信号输出Arduino UNO的D8,然后信号经过Arduino的解码和编码处理后,Arduino通过D6脚输出PWM信号至风扇控制电路。风扇电路采用9013三极管进行开关控制,当9013的基极为高电平时(PWM信号高电平),集电极和发射极导通风扇工作,当9013的基极为低电平时(PWM信号低电平),集电极和发射极截止风扇不工作。这样我们就可以通过调整PWM信号的占空比实现对风扇转速的控制了。PWM信号控制可阅读: 什么是PWM 这篇文章。
读取CT-90301遥控键值
读取遥控键值的方法请参阅:如何使用TV遥控器和Arduino传感器来控制电器,这里不再重复。CT-90301遥控器的部分键值读取结果如下:
2FD48B7 电源开关
2FD807F 1键
2FD40BF 2键
2FD58A7 音量+
2FD7887 音量-
2FDD827 频道+
2FDF807 频道-
2FDC23D 退出
2FD12ED 红
2FD926D 绿
2FD52AD 黄
2FDD22D 蓝
控制代码
代码中将使用遥控器的红键作为风扇启动键,当按下红键风扇将全速运行,即PWM信号占空比为100%;绿键为停止键;黄键为提高转速;蓝键为降低转速。
#include <IRremote.h> int RECV_PIN = 8; // IR Receiver - Arduino Pin Number 8 int pwmPin = 6; // Arduino Pin Number 6 to the Base of the Transistor int pwmValue; IRrecv irrecv(RECV_PIN); decode_results results; void setup() { Serial.begin(9600); irrecv.enableIRIn(); // Start the receiver pinMode( pwmPin, OUTPUT); pwmValue = 0; // Starts the program with turned off motor } void loop() { if (irrecv.decode(&results)) { analogWrite(pwmPin, pwmValue); if (results.value == 0x2FD12ED) { // PLAY Button pwmValue = 255; // 100% Duty Cycle | Max Speed } if (results.value == 0x2FD926D) { // STOP Button pwmValue = 0; // 0% Duty Cycke | Turned off } if (results.value == 0x2FD52AD) { // FORWARD Button if(pwmValue <= 250){ pwmValue = pwmValue + 5; // Increases the Duty Cycle of the PWM Signal delay(20); } } if (results.value == 0x2FDD22D) { // BACKWARD Button if(pwmValue >= 15){ pwmValue = pwmValue - 5; // Decreases the Duty Cycle of the PWM Signal delay(20); } } Serial.print("PWM值="); Serial.print(pwmValue); Serial.print(" 遥控键值="); Serial.println(results.value, HEX); irrecv.resume(); // Receive the next value } delay(100); }
串口输出如下图:
