void loop() { if(digitalRead(7)==HIGH)delayFront=1; if(digitalRead(8)==HIGH)delayFront=2; if(digitalRead(9)==HIGH)delayFront=5; if(digitalRead(10)==HIGH)delayFront=10; Serial.println(delayFront); lcd.setCursor (12, 1); lcd.print(delayFront); lcd.print(" "); if (intFlag) { intFlag = false; // сбрасываем флаг ЗДЕСЬ ДОЛЖНА БЫТЬ ФУНКЦИЯ ЗАДЕРЖКИ НА [b]delayFront[/b] МИЛЛИСЕКУНД digitalWrite(3,HIGH); // включение выхода Serial.println("Interrupt!"); } }
Этот код должен делать вот что. После прихода фронта импульса на цифровой вход 2, возникшее прерывание с задержкой на delayFront миллисекунд должно включить цифровой выход 3. В статьях по программированию Ардуины пишут, что при выполнении прерываний функции времени работают с некими ограничениями. Какую функцию программирования мне следует использовать для того чтоб получать необходимую задержку включения выхода?
P.S. Задержка включения выхода нужна на десятки и даже сотни миллисекунд. Поэтому delayMicroseconds(time) получается что не подходит.
Последний раз редактировалось electroget Сб янв 11, 2025 11:12:41, всего редактировалось 1 раз.
delay() не работает в interrupt, а micros() и millis() не меняет свое значение в interrupt, но все три функции работает вне interrupt. Насколько критично время импульса? Также обработайте ситуацию: в течение времени после прерывания произошло новое прерывание (в зависимости от алгоритма вашего устройства: 1. оно должно или 2. не должно продлить время или проигнорировать новое прерывание). В первом варианте снова пропустите временной период, а во втором случае можете просто остановить прерывания cli(); и продолжить позже sei();.
delay() не работает в interrupt, а micros() и millis() не меняет свое значение в interrupt, но все три функции работает вне interrupt.
То есть, если я уже после обработки прерывания вставлю код с функцией millis() и после этого дам команду digitalWrite(3, HIGH); то межу прерыванием и включением выхода 3 получится необходимый мне интервал времени задержки?
Да. При наличии флага в прерывании реакця будет задержана на несколько такт, пока не войдет в loop. Вот почему спросил о критичности времени. Есть вариации на включения в прерывание и выключения в цикле по истечении времени. Выбирайте согласно своему алгоритму. --- Реакция мог бы быть с задержки - вижу, что пшете сообщения в Serial в цикле без каких-либо условий.
Последний раз редактировалось veso74 Сб янв 11, 2025 11:10:50, всего редактировалось 1 раз.
Компания MEAN WELL пополнила ассортимент своей широкой линейки светодиодных драйверов новым семейством XLC для внутреннего освещения. Главное отличие – поддержка широкого спектра проводных и беспроводных технологий диммирования. Новинки представлены в MEANWELL.market моделями с мощностями 25 Вт, 40 Вт и 60 Вт. В линейке есть модели, работающие как в режиме стабилизации тока (СС), так и в режиме стабилизации напряжения (CV) значением 12, 24 и 48 В.
Заголовок сообщения: Re: Вопрос по программированию задержки внутри прерывания
Добавлено: Сб янв 11, 2025 11:10:30
Друг Кота
Карма: 5
Рейтинг сообщений: 61
Зарегистрирован: Ср сен 30, 2020 16:51:47 Сообщений: 4614 Откуда: РФ
Рейтинг сообщения:0
veso74, Точность вообще не критична. Это делается для установки времени задержки срабатывания электронного предохранителя. Интервалы будут задаваться внешним переключателем: 1,2,5,10,50,100,200 миллисекунд. Скажите, а выполнение прерывания нужно обязательно специальной командой останавливать? В каком месте кода её нужно вставлять?
Для предохранителя: измените проверки if .. if ... if на if ... else if ... else if ... или на switch-case. И lcd.print и Serial.println() - ето медленные функции. Напишите их хотя бы с условием, что не пишет каждой раз в loop.
Одно сообщение не даст объяснения . Необходимо чтение и понимание и множество тестов и проверок, пока не установите на место в первый раз.
Последний раз редактировалось veso74 Сб янв 11, 2025 11:21:07, всего редактировалось 1 раз.
lcd.print и Serial.println() - ето медленные функции. Напишите их хотя бы с условием, что не пишет каждой раз в loop.
Это я всё конечно уберу когда программа заработает как надо. Вы мне пожалуйста ещё скажите про прекращение работы прерывания. Выполнение прерывания нужно обязательно специальной командой останавливать? В каком месте кода её нужно вставлять?
И с каких это пор она не работает в прерывании? Работает и в прерывании. Для коротких отрезков времени можете ее использовать, "the delay() function and many sketches use short delays for such tasks as switch debouncing, the use of delay()
in a sketch has significant drawbacks. No other reading of sensors, mathematical calculations, or pin manipulation can go on during the delay function, so in effect, it brings most other activity to a halt."
И с каких это пор она не работает в прерывании? ...
wiring.c, строка 83. delay() в interrupt прекратит interrupt. Необходимы и другие корректировки. Проще использовать собственную задержку вне interrupt.
Не надо делеить в обработчиках прерываний. Независимо от способа. Это учит плохому. Это будет говнокод.
_________________ Платы для HLDI - установки лазерной засветки фоторезиста. ФоторезистыOrdyl Alpha 350 и AM 140. Жидкое олово для лужения плат (видео) - самое лучшее и только у меня. Паяльная маска XV501T-4 и KSM-S6189 (5 цветов). Заказ печатных плат - pcbsmac@gmail.com
Совершенно верно. Некоторые компиляторы/IDE даже не допускают этого. Они уже "умные" . Не должно быть и медленные операции, такие как печать на ЖК-дисплее, на другой тип, в Serial порте, а также медленные вычисления, напр. с float, циклами и т. д.
Последний раз редактировалось veso74 Сб янв 11, 2025 13:03:02, всего редактировалось 2 раз(а).
in a sketch has significant drawbacks. No other reading of sensors, mathematical calculations, or pin manipulation can go on during the delay function, so in effect, it brings most other activity to a halt."
Ну почему же). Внутри delay() есть yield() - функция позднего связывания. Определив её у себя, можно выполнять операции во время работы delay().
Ардуино под Си не ассемблер. Используем то, что принято в референсе. Прерывание предпочтительно только под короткие операции с флагами и/или короткие фрагменты программного кода. Для слишком критичного ко времени исполнения участка подпрограммы-обработчика под ассемблером есть прием "условного возврата" (подстановка адреса возврата через стек). Возможно нечто похожее можно и под Си (без вставок на ассемблере) получить...
А вот этим yield() для простых прожек баловаться как то... https://alexgyver.ru/lessons/time/ Тем более, что без подключения соответствующей библиотеки ( #include <Scheduler.h> ) yield() работать не будет... Второе... "...расположенный внутри неё (yield()) код будет выполняться во время работы любой задержки delay() в программе..." но это не одно и то же, что "расположенная внутри функции текущего обработчика прерывания функция delay() будет исполняться"...
Последний раз редактировалось BOB51 Сб янв 11, 2025 13:27:43, всего редактировалось 2 раз(а).
Считайте условно нерабочим как происходит действие, которое не было запланировано. (не воспринимайте слово "прекратит" буквально, часто пользуюсь переводчиком).
Последний раз редактировалось veso74 Сб янв 11, 2025 13:35:11, всего редактировалось 3 раз(а).
Тем самым в определенной степени будет нарушена работа устройства. Псевдопараллельный процесс можно организовать как на дополнительном прерывании по COMP_A (у атмег 328 не задействован референсом) так и на сцепке стандартного референса - используя tone и любое из внешних прерываний для подсчета поступающих на вход прерывания импульсов. Правда там два вывода теряем плюс внешняя перемычка.
Для слишком критичного ко времени исполнения участка подпрограммы-обработчика под ассемблером есть прием "условного возврата" (подстановка адреса возврата через стек).
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения