arduino pro mini 自动控制吊扇
本帖最后由 yenan1001 于 2014-9-14 01:50 编辑家里吊扇的拉绳被熊孩子弄断了。
想了几天,决定换个arduino+继电器作为风扇换挡开关。
拆开风扇,发现里面控制转速的就是一个电容块,里面集成了三种不同的电容。通过不同的电容值对交流电限流来控制转速。就好像电阻之于直流电。
猜测着画了个原理图。
决定用arduino pro mini 和一个四路继电器控制转速。
外加人体感应器来自动关闭吊扇。
触发开关不打算用实体开关,而是用红外开关。
实现的功能和原来一样,有触发就打开吊扇,再有触发就换一档。
原装的换挡顺序是 停-最快-中等-最慢-停。因为通常都是用最慢。所以程序设置就自动控制风扇换挡到最慢。
原来打算用中断的。可是红外开关触发一次会发送很多抖动到中断。不想用电容啥的了,就算了。
程序很简单。没想到最困扰我的是对自然光的滤波。白天太阳强烈的时候,就会触发红外开关。所以整个程序有一部分都在解决这个问题。
到现在也没有完全搞定。吊扇偶尔还是会发疯。
***我在四楼放了一个很好的解决方案。要试试看。***
/*
This code is to control the fan to tune the speed and turn on.
当风扇停止时,触动一次开关会顺次打开3档-停五秒-2档-停五秒-一档。
如果在五秒停顿时间内再次触发,将会停在当前档位。
如果风扇在某一档运行,触发开关会降一档。
LED颜色:蓝色-2档;绿色-3档;红色-1档
成功2014/5/8
*/
#include <avr/wdt.h>//看门狗头文件
boolean on = LOW;//both relay and LED low is on
boolean off = HIGH;
int speed = 0;
# define brown_line10
# define gray_line 4
# define purple_line 5
# define led_red 6
# define led_green 7
# define led_blue 8
# define body_sensor 11
# define control 3
void setup() {
//attachInterrupt(1, speed_change, FALLING); //pin 3
//Serial.begin(9600);
wdt_enable(WDTO_8S);//定义看门狗8秒超时。
pinMode(brown_line, OUTPUT);
pinMode(gray_line, OUTPUT);
pinMode(purple_line, OUTPUT);
pinMode(led_blue, OUTPUT);
pinMode(led_green, OUTPUT);
pinMode(led_red, OUTPUT);
pinMode(body_sensor, INPUT);
pinMode(control, INPUT);
speed0();
}
void loop()
{
delay(2000); //省电,不要总是运行;等待红外信号
if (digitalRead(body_sensor)==HIGH) //if human body detected
{if (digitalRead(control)==LOW) //如果有红外信号
{
delay(1000); //延迟,过滤误触发
if (digitalRead(control)==LOW) //如果还有红外信号,不是误触发
{
blink_red();
delay(1000);
if (digitalRead(control)==HIGH) //如果没有信号,不是自然光
{
wdt_reset(); //喂狗
speed_change(); //换挡
}
}
}
}
wdt_reset(); //喂狗
if (digitalRead(body_sensor)==LOW) //if no human body detected, off the fan
{
speed0();
}
void blink_red()
{digitalWrite(led_red, on);
delay(50);
digitalWrite(led_red,off);
delay(500);
}
void blink_green()
{digitalWrite(led_green, on);
delay(50);
digitalWrite(led_green,off);
delay(500);
}
void speed1()
{
digitalWrite(brown_line, off); //slow fan speed, only purple line on
digitalWrite(led_blue, off);
digitalWrite(led_red, on);
speed =1;
}
void speed2()
{
digitalWrite(gray_line, off);//off fast fan
digitalWrite(led_green, off);
digitalWrite(led_blue, on);
delay(500);
digitalWrite(brown_line, on); //middle fan speed
digitalWrite(purple_line, on);
speed =2;
}
void speed3()
{
digitalWrite(gray_line, on);//fast fan speed
digitalWrite(led_green, on);
speed=3;
}
void speed0()
{
digitalWrite(gray_line, off);
digitalWrite(brown_line, off);
digitalWrite(purple_line, off);
digitalWrite(led_red, off);
digitalWrite(led_blue, off);
digitalWrite(led_green, off);
speed=0;
}
void normal_on()
{
switch(speed)
{
case 0:
speed3();
delay(1000);
if (digitalRead(control)==LOW)
{
delay(1000);
if (digitalRead(control)==LOW)
{
digitalWrite(led_green,off);
delay(50);
digitalWrite(led_green,on);
delay(1000);
wdt_reset(); //喂狗
if (digitalRead(control)==HIGH)
{break;}
}
}
else {delay(4000);
wdt_reset(); //喂狗
}
case 3:
speed2();
delay(1000);
if (digitalRead(control)==LOW) //如果检测到控制信号,
{
delay(1000);
if (digitalRead(control)==LOW) //不是误触发
{
digitalWrite(led_blue,off); //闪一下led
delay(50);
digitalWrite(led_blue,on);
delay(1000);
wdt_reset(); //喂狗
if (digitalRead(control)==HIGH) //如果不是自然光
{break;} //跳出,保持,不再降档
}
}
else {delay(4000); //否则,等5秒,降档
wdt_reset(); //喂狗
}
case 2:
speed1();
}
}
void speed_change()
{
switch(speed)
{
case 0:
normal_on();
break;
case 1:
speed0();
break;
case 2:
speed1();
break;
case 3:
speed2();
break;
}
}
看门狗一直没明白 看了楼主的文档有点启发 是不是電容降壓? k8706342 发表于 2014-9-6 23:51
是不是電容降壓?
是,电容在交流电里就是一个电阻的作用。 本帖最后由 yenan1001 于 2014-9-14 01:52 编辑
偶然看到了这篇,非常有启发。
可惜我的红外开关是模块,看来要买单独的原件来做了。
http://www.doyoung.net/articles/A_NEAR_IR/index.html
页:
[1]