Как закодировать задержку внутри ISR?
Я построил простейшего робота для обхода препятствий. Когда датчик обнаруживает препятствие, он дает прерывание RISING для контакта 2. В этот момент я хочу, чтобы робот вернулся на 2 секунды и повернул направо на 2 секунды.
У меня есть код для поворота назад и вправо, но я не могу использовать функцию delay() внутри ISR, так как мне это написать?
@The White Cloud, 👍1
1 ответ
Обработчик прерываний должен быть как можно короче, поскольку во время его выполнения никакие другие прерывания не могут быть обработаны (включая прерывание, вызывающее функцию delay()
). ISR, и вы тоже не должны этого делать.
Вместо этого вы должны установить простую переменную флага в ISR, а затем проверить этот флаг внутри вашей функции loop()
. Если флаг установлен, вы можете выполнить соответствующий код внутри основного кода, а не внутри ISR.
Обычным определением флага является один байт (поскольку каждое действие чтения/записи является атомарным и не может быть прервано ISR). Не забудьте установить ее изменчивой, чтобы компилятор знал, что эта переменная может измениться в любое время.
volatile byte interrupt_flag = 0;
В ISR вы можете установить эту переменную, например, в 1, а затем в своей основной функции loop()
:
if(interrupt_flag){
// Делайте здесь все, что вам нужно
interrupt_flag = 0; // сбрасываем флаговую переменную
}
- Подключение джойстика Logitech к Arduino и прерывание цикла while
- Попытка несколько раз подать импульс светодиоду вне основного контура.
- Использование millis() и micros() внутри процедуры прерывания
- Подсчет импульсов с прерыванием
- Tower Pro MG996R сервопривод с высоким крутящим моментом 180 °, управляющий с помощью Arduino
- Устранение дребезга кнопки с помощью прерывания
- Программа arduino выдаёт ошибку expected //primary-expression before ')' token error: //expected ';' before '}' token E
- Почему необходимо использовать ключевое слово volatile для глобальных переменных при обработке прерываний в ардуино?
В этом случае робот не остановится сразу же после получения прерывания, он выполнит функцию переадресации, и когда он выйдет из этой функции, он будет опрашивать флаг прерывания, а затем остановится., @The White Cloud
Если ваш код должен реагировать быстро, вы должны ускорить
loop()
и функции, которые вы там вызываете. ISR НЕ предназначены для этой цели. Вероятно, вам вообще не нужен ISR., @DataFiddlerЕсли вы пишете свой код без задержек, время между триггером прерывания и опросом флага настолько короткое, что вы его не видите. Обратитесь к примеру BlinkWithoutDelay, чтобы изучить принцип выполнения действий по времени без блокировки другого кода с задержкой., @chrisl