gpt4 book ai didi

c++ - 使用带有 PIR 传感器的毫秒检测连续运动

转载 作者:行者123 更新时间:2023-11-28 04:10:11 25 4
gpt4 key购买 nike

我正在尝试检测 PIR 传感器何时触发连续运动超过 8 秒。这是我所拥有的。当传感器处于低电平时,显示“无 Action ...”,然后短 Action 会触发第一个“< 8 秒”IF 语句。当传感器返回到低电平时 - 没有显示应有的运动,但是当第二次检测到运动时,代码似乎卡住并且没有任何反应。

unsigned long startMillis;
boolean timingFlag = false;
const int buttonPin = 2;
int buttonState = 0;

void setup() {
pinMode(buttonPin, INPUT);
Serial.begin(19200);
delay(500);
}

void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH && millis() - startMillis <= 8000UL)
{
Serial.println("Motion Detected but less than 8");
delay(1000);
//the PIR timed out with in the three seconds so cancel timing
timingFlag = false; //disable timing
}

if (buttonState == LOW)
{
Serial.println("No Motion...");
delay(1000);
timingFlag = true; //enable timing
}
//when nine seconds have gone by with consistant detection do something
if (timingFlag == false && millis() - startMillis >= 9000UL)
{
//There has now been nine seconds of constant PIR detection
Serial.println("Motion Detected and greater than 9 sec");
delay(1000);
//Do Something
}
}

最佳答案

正如 Scheff 在评论中提到的那样,您当前的代码存在一个非常明显的问题:您实际上从未设置过 startMillis任何东西,所以它们可能(但不一定)总是 0。

这意味着语句 if (buttonState == HIGH && millis() - startMillis <= 8000UL)始终false 8000 毫秒后(直到 millis() 流过,大约 50 天* 后),所以 timingFlag永远不会重置为 false在那之后。这最终会导致您的“卡住”情况。

我试图找到一个设置 startMillis 的好地方在你的代码中,但老实说我觉得它有点困惑,所以我允许自己重写你的逻辑,希望你不介意。 (请注意,我还将变量名称从按钮更改为检测器,因为它看起来更适合我):

(此版本在从高电平到低电平的转换时触发)

// define the threshold, after which an action shall be triggered
const int detectionThreshold = 8000;
const int detectorPin = 2;

unsigned long startTime = 0;
int lastDetectorState = LOW;

void setup() {
pinMode(detectorPin, INPUT);
Serial.begin(19200);
delay(500);
}

void triggerDetectionAction(){
// do whatever needs to be done after 8 seconds of motion in here
}

void loop() {

int currentDetectorState = digitalRead(detectorPin);

// if detector is low, no motion is detected
if( currentDetectorState == LOW ){
// when the detector is LOW, we want to check if the last state was HIGH
// because then we just arrived at the transition from HIGH to LOW =>
// "something was detected" to "there is no longer something detected"
if( lastDetectorState == HIGH ){
// then, we can get the total duration, the detection lasted
unsigned long detectionDuration = millis() - startTime;
// and print it for easier debugging
Serial.print("Detection ended after ");
Serial.print(detectionDuration);
Serial.println(" milliseconds");

// finally, we check if the durations was more than
// or equal to our threshold
if( detectionDuration >= detectionThreshold ){
// and trigger stuff if necessary
triggerDetectionAction();
}
}

// if last detector state was LOW too,
// we don't want to do anything

}else{

// here we wan't to check for the transition of LOW to HIGH,
// so we check our last detector state
if( lastDetectorState == LOW ){
// if we caught the transition,
// set the start time to the current millis
startTime = millis();

// we could also set an indicator LED
// or Serial.print something here
Serial.println("Detection started");
}

// otherwise, we don't wan't to do anything

}

// finally, we save our current state into the last state,
// so we have it available in the next loop
lastDetectorState = currentDetectorState;

// do your other loop stuff here

}

请注意,我在编写时无法测试代码,因此可能存在(语法)错误

*更多关于毫秒和溢出的信息:https://www.arduino.cc/reference/en/language/functions/time/millis/


更新:该版本会在达到阈值时立即触发。它还包含一个示例,说明如何在达到阈值后每次循环触发一次操作。

// define the threshold, after which an action shall be triggered
const int detectionThreshold = 8000;
const int detectorPin = 2;

unsigned long startTime = 0;
int lastDetectorState = LOW;
bool actionTriggered = false;

void setup() {
pinMode(detectorPin, INPUT);
Serial.begin(19200);
delay(500);
}

void triggerOnce(){
// this will be called once, when the threshold is reached
}

void triggerEveryLoop(){
// this will be called every loop, after the threshold was reached
// for as long as the detector stays high
}

void loop() {

int currentDetectorState = digitalRead(detectorPin);

if( currentDetectorState == LOW ){

if( lastDetectorState == HIGH ){
// since we want to trigger immediately when the threshold is reached,
// we actually don't need this transition any longer.
// We can still keep it for debugging reasons thought.
// If you don't need this, you can simply remove the entire block
unsigned long detectionDuration = millis() - startTime;
Serial.print("Detection ended after ");
Serial.print(detectionDuration);
Serial.println(" milliseconds");
}

}else{

// Check for LOW => HIGH transition change
if( lastDetectorState == LOW ){
// if we caught the transition,
// set the start time to the current millis
startTime = millis();

// and reset the flag
actionTriggered = false;

// we could also set an indicator LED
// or Serial.print something here
Serial.println("Detection started");

}else{

// otherwise we want to check the duration
unsigned long detectionDuration = millis() - startTime;

// and trigger immediatley when the threshold is reached
if( detectionDuration >= detectionThreshold ){

// as long as it wasn't already triggered before
if( !actionTriggered ){

Serial.println("Threshold reached, triggering");

// now we also need to set a flag, so we know we already triggerd this action once
actionTriggered = true;

triggerOnce();
}

// we can also do something every loop
// this can be handy for e.g. blinking a light or playing a sound or something
triggerEveryLoop();

}

}

}

// finally, we save our current state into the last state,
// so we have it available in the next loop
lastDetectorState = currentDetectorState;

// do your other loop stuff here

}

关于c++ - 使用带有 PIR 传感器的毫秒检测连续运动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57983828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com