Не работает больше одного return; в функции
- Войдите на сайт для отправки комментариев
Здравствуйте, видел, что тема немедленного выхода из режимов гирлянды на ардуино уже обсуждалась и не только здесь. Но у меня вопрос в следующем. Имеется режим, немного длинный во времени. Я изменяю номер режима с помощью прерывания. В этом длинном режиме я сделал проверку номера через некоторый интервал и если режим не совпадает, выхожу из функции через return.
Проблема вот в чём. Первая проверка работает, я проверил, из функции выходит нормально. А вот вторая проверка уже нет. Когда номер меняется, из функции не выходит. Если удалить первый return, второй уже работает. Больше одного return отказывается работать и мне не понятно почему... Если вы знаете почему, прошу вашей помощи. Очень благодарен за уделенное время!
void mode2() { paint(L1, speed2, red_row); paint(L2, speed2, red_row); paint(L3, speed2, red_row); paint(L4, speed2, red_row); delay(250); paint(L5, speed2, red_row); if (mode != 2) return; // этот работает delay(250); paint(L1, speed2, green_row); paint(L2, speed2, green_row); paint(L3, speed2, green_row); paint(L4, speed2, green_row); delay(250); paint(L5, speed2, green_row); if (mode != 2) return; // этот не работает delay(250); paint(L1, speed2, blue_row); paint(L2, speed2, blue_row); paint(L3, speed2, blue_row); paint(L4, speed2, blue_row); delay(250); paint(L5, speed2, blue_row); if (mode != 2) return; // этот не работает delay(250); }
А с чего бы ему работать? И в чем фишка трех одинаковых условий? Вы вообще понимаете, чего наворотили?
Если честно, понимаю, что по-нормальному так не делается и неправильно так-то. Фишка трех одинаковых условий была в том, чтобы уменьшить время выхода из режима в три раза, так как я не понял как выйти из функции в тот момент, когда выполнилось прерывание
morningstar, опишите простыми русскими словами что вы хотите сделать пошагово. Например так: возможны № редимов работы устройства. Если включен режим 1 - делаем то-то. Если включен режим 2 - вызываем пожарных. Если режим не определен не делаем ничего.
А так у вас махровый собачий бред понаписан без возможности даже предположить, как это задумано
"Режим немного длинный во времени" в цитатник ящитаю
И да, если это вызывается в прерывании - в топку весь этот бред. В прерывании выставляйте только флаг режима.
я бы запретил новичкам, не знакомым с миллис - использовать прерывания. Это мешает им правильно писать программы.
ТС, чтобы обеспечить выход из "режимов. немного длинных по времени" - перепишите программу без делеев. Считайте, что такого механизма, как "прерывание" - в МК просто нет. И подумайте, как решить вашу задачу без него.
У меня светодиодная rgb матрица 3х3. Я написал для неё несколько режимов. Имеется переменная mode, котоаря хранит номер эффекта от 0 до 6. В цикле lool() есть конструкция switch, которая по сохраненному значению mode вызывает ту или иную функцию с режимом. Значение в mode изменяется через прерывание кнопкой. Все работает хорошо, но с одной неприятностью. Некоторые режими длинные по времени и если я нажал кнопку и значение режима изменилось (mode++), то после прерывания код выполняется с места прерывания. Приходится ждать пока весь режим не отработает и не включится следующий. Это занимает некоторое время. Я пытался сделать проверку и выход в некоторых местах в режиме.
Если надо весь код, вот: https://pastebin.com/P2uaU4iT
volatile
Ну и всю функцию можно переписать циклом, а лучше машиной состояний.
я бы запретил новичкам, не знакомым с миллис - использовать прерывания. Это мешает им правильно писать программы.
Я хотел об этом написать, но подумал, что ТС с вероятностью 99,9% не писал сам код на прерываниях, а пытается модифицировать скопипизженный в интернетах.
Автор! Ставь флаг режима в прерывании, если тебе так надо, но обрабатывай НЕ в прерывании структурой switch-case
В планах переписать чтобы было без делеей, с помощью миллис и циклов, не вызывать функции отрисовки новой строкой. А по поводу запрета прерываний, нельзя так все запрещать, может кому-то прерывания действительно нужны (не про себя)
А по поводу запрета прерываний, нельзя так все запрещать, может кому-то прерывания действительно нужны (не про себя)
хорошо, мы с микрочипом подумаем... будете себя хорошо вести - может и оставим вам прерывания в некоторых контроллерах
Я хотел об этом написать, но подумал, что ТС с вероятностью 99,9% не писал сам код на прерываниях, а пытается модифицировать скопипизженный в интернетах.
Из интернета только взял динамическую индикацию и решение антидребезга, которое не очень корректно работает
И автор! Кто тебя ТАК учил оформлять switch-case?? Почитай уже книжку по С++, хотя бы по операторам потока
А по поводу запрета прерываний, нельзя так все запрещать, может кому-то прерывания действительно нужны
Перерегистрировался?))
Мне сказали посмотреть как были реализованы режимы в светодиодных кубах, первая ссылка была на светодиодный куб Гайвера. У него было так...
Автор! Ставь флаг режима в прерывании, если тебе так надо, но обрабатывай НЕ в прерывании структурой switch-case
Не совсем понял, что вы имели ввиду, простите
Перерегистрировался?))
Нет, впервые на этом форуме, про запрещать перывания новичкам ничего не слышал. Когда делал выключатель на esp8266 во время ожидания подключения к AP без прерывания, чтобы выключатель выключал во время этого ожидания, не обошлось
Не совсем понял, что вы имели ввиду, простите
Плохо совсем. Короче, прерывание - нафиг. ВАМ они не то, что не нужны, они вам противопоказаны. Кнопку обрабатывать в лупе.
Перерегистрировался?))
Нет, впервые на этом форуме, про запрещать перывания новичкам ничего не слышал
Не ври, ливинг тичер)))
"Режим немного длинный во времени" в цитатник ящитаю
Ну, наверное хорошая цитата будет
В прерывании выставляйте только флаг режима.
Я так и сделал, только один флаг меняю в прерывании:
Я и не вру. Ливинг тичер?
И совершенно верно, что прерывание мне не нужно, кнопку можно обработать и в lool, из режимов то всероно не выйти, пока они не закончатся. Только нажатию кнопки помешает делей, который там много где)
Только нажатию кнопки помешает делей, который там много где)
Придется от делея избавиться. Он не нужен
Нужно курить тему блинк без делея
Я и не вру. Ливинг тичер?
Правда не знаешь? Я почти верю.
Когда делал выключатель на esp8266 во время ожидания подключения к AP без прерывания, чтобы выключатель выключал во время этого ожидания, не обошлось
И эта фраза - случайность
Правда не знаешь? Я почти верю.
И эта фраза - случайность
Я не знаю что такое этот тичер, код для того выключателя я не тырил из интернета (ну только смотрел примеры и пытался сделать своё). Управление через веб сделал с помощью вебсокетов. Вроде работает нормально, пока не жаловался. Но все еще не понимаю почему меня принимают за какого-то другого человека. Расскажете?
Нужно курить тему блинк без делея
От делея избавиться могу, за исключением места в динамической индикации. Его я взял из интернета: https://habr.com/ru/post/129569/
От делея избавиться могу,
Странная ситуация складывается. Делей мешает работе вашего алгоритма, но вы не хотите от этой пакости отказаться. Остается терпеть и не жаловаться
Вот я попытался избавиться. Когда функция выполняется заново, выполняется только первая часть до второго if. Поэтому я сделал флаг, который изменяется и если он изменился, часть кода, которая уже выполнилась, больше не выполняется, так по кругу.
morningstar
Вам нужно еще управлять состоянием (стадиями). Можете попробовать почитать о конечных автоматах .Конечные автоматы в C++ в блоге Личный опыт разработки ПО (devexp.ru)
Можете попробовать почитать о конечных автоматах
Когда-то проходил практику от университета, мне дали задание изучать плисы. Еле научился на нем сделать гирлянду из четырех светодиодов. Следущим были режимы на конечном автомате)) Я его так и не смог осилить. Наверное, время грызть знания пришло... Спасибо за ссылку
P.S. Делей все таки реальное зло! Обычно стараюсь его не использовать, но чет поперло меня на него. Без использования делей из режима выходит сразу же, как завершится анимация, они у меня короткие. Это немного помогло решить мою проблему. Но после прокрутки режимов, этот режим начинается с места где закончился, нужно как-то обновить флаг
Всем спасибо за помощь и советы!
Не работает больше одного return; в функции
И хорошо! Структурное программирование запрещает использование более одного return.
Камасутра... тьфу, блин ... MISRA - тоже! Так и не используйте - будьте правильным и прогрессивным!Правда не знаешь? Я почти верю.
И эта фраза - случайность
Я не знаю что такое этот тичер,
Расскажете?
Да. Чел, который умеет прерывания и ЕСП и не может справиться с делай ооочень похож на троля)). И судя по тому, что интернетом ты пользоваться умеешь тема с ретюрн возникнуть не могла сама по себе. Если ошибся - извини, если нет - не обессудь...
Если ошибся - извини, если нет - не обессудь...
Та все нормально, в esp не приходилось делать делей, разве что есть такая проблема, когда он все таки нужен, я применял нехороший способ програмного рестарта мк, делая вызов
void
(* resetFunc) (
void
) = 0;
Если перед этим что-то отправляется в монитор порта, оно не выводит это, не успевает что-ли. Вот тут и помогал делей в несколько миллисекунд.
А так, я ни кого не троллил, это моя реальная проблема которую я пытаюсь решить
А так, я ни кого не троллил, это моя реальная проблема которую я пытаюсь решить
Для не тролля вы слишком покладисты, учитывая агрессивный тупизм Rumata
Для не тролля вы слишком покладисты
+100500
А так, я ни кого не троллил, это моя реальная проблема которую я пытаюсь решить
Всё нужное для решения было дано больше часа назад, так что неправда.
А так, я ни кого не троллил, это моя реальная проблема которую я пытаюсь решить
Всё нужное для решения было дано больше часа назад, так что неправда.
В названии темы толсто
Ну... возможно до меня долго доходило. От делей избавился везде кроме функции динамической индикации, там присутствует delayMicroseconds(400), 400 микросекунд ардуино ничего не делает, возможно это критично, не знаю. Там просто цикл for и реализовать там без delay возможно для меня будет сложновато.
А еще наверное дурной тон хранить каждый отдельный символ (допустим кадр анимации) в отдельном массиве. При сознании большого количества кадров анимации для разных режимов эти массивы плодятся.
А еще наверное дурной тон хранить каждый отдельный символ (допустим кадр анимации) в отдельном массиве.
Да нет - тон нормальный при наличие памяти. А так она очень быстро кончается.
Меня все-таки шокирует заголовок темы.
В самом деле, если мы один раз зашли в функцию, то вряд ли можем выйти из нее более одного раза. Если зашли во второй раз - то тоже выйти можем только единожды.
Следовательно, если если у нас один раз "сработал" return, то никакой другой сработать не может, т.к. мы находимся уже вне функции.
Я до этого момента избегал return. Спасибо за объяснение