一、设计目的
1.熟悉并掌握舵机、直流电机的功能与编程控制方法;
2.熟练掌握红外遥控器的控制原理与按键控制基本方法;
3.通过项目设计实验电路搭建与程序编写,熟练掌握Arduino IDE编程基础,提高理论联系实际、编程应用的实践能力。
二、设计要求
设计任务:
以Arduino UNO通用开源软硬件台为基础,用红外遥控器、舵机、直流电机等设计一个原型电风扇。
红外遥控器电风扇,按键实现的基本功能:(1)电风扇的开、关;(2)弱、中、强风速档的选择;(3)风速大小的连续调节;(4)风扇正传、反转的转向控制。
三、设计原理
1.舵机
(1)舵机结构
舵机是一种位置(角度)控制的直流电机驱动器,主要用于位置、角度等定位与变化的控制系统。舵机主要由外壳、电路板、马达、齿轮与位置检测器组成,舵机是一种俗称,其实是一种伺服直流电机。
普通舵机有3根线:GND(黑)、VCC(红)、Signal(黄)。电机驱动电流较大,建议为舵机单独供电。
(2)舵机原理
控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。
以180度角度伺服为例,那么对应的控制关系:
0.5ms--------------0度;
1.0ms------------45度;
1.5ms------------90度;
2.0ms-----------135度;
2.5ms-----------180度;
(3)舵机的PWM信号控制
舵机为随动机构,当其未转到目标位置时,将全速向目标位置转动;当其到达目标位置时,将自动保持该位置。由于采用8 为CPU 控制,所以控制精度最大为256 份。目前经过实际测试和规划,分了250 份。将0—185°分为250 份,每份0.74 度。控制所需的PWM 宽度为0.5ms—2.5ms,宽度2ms。2ms÷250=8us;所以得出:PWM 信号= 1度/8us;
(4)舵机库函数ServoServo类
成员函数:
attach(PIN)//连接舵机的接口,接数字接口
write(PWM)//设定舵机转动角度,可设定范围0-180
writeMicroseconds(us)//设定舵机PWM的语句,以微秒为单位
read()//读取舵机转动角度的值,理解为读取最后一条write()命令中的值
attached(PIN)//判断参数是否发送到舵机连接的接口
detach(PIN)//断开与舵机连接的接口
2.直流电机
直流电机原理
直流电机是指能将直流电能转换成机械能或将机械能转换成直流电能的旋转电机。它是能实现直流电能和机械能互相转换的电机。当它作电动机运行时是直流电动机,将电能转换为机械能;作发电机运行时是直流发电机,将机械能转换为电能。
PWM控制
直流电机使用PWM技术,通过打开和关闭高电平电源信号来控制施加到直流电机的电压的平均值率。直流电机的平均电压将取决于PWM信号的周期。
3.ULN2003驱动
ICULN2003是大电流驱动阵列,多用于单片机、智能仪表、PLC、数字量输出卡等控制电路中。可直接驱动继电器等负载。输入5V TTL电平,输出可达500mA/50V。ULN2003是高耐压、大电流达林顿陈列,由七个硅NPN达林顿管组成。
MCU信号 驱动信号
输入 → 输出
引脚1:→引脚16
引脚2:→引脚15
引脚3:→引脚14
引脚4:→引脚13
引脚5:→引脚12
引脚6:→引脚11
引脚7:→引脚10
引脚8接地。
引脚9:内部7个续流二极管负极的公共端,各二极管的正极分别接各达林顿管的集电极。用于感性负载时,该脚接负载电源正极,实现续流作用。
四、硬件设计
1.舵机
2.直流电机
3.ULN2003驱动
4.红外遥控电风扇
五、软件设计
程序模块代码
(1)舵机控制程序
舵机:电位器控制角度
#include<Servo.h>
Servo myServo;
int value;
void setup()
{
myServo.attach(8);
myServo.write(0);
}
void loop()
{
value=analogRead(8);
value=map(value,0,1023,0,179);
myServo.write(value);
delay(10);
}
(2)电机控制程序
直流电机
#define dwqPin A0
#define djPin 3
int sensorValue=0;
int djSpeed=0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
sensorValue=analogRead(dwqPin);
djSpeed=map(sensorValue,0,1023,0,255);
Serial.print("sensorValue=");
Serial.println(djSpeed);
analogWrite(dwqPin,djSpeed);
delay(100);
}
(3)ULN2003驱动
ULN2003驱动:控制角度正反
#include<Servo.h>
Servo myServo;
int value=0;
void setup()
{
myServo.attach(8);
myServo.write(0);
}
void loop()
{
for(value=0;value<180;value++)
{
myServo.write(value);
delay(10);
}
for(value=180;value>=1;value--)
{
myServo.write(value);
delay(10);
}
}
(4)红外遥控程序
红外遥控电风扇
#include <IRremote.h>
#include <Servo.h>
#define dwqPin A0
#define djPin 3
int sensorValue=0;
int djSpeed=0;
Servo myservo; //舵机起个名字
// twelve servo objects can be created on most boards
int pos = 0; // variable to store the servo position
#define MAX 22
int RECV_PIN =11; //定义红外接收模块输出口接arduino数字引脚11
IRrecv irrecv(RECV_PIN);
decode_results results;
//Car mp3编码
unsigned long rremote_code[MAX] = {
0xFFA25D,0xFF629D,0xFFE21D,//CH- CH CH+
0xFF22DD,0xFF02FD,0xFFC23D,//PREV NEXT PLAY
0xFFE01F,0xFFA857,0xFF906F,//VOL- VOL+ EQ
0xFF6897,0xFF9867,0xFFB04F,// 0 100+ 200+
0xFF30CF,0xFF18E7,0xFF7A85,// 1 2 3
0xFF10EF,0xFF38C7,0xFF5AA5,// 4 5 6
0xFF42BD,0xFF4AB5,0xFF52AD, // 7 8 9
0xFFFFFFFF//长按
};
//Car mp3对应的字符串
String rremote_string[MAX] = {
"CH-","CH","CH+",
"PREV","NEXT","PLAY/PAUSE",
"VOL-","VOL+","EQ",
"0","100+","200+",
"1","2","3",
"4","5","6",
"7","8","9",
"longPress"
};
String ServoEn="OFF";
void getRemoteDo();
void ServoCtr();
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); //初始化红外遥控
pinMode(3,OUTPUT);
myservo.attach(8);
void loop()
{
ServoCtr();
sensorValue=analogRead(dwqPin);
djSpeed=map(sensorValue,0,1023,0,255);
Serial.print("sensorValue =:");
Serial.println(djSpeed);
analogWrite(djPin,djSpeed);
delay(1000);
}
void ServoCtr()
{
for(pos = 0; pos <= 90; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
getRemoteDo();
while(ServoEn=="OFF")
{
getRemoteDo();
}
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 90; pos>=0; pos-=1) // goes from 180 degrees to 0 degrees
{
getRemoteDo();
while(ServoEn=="OFF")
{
getRemoteDo();
}
myservo.write(pos); // tell servo to go to position in variable'pos'
delay(15); // waits 15ms for the servo to reach the positin
}
}
/*判断红外接收信息*/
void getRemoteDo()
{
String codeString;
if (irrecv.decode(&results))
{
//打印字符串
codeString = getRremoteString(results.value);
if(codeString.length()!=0)
Serial.println(codeString);
irrecv.resume(); // 接收下一个值
}
if (codeString=="CH")
{
Serial.println("ok");
digitalWrite(3,LOW);
}
if (codeString=="CH+")
{
Serial.println("ok_");
digitalWrite(3, HIGH);
}
if (codeString=="PLAY/PAUSE")
{
ServoEn="On";
}
if (codeString=="NEXT")
{
ServoEn="OFF";
}
}
/**
* 解析红外编码并返回对应的字符串
*/
String getRremoteString(unsigned long code){
String rremotestring = "";
int i = 0;
for(i = 0;i<MAX-1;i++){
if(code == rremote_code[i]){
break;
}
}
//过滤掉长按
if(i==MAX-1) return "";
else return rremote_string[i];
}
五、系统调试
略。
六、实验结果
略。
七、实验总结
通过本次实验,我到了很多的知识,用红外遥控器、舵机、直流电机等设计一个原型风扇。熟悉并掌握舵机、直流电机的功能与编程控制方法;熟练掌握红外遥控器的控制原理与按键控制基本方法;通过项目设计实验电路搭建与程序编写,熟练掌握Arduino IDE编程基础。学会了红外遥控电风扇的线路连接和代码编写。
八、思考
1.智能家居以成为家庭智能化发展与应用的大趋势。你了解智能家居有哪些具体场景应用?能举例分析其中的控制原理吗?