Уважаемые форумчане. Начал работать со скетчами на ардуино.Нужен совет. Как уйти в бесконечный цикл. Т.е. Прикратковременном нажатии на кнопку первый светодиод загорается и при отпускании тухнет. Второй уходит в бесконечный цикл мигания до того времени пока не нажмем reset. Я создал такую программу, но она мне кажется не правильной, хотя все работает. Может у кого есть идеи. Код (Text): #define BUTTON_PIN 2 #define LED_PIN 10 #define LEDD_PIN 13 #define BLINK_DELAY 500 bool LedState = false; bool Button = true; bool mer = false; void setup() { pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(LED_PIN, OUTPUT); pinMode(LEDD_PIN, OUTPUT); } void loop() { bool isButton = digitalRead(BUTTON_PIN); if (!isButton && Button) { digitalWrite(LEDD_PIN, HIGH); mer = true; if (mer) { digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2); } } else {digitalWrite(LEDD_PIN, LOW); if (mer) { digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2);} } }
Добавил. Но это не главное сейчас. Мне нужно узнать правильно ли составлена программа и есть ли альтернативы ей. Может условие за else не совсем и нужно. Либо как-то по другому... Код (Text): #define BUTTON_PIN 2 #define LED_PIN 10 #define LEDD_PIN 13 #define BLINK_DELAY 500 bool LedState = false; bool Button = true; bool mer = false; void setup() { pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(LED_PIN, OUTPUT); pinMode(LEDD_PIN, OUTPUT); } void loop() { bool isButton = digitalRead(BUTTON_PIN); delay (20);// добавил борьбу с дребезгом. if (!isButton && Button) { digitalWrite(LEDD_PIN, HIGH); mer = true; if (mer) { digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2); } } else {digitalWrite(LEDD_PIN, LOW); if (mer) { digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2);} } }
сделал код более читаемым (пользуйтесь Сtrl + T - будет легче) разобрался, всё нормуль. Код (Text): void loop() { bool isButton = digitalRead(BUTTON_PIN); delay (20); if (!isButton && Button) { digitalWrite(LEDD_PIN, HIGH); mer = true; if (mer) { digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2); } } else { digitalWrite(LEDD_PIN, LOW); if (mer) { digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2); } } }
Я как бы преследую другую цель, хочу научиться уходть в бесконечный цикл не зависящий от продолжения программы и прерываний. Объясню по другому: Нажимаю на кнопку она запускает цикл (допустим моргание светодиода), и этот цикл выполняется всегда, даже если в программе стоит передача данных по радиочастоте или др. только при нажатии reset цикл обнуляется. А кнопка которая запускала будет использоваться для другого действия в программе, но это по сути не важно.
Многозадачность на контроллерах, даже промышленных не поддерживается. Всегда в определенный момент выполняется только одна задача. Есть планировщики задач, которые прерывают одну и ставят на выполнение другую, но работает в текущий момент только одна. Для того, чтобы разгрузить основной процессор ставятся "сопроцессоры", например, коммуникационные модули. процесс Loop это и есть бесконечный цикл, который всегда исполняется. Вы только прменьше delay-ев используйте. А это как так? При нажатии на reset Loop() точно перезапустится, но только после Setup() . Вы давно с контроллерами знакомы?
По сути эта программа - продолжение обзора "Умная жерлица" ; С контроллером про мини, который у меня сейчас в единственном экземпляре знаком пару дней. Задумка программы такова, что при нажатии на кнопку (после -это будет геркон) светодиод на жерлице должен мигать постоянно (чтобы ночью было видно куда бежать), но при этом сигнал о срабатывании должен передаться по радиочастоте не прерывая мигания.
Жерлица, это, по-моему, круто. Тогда я не понимаю, откуда у Вас берутся такие вопросы по программированию. по коду Код (Text): #define BUTTON_PIN 2 #define LED_PIN 10 #define LEDD_PIN 13 #define BLINK_DELAY 500 bool LedState = false; bool Button = true; bool mer = false; void setup() { pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(LED_PIN, OUTPUT); pinMode(LEDD_PIN, OUTPUT); } void loop() { bool isButton = digitalRead(BUTTON_PIN); delay (20); if (!isButton && Button) { digitalWrite(LEDD_PIN, HIGH); mer = true; if (mer) { digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2); } } else { digitalWrite(LEDD_PIN, LOW); if (mer) { digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2); } } } У меня 2 замечания переменная Button только объявляется и инициализируется в true, но нигде не используется. поэтому if (!isButton && Button) равносильно if (!isButton). Код (Text): if (mer) { digitalWrite(LED_PIN, (millis() / BLINK_DELAY) % 2); } выполняется 2 раза и на if и на else. это выражение выносится за пределы if (!isButton && Button) сейчас соберусь с мыслями и попробую написать покороче, строчек в 5 в void loop() и без использования библиотек.
Ошибся, кода в void loop() всего 4 строчки, комментарии не считаем. Должно работать. Кнопка в нажатом состоянии выдает на контроллер логический ноль(false), в отпущенном - true. Мигание сбрасывается нажатием на reset, программа просто перезапускается. Если дальше нигде не будешь использовать delay(), то с миганием будет все нормально, даже если будут использоваться передача данных по радио. Для того, чтобы появились проблемы с миганием, длительность цикла void loop() должна приближаться к BLINK_DELAY. Сделать это без использования delay() на ардуино тяжело. Код (Text): #define BUTTON_PIN 2 #define LED_PIN 10 #define LEDD_PIN 13 #define BLINK_DELAY 500 bool Button; bool mer = false; void setup() { pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(LED_PIN, OUTPUT); pinMode(LEDD_PIN, OUTPUT); } void loop() { Button = !digitalRead(BUTTON_PIN); //считываем и нормализуем кнопку digitalWrite(LEDD_PIN, Button); //Если нажата кнопка, то светится светодиод LEDD if (Button) mer = true; //если была нажата клавиша, а затем ее отпустили, то на светодиод LED выводится симметричный меандр //с длительностью импульса BLINK_DELAY миллисекунд digitalWrite(LED_PIN, ((millis()/BLINK_DELAY)%2) && mer && !Button); }
Спасибо! Все хорошо, но не очень. Маленькая загвоздка: При нажатии на кнопку(геркон, он будет установлен на теле жерлицы, а магнит на катушке) и удержании ее ( по сути магнит на катушке может остановиться напротив геркона, а тот в свою очередь сомкнет контакты) цикл LED останавливается. Сейчас еще сам покумекаю над этой блестящей на мой нубский взгляд программой. P/S/ совсем не понял про симметричный меандр. Буду разбираться.
Да, забыл про Button в скетче. Я выдрал из двух(чужих) программ вроде как главное. Слепил. Через 6 часов добавил. И как-бы получилось. Но написание Вашей программы - это то что я хотел. Но нужно доработать.
Никакие циклы не останавливаются. Loop работает все время без остановки В программе реализован такой алгоритм. LEDD горит, если нажата клавиша и пока она нажата. Если ее отпустить, то LEDD погаснет, если нажать снова, то загорится опять. LED мигает, если клавишу нажали, а потом отпустили. Если снова нажали клавишу, то мигать перестает. Если отпустить снова, то опять мигает. Меандр это и есть мигание. Симметричный - время горения равно времени погашенного состояния
Попробуй еще такой код на LED digitalWrite(LED_PIN, (((millis()/BLINK_DELAY)%2) && mer && !Button) || (((millis()/200)%2) && Button)); Если клавиша нажата, то диод мигает часто, если была нажата, но уже отпущена - реже
ПОЛУЧИЛОСЬ!!! digitalWrite(LED_PIN, ((millis()/BLINK_DELAY)%2) && mer ) ; \\ убрал !Button Хотя Ваше предложение еще лучше, так можно отслеживать вращение катушки
Вот еще бы подсказали как сделать так, чтобы если в самом начале (при установке жерлицы) кнопка нажата(магнит на катушке случайно совпал с герконом), то программа не запускается и горит, допустим, третий светодиот (красный). Это было бы для начала сказка.
А смысл? У Вас же уже есть целых 2 индикатора, что кнопка нажата? Установили жерлицу, видите, что LED мигает быстро, приспустили немного леску, чтобы магнит отошел от геркона и нажали reset. Тем самым поставив жерлицу в режим ожидания. Можно еще сделать не по срабатыванию геркона, а по изменению его состояния. Тогда программа будет такая Код (Text): #define BUTTON_PIN 2 #define LED_PIN 10 #define LEDD_PIN 13 #define BLINK_DELAY1 500 #define BLINK_DELAY2 200 bool Button, Button_old; bool mer = false; void setup() { pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(LED_PIN, OUTPUT); pinMode(LEDD_PIN, OUTPUT); } void loop() { Button = !digitalRead(BUTTON_PIN); //считываем и нормализуем кнопку digitalWrite(LEDD_PIN, Button); //Если нажата кнопка, то светится светодиод LEDD // устанавливаем mer по изменению состояния клавиши if ((Button && !Button_old) || (!Button && Button_old)) mer = true; Button_old = Button; digitalWrite(LED_PIN, (((millis()/BLINK_DELAY1)%2) && mer && !Button) || (((millis()/BLINK_DELAY2)%2) && mer && Button)); }
Все прекрасно работает, но задумка не в этом. Можно ли в СЕТАПЕ создать условие, при котором не выполнение его ЛУП не запустится.
Код (Text): if () { ... // что-то делаем while(1){}; // "зависаем" } Вместо 1 в условии while можно поставить какое-нибудь условие "возврата к жизни" с отрицанием.