|
本帖最后由 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_line 10
- # 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;
- }
- }
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|