我正在研究这段代码,我无法弄清楚如何实现循环重置。
我希望程序在最初的10秒倒计时期间随时重新连接光束时返回空闲状态。所以换句话说,这就是我想告诉Arduino:如果在10秒内的任何时间 倒计时你看到beamPin高(光束连接)重置循环。 必须有一个简单的方法来做到这一点。
我正在尝试使用此代码,但它不能像我想要的那样工作。
if (state == PAUSE_BEFORE_ON) {
//Wait in tight loop while counting down 10 second pause...
while (millis() - start_time >= PAUSE_BEFORE_ON_ms) {
//Check if BEAM is reconnected...
//If it is, reset to IDLE mode
if ( !beamIsBroken() ) {
state = IDLE;
}
这是整个代码
//Diesels High Tech Pet beam break sensor
//This sketch activates and deactivates the "hold Up" function which is build into the HIGH TECH pet door
//By imitating pressing and holding "ON BUTTON" while pressing "OPEN BUTTON" and then releasing both buttons
enum State {
IDLE, PAUSE_BEFORE_ON, ON_DELAY, OPEN_DELAY, WAIT_BEAM, PAUSE_BEFORE_CLOSE, OFF_DELAY
} state = IDLE;
uint32_t start_time;
const uint32_t PAUSE_BEFORE_ON_ms = 10L * 1000L; //pause for 10 seconds before initiating sequence
const uint32_t ON_DELAY_ms = 500L; // pause for half a second before sending ON signal
const uint32_t OPEN_DELAY_ms = 500L; // pause for half a second before sending OPEN signal
const uint32_t PAUSE_BEFORE_CLOSE_ms = 2L * 1000L; // pause for 2 seconds before sending ground signal to openPin which deactivates "hold Up" funtion
const uint32_t OFF_DELAY_ms = 250L;// pause for quarter of a second
const byte onPin = 2; // On button
const byte openPin = 3; // Open button
const byte beamPin = 4; // QT50CM yellow wire of receiver
void activateButton(byte pin) {
// to activate a button, we ground the pin
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}
void deactivateButton(byte pin) {
// to deactivate a button, we float the pin
pinMode(pin, INPUT);
digitalWrite(pin, LOW);
}
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
deactivateButton(onPin);
deactivateButton(openPin);
pinMode(beamPin, INPUT_PULLUP); // turn on internal 5.1k pullup resistor
state = IDLE;
start_time = millis();
}
boolean beamIsBroken() {
//'broken beam' grounds the output
return digitalRead(beamPin) == LOW;
}
/**
--wait for beam to break (IDLE)
--beam breaks
--wait 10 seconds (PAUSE_BEFORE_ON)
--send signal to ON
--wait half a second (ON_DELAY)
--send signal to OPEN
--wait half a second (OPEN_DELAY)
--release/turn off/float both signals
--wait for beam to reconnect (WAIT_BEAM)
--wait another 2 seconds (PAUSE_BEFORE_CLOSE)
--send ground signal to ON(which deactivates function)
--wait 1/4 of a second (OFF_DELAY)
--turn off "hold Up funtion" by sending ground signal to openPin
--wait for beam to break again (IDLE)
*/
void loop() {
switch (state) {
case IDLE:
if (beamIsBroken()) {
state = PAUSE_BEFORE_ON;
start_time = millis();
}
break;
case PAUSE_BEFORE_ON:
if (millis() - start_time >= PAUSE_BEFORE_ON_ms) {
activateButton(onPin);
state = ON_DELAY;
start_time = millis();
}
break;
case ON_DELAY:
if (millis() - start_time >= ON_DELAY_ms) {
activateButton(openPin);
state = OPEN_DELAY;
start_time = millis();
}
break;
case OPEN_DELAY:
if (millis() - start_time >= OPEN_DELAY_ms) {
deactivateButton(openPin);
deactivateButton(onPin);
state = WAIT_BEAM;
start_time = millis();
}
break;
case WAIT_BEAM:
if (!beamIsBroken()) {
state = PAUSE_BEFORE_CLOSE;
start_time = millis();
}
break;
case PAUSE_BEFORE_CLOSE:
if (beamIsBroken()) {
state = WAIT_BEAM;
start_time = millis();
}
else if (millis() - start_time >= PAUSE_BEFORE_CLOSE_ms) {
activateButton(openPin);
state = OFF_DELAY;
start_time = millis();
}
break;
case OFF_DELAY:
if (millis() - start_time >= OFF_DELAY_ms) {
deactivateButton(openPin);
state = IDLE;
start_time = millis();
}
break;
}
}
答案 0 :(得分:0)
尝试添加第二个if语句,将状态机路由回PAUSE_BEFORE_ON状态的IDLE状态。
case PAUSE_BEFORE_ON:
if (millis() - start_time >= PAUSE_BEFORE_ON_ms) {
activateButton(onPin);
state = ON_DELAY;
start_time = millis();
}
if ( !beamIsBroken() ) {
state = IDLE;
}
break;