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 и любое из внешних прерываний для подсчета поступающих на вход прерывания импульсов. Правда там два вывода теряем плюс внешняя перемычка.
Для слишком критичного ко времени исполнения участка подпрограммы-обработчика под ассемблером есть прием "условного возврата" (подстановка адреса возврата через стек).
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения