好久没有更新了,家里实在太乱,最近趁着618活动,买了一堆收纳抽屉和置物架,把家里彻底收拾了一下,然后客厅就成了这个奇葩样子,注孤生的节奏了。
话不多说,夏天到了,天气逐渐热起来,风扇成了必不可少的消暑利器。
本文主要介绍两种基于Arduino的风扇自动调速方案,使用的是5V的USB风扇,物美价廉还省电。
方案一是通过舵机控制旋钮变压器实现调速,方案二通过脉冲宽度调制(PWM)实现调速。
名称 | 数量 | 淘宝单价 |
---|---|---|
Arduino UNO | 1 | 15 |
USB风扇调速器 | 1 | 6 |
DH11温湿度传感器 | 1 | 4 |
SG90S舵机 | 1 | 7.5 |
红外接收模块加遥控器 | 1 | 3.3 |
所用零件均可在淘宝买到,价格时有波动。
思路是通过DH11温湿度传感器测量温度,根据温度控制舵机的角度,舵机的转轴与USB风扇调速器的旋钮连接,带动旋钮转动,进而控制风扇的输入电压,实现转速控制。
此外,增加了红外控制,用于远程开关风扇,切换模式。
需要红外控制模块和DH11温湿度传感器的库,代码及库的下载链接在文末。
3种红外信号分别对应全开、全关和自动模式。
自动模式会根据室温调节风扇的转速。
#include //调用dh11温湿度传感器的库
#include //调用红外控制的库
#include //调用舵机控制的库
dht DHT;
Servo servo;
#define RECV_PIN 9 //定义红外接收器针脚
IRrecv irrecv(RECV_PIN);
decode_results results;
#define dataPin 10 //定义温湿度传感器针脚
int servoPin = 7; //定义舵机针脚
char value; //红外接收器接收的数值
float t; //温湿度传感器测量的温度数值
int a = 0;
int b = 0; //a、b用于切换模式
void setup() {
irrecv.enableIRIn();
servo.attach(servoPin);
servo.write(0);
delay(1000);
servo.detach();
//Serial.begin(9600);
}
void loop() {
if (irrecv.decode(&results)) {
if (results.value == 16753245) {
a = 1;
}
if (results.value == 16736925) {
a = 0;
b = 0;
}
if (results.value == 16769565) {
a = 0;
b = 1;
}
irrecv.resume();
}
if (a == 0 && b == 0) {
servo.attach(servoPin);
servo.write(0);
delay(1000);
servo.detach(); //关闭风扇
}
if (a == 0 && b == 1) {
servo.attach(servoPin);
servo.write(180);
delay(1000);
servo.detach(); //打开风扇
}
if (a == 1) {
int readData = DHT.read11(dataPin);
t = DHT.temperature;
if (t <= 26) {
servo.attach(servoPin);
delay(1);
servo.write(0);
delay(500);
servo.detach(); //自动模式低于26度关风扇
}
else if (t > 26 && t <= 28) {
servo.attach(servoPin);
delay(1);
servo.write(60);
delay(500);
servo.detach(); //自动模式26-28度一档
}
else if (t > 28 && t <= 30) {
servo.attach(servoPin);
delay(1);
servo.write(120);
delay(500);
servo.detach(); //自动模式28-30度二档
}
else if (t > 30 && t <= 40) {
servo.attach(servoPin);
delay(1);
servo.write(180);
delay(500);
servo.detach(); //自动模式高于30度全开
}
//Serial.println(t);
delay(1000);
}
}
脉冲宽度调制(pulse width modulation)通过快速打开和关闭电源来调整发送到电子设备的平均电压值。
平均电压取决于占空比,占空比是指在一个脉冲循环内,通电时间相对于总时间所占的比例。
可以通过Arduino的脉宽调制输出连接L298N电机驱动模块,并通过控制脉宽调制输出来控制电机的速度。
通过下图可以看出,输入电压为12V,当占空比为0.25时,平均电压值为3V;当占空比为0.5时,平均电压值为6V。
名称 | 数量 | 淘宝单价 |
---|---|---|
Arduino UNO | 1 | 15 |
L298N电机控制模块 | 1 | 6 |
DH11温湿度传感器 | 1 | 4 |
所用零件均可在淘宝买到,价格时有波动。
仍然是通过DH11温湿度传感器测量温度,然后根据温度计算占空比,改变L298N电机控制模块的平均输出电压,实现转速控制。
需要L298N电机控制模块和DH11温湿度传感器的库,代码及库的下载链接在文末。
通过map
函数将室温转换为占空比。
motorSpeed = map(t, tempMin, tempMax, speedMin, speedMax);
以本文为例
motorSpeed = map(t, 28, 50, 30, 100);
上文已经交代,占空比是指在一个脉冲循环内,通电时间相对于总时间所占的比例。
即温度从28变化到50,占空比从0.3变化到1。
#include //调用L298N模块的库
#include //调用dh11温湿度传感器的库
dht DHT;
#define IN1 2
#define IN2 4
#define ENA 3 //必须是带有~符号的PWM针脚
const int CCW = 2; //反转
const int CW = 1; //正转
const int motorDirection = CW;
#define motor1 1
Robojax_L298N_DC_motor motor(IN1, IN2, ENA, true);
#define dataPin 10 //定义温湿度传感器针脚
float t; //温湿度传感器测量的温度数值
const float tempMin = 28.0; //温度下限
const int speedMin = 30; //转速下限
const float tempMax = 50.0; //温度上限
const int speedMax = 100; //转速上限
int motorSpeed; //根据温度计算出的转速
void setup() {
motor.begin();
}
void loop() {
tempToSpeed();
motor.rotate(motor1, motorSpeed, motorDirection);
delay(500);
}
void tempToSpeed()
{
float readData = DHT.read11(dataPin);
t = DHT.temperature;
motorSpeed = map(t, tempMin, tempMax, speedMin, speedMax);
if (t < tempMin)
{
motorSpeed = 0;
motor.brake(1); //温度低于下限停止
}
if (t > tempMax)
{
motorSpeed = 100; //温度高于上限全开
}
}
本人菜鸟,发现错误,欢迎指出,谢谢大家。