Кнопка и реле: как сделать паузу c millis и отключение?
- Войдите на сайт для отправки комментариев
Сб, 19/01/2019 - 21:45
Здравствуйте! Вопрос от чайника )
Скетч простой - кнопка включает и выключает реле.
int flag=0; void setup() { pinMode(34, OUTPUT); // реле digitalWrite(34, LOW); pinMode(19, OUTPUT); // кнопка digitalWrite(19, LOW); } void loop() { if(digitalRead(19)==HIGH&&flag==0) { digitalWrite(34,!digitalRead(34)); flag=1; } if(digitalRead(19)==LOW&&flag==1) { flag=0; } }
Как изменить код, чтобы:
1) реле после включения само отключалось через 60 сек (лучше с millis)
2) если во время работы реле опять нажать кнопку, реле должно отключатся (досрочное отключение)
Спасибо!
А сами то Вы пытались? Или Вам в лом?
Пытался. А Вам не в лом комменты ни о чём писать?
Ты сжёг Ардуинку. Сам. Специально. Командой:
pinMode(19, OUTPUT);
// кнопка
... кнопка не может быть выходом!!!!!!!!!!!!!!!!!
Спасибо. Исправил. Но как ни странно работала (включала) и не сгорела)
Вот водочки немного принял и добрый стал
НЕ - похоже многовато - исправил программу
Спасибо большое! Таймер работает!
Может ещё рюмочку и по досрочному отключению подскажете? )
Спасибо большое! Таймер работает!
Может ещё рюмочку и по досрочному отключению подскажете? )
Это мы завсегда-пожалуйста (рюмочку значит), а досрочное отключение требует условий. Вы их не сформулировали. Но я Вам простым языком объясню - нажимаем на кнопку (описываем ее как вход!) и если она нажата то скидываем флаг в ноль. Напишите сами - интереснее будет.
Пытался.
Пытался - показывайте. Таковы правила форума. Помогают тому, кто сам делает.
Добавил условие (может не туда?)
Нажатие на кнопку стало непредсказуемо включать-выключать реле - когда-то отключает досрочно, когда-то нет, когда-то даже просто включить не может... (
Условие простое: если в течение 60 секунд, пока работает реле, нажать на кнопку, то реле должно отключиться
Спасибо! Этот труд мне ещё надо осмыслить.. )
Работает, но в начале после включения ардуинка сама без спроса включает реле на указанное время, а потом отключает.
После этого всё как надо реагирует на кнопку.
Как отключить это самоуправство в начале?
Ни как.Запускается встроеный загрузчик. Скорее инвертивовать работу реле.
ПС: Как вариант притянуть резистором 1кОм к земле выход на включение модуля реле.
Это следующий этап моего развития в ардуино ))
Просто предполагается, что реле будет включать электромагнитный клапан для воды... И самовольное включение тут не очень желательно (с учетом перезагрузок из-за возможных отключений эл-ва).
"....После этого всё как надо реагирует на кнопку.
Как отключить это самоуправство в начале? ...."
А ты отвлеки Ардуинку чем нибудь.
Отличный вариант первой строчкой после Воид сетап написать delay (6000).
Работе не мешает. Загрузке не мешает. А ногами не шевелит. Пока загрузка.
Ничего не изменилось - после 6 секунд по-прежнему запускется реле..
Delay вроде же не даёт в фоне ничему происходить?
Ты сжёг Ардуинку. Сам. Специально. Командой:
pinMode(19, OUTPUT);
// кнопка
... кнопка не может быть выходом!!!!!!!!!!!!!!!!!
Все в этой жизни отночител но. Иногда надо подать сигнал на выход что бы считать кнопку.
При сбросе выводы МК переходят в Z состояние или становятся входами. И это происходит до тех пор пока программист не сделает ее выходом и не подаст на нее LOW. Вот это начальное ошибочное состояние Вы наблюдаете. Так что проще бороться с этой проблемой аппаратно с помощью дополнительного резистора, который подтягивает вывод идущий на модуль реле в ноль.
Tanatos, спасибо тебе!
qwone, спасибище огромное!!!
Я собрался сделать маленькое скромное реле, удлиняющее время работы лампы на три секунды после подачи сигнала. Дело в том, что столь простая задача на деле оказалась очень непростой. Импульс бывает разной длины, а считать надо уже от фронта этого импульса. Сработку по фронту длинного импульса не объясняет ни один пример.
С помощью сторонней библиотеки я задачу вроде решил, но по ТЗ всё будет собрано на AtTiny85. Библиотека с ней не дружит и пришлось искать решение с поддержкой инструкций для Тиньки.
Я сломал голову себе, пытаясь увязать столько условий. Вот тебе и простая задача... Удлинил импульс, называется.
Слизал Ваш код, чутка подправил - миссия выполнена. Почти.
По хорошему надо чтобы выход не сбрасывался в ноль по истечении времени, но при наличии импульса на входе. Но я уже третью неделю бьюсь над этой программкой, задолбался, и мне проще реализовать простейшее "ИЛИ" на паре диодов.
Ещё раз, qwone, спасибо.
з.ы. Надо всё-же добавить пример с обработкой длинного импульса, а то всё кнопки, кнопки...
в чем принципиальная разница между "длинным импульсом" и удержанием кнопки? - ни в чем. Примеров достаточно.
Принципиальная разница в начале интерпретации длинного нажатия. Всё, что мне попадалось было написано на так или иначе реализованном подсчёте времени после появления высокого логического уровня, что приводило к задержке включения таймера на величину этой задержки. Половина найденных примеров выполняет инструкцию по обратному перепаду уровня в "ноль" и по посчитанной длительности до этого перепада выполняет инструкцию. Попытка перевернуть такой пример на реакцию по фронту приводит к бесконечному циклу. По крайней мере у меня, зелёного.
qwone в своём варианте тоже инструкцию по обратному спаду выполняет, разве что у него это всё в отдельные циклы вынесено и можно легко инвертировать без последствий.
Проблема в том, что если импульс длинней выдержки - таймер перезапускался, а должен был посчитать однократно. Со сработкой по спаду таймер вообще не запускался - он ждал спад.
А существует-ли в Ардуино ИДЕ библиотека, имитирующая одновибратор? Если есть - ткните, пожалуйста, носом.
Заводите флаг, который эрегирует в момент фиксации фронта, а дальше кладете на этот хай, пока не истечет интервал, придуманный вами для максимально возможной длины импульса.
Ну или мониторите, пока не поймаете спад.
Правильная реакция на длинное нажатие может быть в одной из двух реализаций:
- по отпусканию кнопки, если время нажатия превосходит интервал, определенный как длительное нажатие,
- о истечении интервала, определенного для длительного нажатия, при условии, что кнопка остается нажатой.
На мой взгляд, более логичным представляется второй вариант - держишь кнопку до тех пор, пока не появилась реакция на длинное нажатие.
Я уже пришёл к такому-же выводу.
Но повторюсь. Там ни разу не кнопка.
Как и сказано выше, флаг я заводил и он эрегировал...
Я упёрся в то, что пока стоит флаг наличия высокого уровня на входе - счётчик при каждом цикле начинает отсчёт заново и до конца не досчитывает. Перманентное начало счёта. Мне нужно было считать и при наличии уровня на входе. Если досчитал, а уровень входа высокий - не начинать счёт сначала.
Потом был добавлен ещё флаг наличия счёта в таймере на миллис и таймер стал досчитывать, но стал перезапускаться при высоком уровне. Теперь надо было дать понять таймеру, что "всё, хватит". Я завёл третий флаг и в них запутался. Вот тут моск со мной попрощался вверг меня в сплин.
Я пытался разными способами заставить счётчик считать один раз на один фронт сигнала, но я ещё не постиг такой магии, а в примерах однократного выполнения процедуры по фронту я не нашёл.
Формально, я мог-бы это родить на паре транзисторов и конденсаторе, но решил вкатиться в Ардуино и прифигел от невозможности просто решить такую задачу.
"просто" - понятие относительное. Оно приходит с опытом. Опытному столяру табуретку собрать - нефиг делать, а я 2 дня буду корпеть и вряд ли соберу.
В вашей задаче нет ничего сложного. Похоже, что вы просто отслеживали только уровень сигнала - а этого мало. Чтобы отследить именно фронт - нужно поймать такой момент, когда текущее значение сигнала 1, а предыдущее = 0. Вот в этот то момент вы и запускаете свой таймер. Совершенно очевидно, что при таком условии таймер не будет начинать счет сначала ни при каждом проходе, ни при окончании счета - ведь "фронта" там нет. И флаги в простейшем случае вообще не нужны.
Перечитал еще раз. Насколько понял, вас интересует только высокий фронт, а длина импульса может быть любой? Распишите, для начала, все возможные состояния и реакцию на них. Будет легче. Лично я не осознаю всю задачу до конца. Например, что делать, если в течении этих трех секунд уровень поменялся с высокого на низкий, и обратно. Через сколько, от истечения трех секунд, начинать цикл по новой от смены уровней и т.д.
Bi11i, Вам нужа не куча флагов, а одна переменная состояния. Почитайте что-нибудь о конечных автоматах.
Спс. Читаю...
ТЗ на самом деле несложное.
Это "тройное моргание" поворотником в авто. Ранее успешно справлялась пара реле времени и пара реле контактных. На них была собрана логика. Проблема в размерах. Реле великоваты, а тут ещё стали подгорать и не включать поворотник вообще. В авто реализация этого режима выбирается переключателем, подающим плюс от прерывателя на цепи с лампами. Там при подключении нагрузки появляется пульсирующий ток.
Я через полевые транзисторы собираюсь коммутировать цепи с пульсирующим током, а сигналы о включении брать с переключателя, куда будет подведён плюс на "общий" контакт.
Задача контроллера - увидеть высокий уровень с переключателя, установить на выходном порту также высокий уровень и держать его таковым три секунды вне зависимости от длины входного импульса. Чрезмерная длительность на выходе реализована на простейшем "или" на диодах, один из которых пропустит сигнал на полевик со входа МК, а другой с выхода МК. То есть я поворачиваю - включаю переключатель на фиксатор. Полевик будет открыт, пока есть высокий лог. уровень на входе каскада. Уровень через диод обходит МК, пока включен переключатель. Это страховка на случай поломки МК, т.к. обычный режим моргания останется всегда. Если я включил переключатель кратковременно - высокий лог- уровень придёт на каскад с выхода МК через свой диод. Три секунды моргания поворотником при перестроении.
При включении "правого" входа - выход левого должен встать в ноль и наоборот, чтобы исключить моргание правых и левых поворотников вместе.
Вот и всё.
Два входа, два выхода. Собирать хочу на АтТини85.
алгоритм, по-моему, несложный
1. при появлении высокого уровня сразу запускаем таймер - назовем этот момент "СТАРТ"
2. если в течении 0.5 сек после СТАРТА высокий уровень пропал = это "короткое включение" = оставляем таймер на 3 сек
3. Если через 0.5 сек с момента СТАРТА все еще высокий уровень = "длинное включение" = останавливаем таймер
4. При появлении высокого уровня на противоложном поворотнике без всяких условий останавливаем таймер
Если я правильно понял задачу то так попробуйте
Всем доброго времени суток, очень нужна помощь,
Я пытаюсь написать программку для облегчения своей работы, работа не связана с программированием, поэтому в этой сфере я полный НОЛЬ, немного по изучав я наткнулся на программу ардублок, но там отсутствует возможность использовать задержки кроме delay. а мне необходимо отключать или запускать другой процесс а с delay это не получается и приходится постоянно перезагружать ардуинку, попробовав разные варианты с форума и с интернета, у меня ничего не получилось, программа заключается в включении трех реле на 2-3сек через определенный промежуток времени, в программе в место реле описаны светодиоды, так как я пробую на них и так нагляднее, вот пример моего кода.
все вот это pinMode(11, OUTPUT); не требуется делать каждый раз, только в сетапе. или это ардублок генерит автоматом ?
наткнулся на программу ардублок, но там отсутствует возможность использовать задержки кроме delay. а мне необходимо отключать или запускать другой процесс а с delay это не получается
Т.е. вы отказались от ардублок ?
программа заключается в включении трех реле на 2-3сек через определенный промежуток времени, в программе в место реле описаны светодиоды, так как я пробую на них и так нагляднее, вот пример моего кода.
А где в этом вашем ТЗ написано о "запускать другой процесс" ? Тут все укладывается в вариант с delay.
Программирование всякого такого без delay принципиально отличается, программа никогда не должна останавливаться и чего то ждать (или крутить длинный цикл) в определенном месте кода, она должна крутить основной цикл, в нем ждать каких то изменений (отсчета времени или нажатия кнопок), реагировать на них быстренько (переключать реле например) и крутить основной цикл дальше.