2017-04-06 102 views
0

我正在尝试创建一个运动控制灯,除非天黑,否则灯不亮。运动控制灯

我希望在检测到运动时使用pwm慢慢打开和关闭灯。现在我的代码工作,几乎做了我想要的任何事情。

问题是我使用延迟功能来保持灯亮到达完全亮度后。并且由于这个原因,如果在灯亮时检测到运动,它不会重置计时器。一旦延迟计时器耗尽并检测到运动,亮度将降低然后返回。

我想有运动检测器重置定时器,保持领导,但一直未能得到它的工作。

我已经看过这些:

http://playground.arduino.cc/Code/AvoidDelay

https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

但因为我比较有限的Arduino的代码理解我一直没能得到它的工作。我真的很感激任何帮助。

解决

下面的工作代码:

const byte MotionPin = 4; // Motionsensor 
int LightSensorPin = 2; // Lightsensor 
const byte LedPin = 11; // LED 

unsigned long MotionDetectedMillis; // When motion was detected 
unsigned long ledTurnedOnAt; // when led was turned on 
unsigned long turnOnDelay = 50; // wait to turn on LED 
unsigned long turnOffDelay = 5000; // turn off LED after this time 
bool ledReady = false; // Has motion been detected 
bool ledState = false; // Led on or off 
int LightSensorState = 0; 

int fadeAmount = 5; // How much to fade in a loop 
byte brightness = 0; 

void setup() { 
pinMode(MotionPin, INPUT); 
pinMode(LightSensorPin, INPUT); 
pinMode(LedPin, OUTPUT); 

digitalWrite(LedPin, LOW); 
} 

void loop() { 
// get the time at the start of this loop() 
unsigned long currentMillis = millis(); 

if (digitalRead(MotionPin) == HIGH && digitalRead(LightSensorPin)== HIGH) 
{ 
    MotionDetectedMillis = millis(); 
    ledReady = true; 
} 

if (ledReady) 
{ 
    if ((unsigned long)(currentMillis - MotionDetectedMillis) >= turnOnDelay) 
    { 
     while (brightness < 255) 
     { 
     brightness = brightness + fadeAmount; 
     analogWrite(LedPin, brightness); 
     delay(30); 
     } 

    // setup our next "state" 
    ledState = true; 
    // save when the LED turned on 
    ledTurnedOnAt = currentMillis; 
    ledReady = false; 
    } 
} 

// see if we are watching for the time to turn off LED 
if (ledState) 
{ 
    if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay) 
    {  
    while (brightness >0) 
     { 
     brightness = brightness - fadeAmount; 
     analogWrite(LedPin, brightness); 
     delay(30); 
     } 
    ledState = false; 
    } 
} 
} 
+0

您发布的第二个链接是一个很好的教程,可直接解决您的问题。如果这没有帮助,你可能需要问一个更具体的问题。教程的哪一部分让你感到困惑? –

+0

我需要帮助的部分是如何将该代码集成到我的。我尝试了很多次,只是无法让它工作。 – lollero2

回答

1

你想要的是一个状态机;你必须跟踪你当前处于哪种状态的循环,以及触发下一个状态的条件是什么;因为你的循环只会在触发一个新状态的情况下执行一个动作,而不是使用delay(),你将使用'等待超时'状态(记住要知道下一个状态是什么)。

如果这让您感到困惑,请将每个状态想象成说明手册中的步骤; 打开led 1,等待x,打开led 1稍多一点,等y等等。 因为你没有更多的延迟,管理状态的“正常流程”之前或之后,你可以添加一些特殊的例如“如果输入2为高,当前状态为X或Y,则将当前状态设置为Z”。

+0

谢谢。我能够让我的代码工作。 – lollero2

0

所以,你想要什么可以很容易地存档与一个中断,但像这样一个简单的项目,你可以通过删除delay(OnTime)函数得到相同的结果。 如果您想了解更多关于Arduino UNO使用的atmega328中断的信息,请转至here