Как использовать serial.available () внутри void loop () во время задержки в Arduino? - PullRequest
0 голосов
/ 05 июня 2018

Я хочу выполнять функцию всякий раз, когда отправляю значение через последовательный монитор, но когда функция void loop () выполняет функцию задержки последовательной передачи.функция available () не работает, поэтому, если я отправлю какие-либо значения в последовательный монитор во время периода задержки, функция serial.available не будет работать

#define red 9
#define yellow 8
void setup() {
    // put your setup code here, to run once:
    Serial.begin(9600);
    pinMode(red, OUTPUT);
    pinMode(yellow, OUTPUT);
}
void LightON() {
    digitalWrite(red, HIGH);
    delay(1000);
    digitalWrite(yellow, HIGH);
    delay(1000);
    digitalWrite(red, LOW);
    delay(1000);
}
void LightOff() {
    digitalWrite(red, LOW);
    digitalWrite(yellow, LOW);
}
void loop() {
    // put your main code here, to run repeatedly:
    LightON();
    if (Serial.available())
    {
        LightOff();
    }
}

Как это исправить, когда я вхожузначение в последовательном мониторе в течение периода задержки функции Lighton (), поэтому Lightoff () выполняется?

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

LightON всегда будет занимать 3 секунды.Чтобы избежать этого, все становится сложнее.Вы можете использовать конечный автомат, чтобы отслеживать, где находится последовательность миганий в любой момент времени.Это также имеет то преимущество, что ваш код может делать другие вещи вместо того, чтобы зацикливаться или ждать на delay().

// This class represents the led state machine
class blinker {
    public:
    // Possible states
    enum {START, RED_ON, YELLOW_ON, RED_OFF, INACTIVE};

    // Constructor
    blinker(byte red_pin, byte yellow_pin, long timeout=1000) :
            red(red_pin), yellow(yellow_pin), timeout(timeout), state(INACTIVE) {
        pinMode(red, OUTPUT);
        pinMode(yellow, OUTPUT);
    }

    // Start the loop from the beginning
    void start() {
        stop();
        state = START;
    }
    // Stop the loop
    void stop() {
        digitalWrite(red, LOW);
        digitalWrite(yellow, LOW);
        state = INACTIVE;
    }

    // Update
    void loop() {
        // Only change if started and time is up
        if (state != INACTIVE && timer_expired()) {
            switch (state) {
                // Starting over?
                case START:
                    state = RED_ON;
                    digitalWrite(red,HIGH);
                    break;
                // Red is on, turn yellow on
                case RED_ON:
                    state = YELLOW_ON;
                    digitalWrite(yellow,HIGH);
                    break;
                // Yellow is on, turn red off
                case YELLOW_ON:
                    state = RED_OFF;
                    digitalWrite(red,LOW);
                    break;
                // Red is off, start over
                case RED_OFF:
                    state = START;
            }
        }
    }    

    protected:
    byte red, yellow;
    long timeout;

    // Returns true when time is up. 
    // Also resets the timer    
    bool timer_expired() {
        if ((millis() - last_time) >= timeout) {
            last_time = millis();
            return true;
        }
        return false;
    }
};

// Create the state machine
blinker blinky(9, 8);
void setup() {
    Serial.begin(9600);
    // Start loop
    blinky.start();
}

void loop() {
    // Call this everytime
    blinky.loop();

    // Stop?
    if (Serial.available()) {  
        blinky.stop();
    }

    // Can do other stuff here
}

Я просто бросил это все вместе.Вы можете улучшить это.

0 голосов
/ 05 июня 2018

Используйте пользовательскую функцию задержки следующим образом:

bool LedOn;

void MyDelay(int ms) {
   for(int i=0;i<ms;i++){
      if (Serial.available())
      {
        LightOff();
        LedOn = false;
        break;
      }
      delay(1);
   }
}

void LightON() {
    digitalWrite(red, HIGH);
    MyDelay(1000);
    if(! LedOn) return;
    digitalWrite(yellow, HIGH);
    MyDelay(1000);
    if(! LedOn) return;
    digitalWrite(red, LOW);
    MyDelay(1000);
}
void loop() {
  LedOn = true;
  LightON();
  if (Serial.available())
  {
    LightOff();
    LedOn = false;
  }
}
...