首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >运动控制光

运动控制光
EN

Stack Overflow用户
提问于 2017-04-06 16:32:06
回答 2查看 78关注 0票数 0

我试图创造一种运动控制的光,除非天黑,否则不会打开。

我希望当检测到运动时,用pwm慢慢地打开和关闭灯。现在,我的代码可以工作,并且几乎可以完成我想要的任何事情。

问题是,我使用延迟函数来保持灯在达到完全亮度后继续亮。正因为如此,如果在光线亮着的时候检测到运动,它不会重置计时器。一旦延迟计时器运行完毕,并检测到运动,亮度将下降,然后备份。

我想让运动探测器重置的定时器,保持led,但还没有能够使它工作。

我看过这些:

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

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

但是由于我对arduino代码的理解有限,我一直无法让它正常工作。我真的很感谢你的帮助。

解出

工作守则如下:

代码语言:javascript
复制
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;
   }
 }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-06 22:05:55

您需要的是一个状态机;您必须在循环中跟踪当前的状态以及触发下一个状态的条件;因为只有在发生了触发新状态的事件时,循环才会执行操作,而不是使用delay(),而是使用“等待超时”状态(记住要保持一种知道下一个状态的方法)。

如果这让你困惑,想象一下每一种状态都是说明书中的步骤;打开led 1,等待x,再打开led 1,等等等等。而且,由于不再有延迟,所以在管理状态的“正常流”之前或之后,可以添加一些特殊情况,例如“如果输入2高且当前状态为X或Y,则将当前状态设置为Z”。

票数 1
EN

Stack Overflow用户

发布于 2017-04-07 00:37:37

因此,您想要的东西可以很容易地通过中断进行归档,但是通过这样一个简单的项目,您可以通过删除delay(OnTime)函数获得相同的结果。如果您希望更多地了解atmega328的中断(这是Arduino UNO使用的中断),请转到这里

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43260905

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档