Выполнение кода во время задержки
- Войдите на сайт для отправки комментариев
Доброго времени суток! Наверняка я не первый тут с таким вопросом, но всё же.
Есть следующее железо: ардуино нано, реле (питает помпу) и датчик хола (у меня пока в место него обычная кнопка, для теста)
Задача следующая: вкл реле, дать ему поработать 25 сек, в это время считать количество срабатывания датчика хола (кнопки) и записывать его в переменную, затем выключить реле
Собственно вопрос: как сделать несколько процессов одновременно? Тот же delay "тормозит" мозги и паралельно ничего не сделать. То есть держать цифровой пин активным, считать инфу с датчика и записывать в переменную? Как сделать всё отдельно - знаю, а одновременно - увы.
Вот пример из того что сейчас работает просто через delay(), там нет работы с датчиком и тд. только вкл/выкл пин по таймеру. Не судите строго по качеству кода. Второй вечер разбираюсь что тут и как.
void start_filling() { digitalWrite(PIN_RELAY, HIGH); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Помпа ВКЛ."); delay(25000); // (тут нужно пыполнить другой код пока идут 25 сек) digitalWrite(PIN_RELAY, LOW); lcd.clear(); lcd.setCursor(0, 1); lcd.print("Помпа ВЫКЛ."); }
Благодарю!
Сравните blink и blink without delay.
Второй делает именно то, что Вам нужно.
Нашел примеры в которых в цикле мигают лампочкой. Но мне не нужен цикл. Эта часть кода - один из void`ов, которые запускаются при определённых условиях и должен выполниться лишь раз
Если уж прям-прям с точностью до миллисекунд - смотри в сторону RtOs. Для AVR они есть. :))
Та не) +- трамвайная остановка тоже подойдёт. там супер точность не важна. главное сам момент одноразового выполнения кода во время работы таймера
Нашел примеры в которых в цикле мигают лампочкой. Но мне не нужен цикл. Эта часть кода - один из void`ов, которые запускаются при определённых условиях и должен выполниться лишь раз
Очень просто: после выполнения нужного Вам участка кода, поднимаете флаг. А в цикле loop() проверяете, поднят ли флаг. Если да - пропускаете, если нет - выполняете.
Нашел примеры в которых в цикле мигают лампочкой. Но мне не нужен цикл. Эта часть кода - один из void`ов, которые запускаются при определённых условиях и должен выполниться лишь раз
Очень просто: после выполнения нужного Вам участка кода, поднимаете флаг. А в цикле loop() проверяете, поднят ли флаг. Если да - пропускаете, если нет - выполняете.
Не совсем понимаю как завязать это дело на времени.
Не могли бы вы показать пример на основе того кода что я оставил? Благодарю
Объявляешь две булевых переменных флаги времени и выполнения. Флаги опускаешь - false. Ждёшь команды включения помпы. Вкючил помпу, поднял флаг -true помпа включена, запомнил время. Делаешь что нужно если флаг времени поднят, флаг выполнено опущен, в конце ставиш флаг выполено. Если флаг времени поднят проверяешь сколько времени прошло. Если (IF) меньше чем надо и не надо ещё раз что то делать то просто идёшь в начало цика. Если больше, выключаешь помпу, снимаешь флаги, ждёшь следующей команды включения помпы.
Про идею с флагами всё понял, спасибо. Но как описать это в коде - не хватает опыта. Второй день постигаю всё это. Пожалуйста, дайте пример. Спасибо!
Доброго времени суток! Наверняка я не первый тут с таким вопросом, но всё же.
Есть следующее железо: ардуино нано, реле (питает помпу) и датчик хола (у меня пока в место него обычная кнопка, для теста)
Задача следующая: вкл реле, дать ему поработать 25 сек, в это время считать количество срабатывания датчика хола (кнопки) и записывать его в переменную, затем выключить реле
Собственно вопрос: как сделать несколько процессов одновременно? Тот же delay "тормозит" мозги и паралельно ничего не сделать. То есть держать цифровой пин активным, считать инфу с датчика и записывать в переменную? Как сделать всё отдельно - знаю, а одновременно - увы.
Вот пример из того что сейчас работает просто через delay(), там нет работы с датчиком и тд. только вкл/выкл пин по таймеру. Не судите строго по качеству кода. Второй вечер разбираюсь что тут и как.
void start_filling() { digitalWrite(PIN_RELAY, HIGH); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Помпа ВКЛ."); delay(25000); // (тут нужно пыполнить другой код пока идут 25 сек) digitalWrite(PIN_RELAY, LOW); lcd.clear(); lcd.setCursor(0, 1); lcd.print("Помпа ВЫКЛ."); } Благодарю!
Ну если по ТЗ ТС то проще всего так :-)
Я так понимаю в yield (знаю как он работает) у нас идёт таймер который раз в секунду добавляет +1 к значению, а в 11 строке условие по которому если меньше, или равно 25, то делаем нужный код. И таким образом через yield "обходим" ограничение работы с обычным "delay". Я верно понял? Просто хочу для себя понять, а не просто готовый код взять
Нет.
yield() крутится как loop() пока delay(25000) отсчитывает свои 25 секунд и тормозит весь последующий код.
Если в в yield() нужен секундный таймер он делается на millis()
То есть в 13 строке я пишу код и он будет исполнятся только пока идут те 25 сек, или нужный мне код нужно писать в yield? Если нужно писать в yield, то будет ли работать код написанный в 13 строке, или он будет ждать окончания delay?
Код в строке 13 выполнится после выхода из delay(25000) - то есть через 25 секунд.
Пока идут эти 25 секунд буде постоянно вызываться yield() и в yield() уже тормозить нельзя. НИКАКИХ delay() там быть не должно.
Если в yield нужно что то проверять раз в секунду нужно использовать millis()
Примерно так:
Не надо delay. вместо него взять код из yield()
Не проверял, только идея.
сделал так:
Но весь процесс останавливается на lcd.print("Помпа ВКЛ."); и всё. Больше на дисплее информация не появляется
ругается на
и
сам код следующий:
ругается на
и
сам код следующий:
конечно ругается. таймеры то в 0 не выставил. сейчас код выглядит так:
Переменные надо описывать до использования. Для кнопки взял титановый велосипед.
https://github.com/Klapautsiy/titanium-bicycle-for-button/releases/tag/B...
Сильно палками не стукайте, но сейчас код такой:
И оно работает! И я даже понимаю почему! (сам удивлён)
Всем огромное спасибо!
74 строка как задумано?
она выключается на 77. на самом деле +- немного это не важно. главное что бы всегда было одинаково
Не понятно зачем. Раз в секунду за 25 секунд будет 25. Или тут будет что то другое?
74 строка как задумано?
по факту там не кнопка, а будет датчик хола. кнопка там для удобного теста в протеусе
(железо ещё не доехало)
там раз в 10 мс опрашивается кнопка (которая датчик хола) и если она активна - то пишет +1 в счётчик, а через 25 сек помпы выкл и всё что насчитало за 25 сек выводит на дисплей
А зачем датчик Холла по времени? Если считать обороты, то наоборот надо ловить фронты датчика через прерывание и считать их в прерывании. Совсем не внутри цикла. Тогда можно по второй кнопке можно отключать помпу и выходить из цикла раньше в случае необходимости через return.
ну мне не важно сколько оно там насчитает. нужен сам факт подсчёта с выводом. я это всё в глаза вижу второй день. до этого дела со всем этим не знакомился, так что использовал тот код что вы (форумчане) мне и дали
while
( millis() - TimeStartPomp <=25000);
тот же delay(), тока вид сбоку
Но мы в нутри этого делея и можем его в любой момент прервать.
Вот-вот. То что мне и нужно было!
внимательно посмотри на строчку, которую я написал. В каком мы нутре?
Код выше скопирован из исходников - yield объявлена как weak ...
Переобъявляем yield и получаем активность внутри delay ..
https://wokwi.com/projects/343926146113471058
Главное не переусердствовать - delay вызывается не только в вашем коде, но и внутри Arduino Core и многих библиотек. Ваш код из yield будет срабатывать на все эти вызовы !!!
Помогать ТС'у прикрутить костыли к его изначально ошибочной конструкции , это такой тонкий троллинг ?
внимательно посмотри на строчку, которую я написал. В каком мы нутре?
Мы в внутри от do до while. И самое главное отличие нам не нужен йелд, что бы что то делать дополнительно, а следовательно мы можем прервать этот delay в любой момент, если потребуется.
АААААА, там do-while, это значит, что это я тупой спрасони. Прошу пардону.
А зачем на каждом прохождение лупа вызывать обороты?
А зачем на каждом прохождение лупа вызывать обороты?
Я так захотел , потому что.
Захоти не вызывать и не вызывай.
И ещё из yield нельзя прервать delay. А свой delay из do while можно. И внутри своего можно резвиться как угодно.
Аппаратный счетчик-самое простое решение как по мне
Собственно вопрос: как сделать несколько процессов одновременно?
https://arduino.ru/forum/programmirovanie/upravlenie-neskolkimi-protsess...
Так так у него был поставлен вопрос. Это самое простое и короткое решение для его кода. Меньше всего переделок.
На Амперке мы уже обсуждали как можно использовать делай с возможностью выхода из него по решению из yield()
Нашел примеры в которых в цикле мигают лампочкой. Но мне не нужен цикл. Эта часть кода - один из void`ов, которые запускаются при определённых условиях и должен выполниться лишь раз
Очень просто: после выполнения нужного Вам участка кода, поднимаете флаг. А в цикле loop() проверяете, поднят ли флаг. Если да - пропускаете, если нет - выполняете.
Вчера не ответил, спал уже почти...
Вот пример с одним флагом
P.S Это как вставить код , что был вначале темы
С millis для систем которые не планируется выключать - т.е они работают месяцами будет баг если не учитывать что раз в несколько 10-ков часов в том же Nano (там по разному) будет wraping т.е. millis возвращает число миллисекунд со старта - и размерность переполнится. Читал, что в Nano что-то вроде от 54 часов до 7 дней вроде в разных версиях.
Поэтому если наступит переполнение - от новые данные millis после перехода из-за переполнения на 0 - будут всегда меньше старых если те взяты непосредственно перед переполнением. Система никогда не дождется той самой 1 секунды и залипнет в том состоянии которое было перед этой ситуацией. Стоит дописать проверку - что если после число меньше чем перед - то учесть число остатка или (если не важна точность) число миллисекунд перед обнулить.
Такой баг будет не всегда, отследить будет трудно, система будет зависать раз в случайное число дней (или недель).
опять великое переполнение миллис )))
опять великое переполнение миллис )))
В 32 битной системе максимум
4294967295/1000 = 4294967 секунд / 60 = 71582 минут /60 = 1193 часа / 24 = 49 суток.
Я полагаю, что конроль за такими вещами как температура в комнате с использованием котла на газе или палетах -будет работать на большей территории России в течении 4-6 месяцев в зависимости от региона. Вероятность что вы не отключите нагрев котла вас не пугает?
Ну, йоптЭ, приведи пример в коде, кто_ж мешает то, Апсудим, чО. Ни_ачкуешЪ???
Ну, йоптЭ, приведи пример в коде, кто_ж мешает то, Апсудим, чО. Ни_ачкуешЪ???
Хорошая попытка но нет. Сам все сам.
Это изначально было очевидно. ))))))))))))))))))))
Это изначально было очевидно. ))))))))))))))))))))
Да - ты победитель, теперь все?