最近在使用arduino UNO开发板完成课程小作业。其中一个要求设计一个电风扇控制系统,要求能够通过PWM调节风扇的转速。期间搜索了许多例程和方法,但受限于器件,效果不好。最后融合了两种方法,成功实现控制功能,因此在这里总结出来。
PWM原理
根据arduino官方社区的定义,PWM即脉冲宽度调制,是一种通过数字控制方式获得模拟结果的技术。数字控制用于创建方波,即在on和off之间切换的信号。通过改变信号处于ON状态时间和处于OFF状态时间的比例,这种模式可以模拟板子从Vcc(对UNO是5V)到off(GND,即0V)的所有电压。“ON”的持续时间称为 脉冲宽度。更改或调制脉冲宽度可以获得变化的模拟值。如果用LED灯足够快地重复此开关模式,效果相当于用一个介于0~Vcc之间的稳定电压,控制着LED灯的亮度。
0%占空比的图中,绿线代表固定时间段。如果arduino的PWM频率为500Hz,则该段持续时间或周期为2毫秒。analogWrite()函数的写入范围是0-255,那么analogWrite(255)代表请求100%的占空比(始终打开),而analogWrite(127)则是50%的占空比(一半时间)。
实验器件
器件 | 数目 |
---|---|
Arduino UNO及USB下载线 | 1 |
ULN2003 | 1 |
大面包板 | 1 |
直流电机 | 1 |
小风扇 | 1 |
4.7kΩ电阻 | 2 |
四角按键开关 | 2 |
杜邦线 | 若干 |
这里在附上这些器件的官方指南和工作原理的说明。
- ULN2003
是一种高压大电流的共发射极达林顿晶体管数组集成电路,内含7组达林顿对管,每组对管的电流容量是500mA,输出的电压最高50V。该集成电路还集成了7只共阴极形式连接的续流二极管,用于电感性负载的开关动作的电流续流。ULN2003A常见的封装形式有PDIP、SOIC、SOP或TSSOP。
实际操作时,ULN2003驱动板的IN1连接arduino的数字IO口9,供电口分别连接arduino的5V和gnd口。步进电机驱动部分最上方的接口连接直流电机。
- 四角按键开关怎么接线
- 直流电机
直流电机两端无正负之分。
功能描述
Arduino的板载输出电流是不够的,所以我们得需要借助ULN2003驱动板来实现。
通过加速和减速按键,能够控制负载/电机两端电压,改变电机转速。
PWM频率一定时,脉冲宽度越大,占空比越大,提供给电机的平均电压越大,电机转速就越高。反之脉冲宽度越小,则占空比越小,提供给电机的平均电压越小,电机转速就低。
接线图/原理图
实现代码
代码及注释如下,可供参考。
// 定义引脚
const int buttonPin1 = 7; //定义buttonPin1引脚为7,加速按键
const int buttonPin2 = 2; //定义buttonPin2引脚为8,减速按键
const int motorPin = 9; //定义motorPin引脚为9,驱动电机
int buttonState1 = 0;
int buttonState2 = 0;
int outputValue = 0;
int a1 = 0; //占空比,这里取0-255
void setup() {
//输入输出状态定义
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
pinMode(motorPin, OUTPUT);
Serial.begin(9600); //定义串口波特率
}
void loop() {
// 串口监视器打印按键状态和电机转速
buttonState1 = digitalRead(buttonPin1);
buttonState2 = digitalRead(buttonPin2);
Serial.print("加速按钮=");
Serial.println(buttonState1);
Serial.print("减速按钮=");
Serial.println(buttonState2);
delay(1000);
outputValue=analogRead(motorPin); //outputValue:0~1023
Serial.print("output=");
Serial.println(outputValue);
if(outputValue<=500){
if(buttonState1 == HIGH) { //如果加速按键按下
a1 += 20; // a1的变化数值可以根据实际需求调整
analogWrite(motorPin, a1); //将a的值赋给motorPin
delay(1000); //延迟1s
}
if(buttonState2 == HIGH) { //如果减速按键按下
a1 -= 20;
analogWrite(motorPin, a1);
delay(1000);
}
}
}
结果
程序烧录到arduino板子上后,打开串口监视器,同时随机按下按键,观察风扇转动情况与串口监视器读数。
总的来说,编程可以实现按键控制风扇转速增加/减小。
- 但是由于代码本身没有按键去抖动的保护,按下按键后,作用到电机的结果有延迟,或者速度控制不是很稳定。后续可以进一步改进,提高系统稳定性。
- analogRead()读取到的电机接口状态在0-1023之间,尽管初始化时已经通过analogWrite()将状态设为0,但是一开始读取到的接口状态并非0而是334左右,这意味着一开始作用到电机上的电压约为384/1024*5=1.631V,可能是ULN2003驱动板的作用,这个现象还可以继续深入探索。