需要一些关于Arduino的光束断裂传感器代码的帮助

时间:2017-03-30 03:42:12

标签: arduino sensor

我正在研究这段代码,我无法弄清楚如何实现循环重置。

我希望程序在最初的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;
  }



}

1 个答案:

答案 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;
相关问题