Использование задержки 1 мс () в цикле for для проверки входных данных.. Плохо?

millis input delay

Итак, во-первых, я знаю, что millis() существует. Просто спрашиваю из любопытства. Допустим, у вас есть кнопка, которую вы хотите проверить во время задержки.. Может быть, 10-секундная задержка. Итак, вы создаете цикл for, который проверяет ввод и задерживает 1 мс ... 10 000 раз. Что в этом плохого?

 int pin = 13;   
    bool button = false;        
    
    void setup()
    {
      pinMode(pin, INPUT);    
    }
    
    void loop()
    {

     while(button == false) {
     for(int i = 0; i<10000; i++) {
     if(digitalRead(pin,HIGH){
     button = true;
}
     delay(1);

    }
  }
}

, 👍0

Обсуждение

Угадайте, почему loop() называется циклом. Ваш код становится проще, если вы не вкладываете в него другие циклы ожидания. Чем проще, тем лучше., @DataFiddler


3 ответа


Лучший ответ:

3

Вы можете сделать это для довольно простых набросков. Это начинает становиться уродливым, если вы добавляете больше функций и условий.

Следовательно, "правильныйTM" (читай: профессиональный) способ - это реализовать конечный автомат. Смотрите в IDE пример мигания без задержки.

const unsigned long DELAY_MS = 1000;

int pin = 13;

enum State {
    WAITING, WORKING,
};

State state;

unsigned long startTime;

void setup()
{
    pinMode(pin, INPUT);
    state = WAITING;
    startTime = millis();
}

void loop()
{
    switch (state) {
    case WAITING:
        // Вы можете поместить оба условия в одно "if" с помощью оператора "||".
        // Но это будет выглядеть менее четко.
        if (millis() - startTime > DELAY_MS) {
            state = WORKING;
        } else if (digitalRead(pin)) {
            state = WORKING;
        }
        break;
    case WORKING:
        // что-нибудь нужно сделать после задержки или кнопки
        break;
    default:
        // любая обработка ошибок, которую вы считаете подходящей
        break;
    }
}

Функция loop() предназначена для бесконечного повторного вызова. Используйте это в своих интересах.

,

1

Что в этом плохого?

Это выглядит немного неуклюже, но я полагаю, что в этом нет ничего особенно плохого (кроме вашей опечатки digitalWrite, а не digitalRead).

Я бы сделал это скорее так:

unsigned long now = millis ();
button = LOW;

while ((millis () - now < 10000) && (button == LOW))
  button = digitalRead (pin);
,

но тогда if тоже будет работать в loop (), @Juraj


0

Я знаю, что millis() существует

Хорошо, millis - это всегда лучший способ ...

Допустим, у вас есть кнопка, которую вы хотите проверить во время задержки.. Итак, вы создаете цикл for, который проверяет ввод и задерживает 1 мс ... 10 000 раз.

Ваш код на самом деле делает не то, что вы хотите. Ваш цикл while никогда не заканчивается до тех пор, пока кнопка не будет нажата, поэтому задержка в 10 секунд не имеет смысла. Я полагаю, что ваш код должен завершиться через 10 секунд или при нажатии кнопки.

Просто спрашиваю из любопытства

Ваш код, без millis(), должен быть

bool button = false;
...
...
void loop() {
  uint16_t ms2wait = 10000;
  while (button == false && --ms2wait > 0) {
    if(digitalRead(pin,HIGH)
      button = true;
    delay(1);
  }
}
,

В моем случае я не хочу, чтобы цикл while завершался до тех пор, пока не будет нажата кнопка. Я также пытаюсь обсудить, почему millis() лучше, чем задержка 1 мс 10 000 раз., @BobaJFET

Вы должны спросить: "Будет ли мой код делать что-то еще, пока он ожидает события?". Если ответ "ДА", ваш код должен использовать подход millis(), если "НЕТ", вы можете использовать delay() . Я сказал, что миллис - лучший способ, потому что "ДА" на 99,99% является правильным ответом. В вашем примере 10 секунд - это огромный промежуток времени, и совершенно очевидно, что ваш MCU тем временем должен сделать что-то еще. В общем, проверка того, прошло ли 10000 мс, или замораживание вашего MCU на 1 мс 10000 раз - это одно и то же., @Marco Cogo

Я говорю вполне, потому что, используя 1msx10000, вы не учитываете время, затраченное на выполнение кода внутри цикла for, и это может увеличить реальную задержку после 10000 циклов., @Marco Cogo