Использование задержки 1 мс () в цикле for для проверки входных данных.. Плохо?
Итак, во-первых, я знаю, что 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);
}
}
}
@BobaJFET, 👍0
Обсуждение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()
предназначена для бесконечного повторного вызова. Используйте это в своих интересах.
Что в этом плохого?
Это выглядит немного неуклюже, но я полагаю, что в этом нет ничего особенно плохого (кроме вашей опечатки digitalWrite, а не digitalRead).
Я бы сделал это скорее так:
unsigned long now = millis ();
button = LOW;
while ((millis () - now < 10000) && (button == LOW))
button = digitalRead (pin);
но тогда if
тоже будет работать в loop (), @Juraj
Я знаю, что 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
- Как независимо запускать позиционные и непрерывные сервоприводы с помощью millis()?
- Вопрос об использовании millis для сигнальных условий - Arduino
- Использование millis вместо задержки перезагрузки реле
- Как справиться с rollover millis()?
- Использование millis() и micros() внутри процедуры прерывания
- Чтение из Serial
- ардуино - миллисекунды ()
- Кнопка с таймером переключения и функцией сброса времени + светодиод обратной связи
Угадайте, почему loop() называется
циклом
. Ваш код становится проще, если вы не вкладываете в него другие циклы ожидания. Чем проще, тем лучше., @DataFiddler