Остановка программы и возврат в меню
- Войдите на сайт для отправки комментариев
Доброго дня, хочу спросить совета.
Есть ардуина с набором датчиком и управлением по блютусу. На ней запускаются различные подпрограммы и после их выполнения программа снова ожидает ввода данных, так называемое главное меню. Организованно вызовом функции из loop при получении данных по serial порту и возврате в него после выполнения подпрограммы.
но бывает нужно выйти до завершения подпрограммы или же ее завершение технически невозможно.
хочу организовать выход из этих подпрограм при получении по serialпорту заданного символа.
пока есть мысли по следующим вариантам
1. Прерывание при поступлении данных по serial порту (блютусу) - приходит символ, срабатывает прерывание, в нем сравниваем полученный символ, если он на перезагрузку, то ставим глобальную переменную в 1, и в каждой подпрограмме в конце цикла добовляем проверку этой переменной и выход из подпрограммы.
2. Практически тоже самое, только вместо установки переменной дергаем одним пином ресет. Кондер в цепь добавлять надо и как правильно подключить.
3. По прерыванию попробовать програмно рестартовать контроллер.
подскажите, как правильнее и оптимальнее поступить?
заранее благодарен
но бывает нужно выйти до завершения подпрограммы или же ее завершение технически невозможно.
Это говорит об ошибке проектирования.
Такой ситуации в принципе не должно возникать.
Следует перепроектировать программу, а не искать костыли для компенсации ошибок проектирования.
Нет, в данном случае это не ошибка и не костыли.
каждая подпрограмма работает определенное количество циклов - срабатываний датчиков. В некоторых подпрограммах это может быть большое число - 100 или даже тысяча срабатываний датчиков. Иногда ждать такое количество срабатываний нет нужды и нужно переключиться на другую подпрограмму.
Значит, не нужно делать в подпрограмме обработку срабатывания тысячи датчиков. Сделайте столько, сколько нужно наверняка. Если понадобится, еще раз (еще 1000 раз) вызовете эту подпрограмму.
Тоже не вариант, возможно неверная терминология.
это электронные мишени, с заданными упражнениями. Если мне нужно прекратить упражнение или же начать его заново, мне не нужно впустую поражать мишени н-ое количество раз, чтобы его закончить.
Рекомендую найти книгу: В.Д. Паронджанов "Занимательная информатика" и прочитать. После прочтения, у вас вопросы отпадут сами собой. Очень легко написано, мой 10-и летний рыбенок прочитал за пару вечеров.
Тоже не вариант, возможно неверная терминология.
это электронные мишени, с заданными упражнениями. Если мне нужно прекратить упражнение или же начать его заново, мне не нужно впустую поражать мишени н-ое количество раз, чтобы его закончить.
Ну так заведите переменную-флаг и меняйте её состояние (например нажатием кнопки или приёмом символа через serial). В условии if() подпрограммы проверяйте эту переменную, и в зависимости от её состояния (например логическое true/false или 1/0) выполняете или не выполняете какое-либо действие. Примерно это вы и описали в п1.
и в каждой подпрограмме в конце цикла добовляем проверку этой переменной и выход из подпрограммы.
Не в конце, а в начале. Будет не выход из подрпрограммы, а не вход в подпрограмму.
Чёт я так и не понял, надо выйти или перезагрузить контроллер? Вы что-то оба варианта рассматриваете.
Можно выйти в меню, можно перезагрузить. Данное действие будет выполняться очень редко, но нужно чтобы оно было.
Сам склоняюсь к первому варианту через прерывание, но с прерываниями на ардуино еще не работал, это первый проект на ардуино, он работает, но вот функция выхода не реализована
Тоже не вариант, возможно неверная терминология.
это электронные мишени, с заданными упражнениями. Если мне нужно прекратить упражнение или же начать его заново, мне не нужно впустую поражать мишени н-ое количество раз, чтобы его закончить.
Отчего же не вариант? Разве кто заставляет гнать цикл обязательно ВНУТРИ подпрограммы. Сделайте внешний цикл (собственно, он уже есть - loop(), осталось только добавить собственную переменную цикла и следить за ней) и в нем проверяйте условие прекращения упражнения и принимайте решение о вызове тех или иных подпрограмм.
Не в конце, а в начале. Будет не выход из подрпрограммы, а не вход в подпрограмму.
А еще точнее "в самом начале", т.е. проверку нужно осуществлять не после входа в подпрограмиму, а перед тем, как ее вызывать.
Да, как раз такой способ я имел в виду, просто неверно выразился.
Нет, в данном случае это не ошибка и не костыли.
Точно. Это лажа! Такой проблемы не должно быть, а Ваше решение с ресетом - бред.
Проблема в архитектуре. Пишите код так, чтоб:
1. луп завершался (и соответственно заново вызывался ардуиновским ядром) не реже десятков миллисекунд. Тогда все модули и классы смогут получить свой кусочек процессорного времени достаточно часто, чтоб сделать нужное.
2. Циклы не удовлетворяющие требованию п.1 недопустимы, заменяются на некий обработчик вызова с использованием глобальных переменных. Кстати именно по этому тут "геноцидят" delay().
3. Всех кто напишет что "глобальные переменные - плохо" посылайте. Если природная скромность не позволит - перенесите глобальные в публичные любого класса, экземпляр которого создастся при старте программы. "Антиглобалисты" глупы, это их удовлетворит.
4. После выполнения п.1-4 посмотрите, нужны ли вам ещё прерывания и перенесите их обработчики в луп (в 90% случаев так будет).
а Ваше решение с ресетом - бред.
Ну, почему так уж сразу бред?
Главное ведь подойти креативно и творчески! :))))
Вот. возьмёт ТС и присобачит туда серву, которая будет каким-нибудь
костылёмпротезом пальца на кнопку Reset ардуины нажимать. когда надо. И проект сам по себе нетривиальный и, выглядит здорово, и, опять же, ни у кого такого нет. Весьма достойно!