Очередной вопрос по нажатию кнопки
- Войдите на сайт для отправки комментариев
Добрый день, участникам форума!
Прошу помочь разобраться с вопросом, который у меня возник при изготовлении поделки на ардуино. Проект - автоматические шторы. Идея такая: нажал одну кнопку - шторы закрылись, нажал другую кнопку - шторы открылись. Если шторы находятся в процессе открытия/закрытия, то нажатие на любую кнопку приводит к остановке штор. Вроде простая задача. Поскольку программист я так себе, то пишу программу добавляя по несколько строк и смотрю на результат работы. Сначала написал кусок программы, который открывает и закрывает шторы, путем включения соответствующих реле на заданное время. Все работает. Дребезг контактов подавляю с помощью библиотеки Bounce2. Добавляю кусок кода, который устанавливает флаг движения штор и отключает реле, если кнопка нажата во время движения. Строки 58-62 и 70-74. И тут появилась проблема. По идее, если при нажатии кнопки взведен флаг движения, то сигнал на реле перестает подаваться и флаг движения устанавливается в ноль. Все вроде просто. Но снова появился дребезг. Пробовал увеличивать время задержки в debouncer.interval. Пробовал устанавливать задержку после взведения флага. Дребезг все равно остается. Думаю, что проблема в коде, но не могу сам найти ошибку. Не могли бы уважаемые участники форума посмотреть код и сказать, в чем моя ошибка?
// Include the Bounce2 library found here : // https://github.com/thomasfredericks/Bounce2 #include <Bounce2.h> #define BUTTON_PIN_1 2 #define BUTTON_PIN_2 3 #define PIN_OPEN 14 #define PIN_CLOSE 15 // Флаг движения штор int action_flag = 0; // Переменная для хранения точки отсчета unsigned long timing; // Instantiate a Bounce object Bounce debouncer1 = Bounce(); // Instantiate another Bounce object Bounce debouncer2 = Bounce(); void setup() { pinMode(BUTTON_PIN_1, INPUT_PULLUP); // After setting up the button, setup the Bounce instance : debouncer1.attach(BUTTON_PIN_1); debouncer1.interval(10); // interval in ms // Setup the second button with an internal pull-up : pinMode(BUTTON_PIN_2, INPUT_PULLUP); // After setting up the button, setup the Bounce instance : debouncer2.attach(BUTTON_PIN_2); debouncer2.interval(10); // interval in ms pinMode(PIN_OPEN, OUTPUT); pinMode(PIN_CLOSE, OUTPUT); } void loop() { // Update the Bounce instances : debouncer1.update(); debouncer2.update(); // Get the updated value : int value1 = debouncer1.read(); int value2 = debouncer2.read(); // Отслеживаем состояние кнопок if ( value1 == LOW ) { if ( action_flag == 0 ) { // Если нажата кнопка "открыть" и движения нет digitalWrite( PIN_OPEN, HIGH ); timing = millis(); action_flag = 1; } else { // Если нажата кнопка "открыть" и движение есть digitalWrite( PIN_OPEN, LOW ); //Остановить движение digitalWrite( PIN_CLOSE, LOW ); action_flag = 0; } } if ( value2 == LOW ) { if ( action_flag == 0 ) { // Если нажата кнопка "закрыть" и движения нет digitalWrite( PIN_CLOSE, HIGH ); timing = millis(); action_flag = 1; } else { // Если нажата кнопка "закрыть" и движение есть digitalWrite( PIN_OPEN, LOW ); //Остановить движение digitalWrite( PIN_CLOSE, LOW ); action_flag = 0; } } if ( action_flag == 1 ) { if (millis() - timing > 10000) { // Вместо 10000 подставьте нужное вам значение паузы digitalWrite( PIN_OPEN, LOW ); digitalWrite( PIN_CLOSE, LOW ); action_flag = 0; } } }
юзайте титановый велосипед, местный продукт
Это не дребезг. Скорее всего это реакция на длительное нажатие на кнопку. Т.е. вы ее просто не успеваете отпустить, как она срабатывает снова
Это не дребезг. Скорее всего это реакция на длительное нажатие на кнопку. Т.е. вы ее просто не успеваете отпустить, как она срабатывает снова
Похоже на то. Я думал, что это можно победить, установив задержку после обнаружения нажатия кнопки. Но не помогло. Думаю, что порождение злого гения (класс титановый велосипед) не поможет по той же причине. Хотя скачал, попробую разобраться.
До какого значения увеличивали интервал? ИМХО, здесь обычной задержки должно хватать через край, без каких-либо библиотек.
До какого значения увеличивали интервал? ИМХО, здесь обычной задержки должно хватать через край, без каких-либо библиотек.
debouncer.interval делал 10, 50, 100, 300, 1000. Чем больше, тем непонятнее поведение программы. Еще глюк. По логике программы (как вижу ее я), если нажата кнопка 1 и запущено реле 1, то нажатие кнопки 2 должно выключать реле 1. Вместо этого включается реле 2.
Думаю, что порождение злого гения (класс титановый велосипед) не поможет по той же причине. Хотя скачал, попробую разобраться.
Во-первых поможет, потому что там есть работа с состоянием кнопки. Во-вторых можно и ваш код довести до ума, а для этого нужно вести учет не только нажатию, но и отжатию кнопки. Т.е. завести еще один флаг (для каждой кнопки), который будет устанавливаться в true при нажатии и в false при отпускании кнопки, а все нынешние действия с кнопками допускать только при условии, что этот флаг еще false. Так вы исключите множественные срабатывания кнопки за одно нажатие.
Ну и в-третьих - не уверен, т.к. не пользовался библиотекой Bounce2, но, возможно, и в ней есть возможность обработки состояния кнопки (а не только считывания, как вы делаете сейчас)
В bounce2 есть и fell() и rose()
Во-первых поможет, потому что там есть работа с состоянием кнопки. Во-вторых можно и ваш код довести до ума, а для этого нужно вести учет не только нажатию, но и отжатию кнопки. Т.е. завести еще один флаг (для каждой кнопки), который будет устанавливаться в true при нажатии и в false при отпускании кнопки, а все нынешние действия с кнопками допускать только при условии, что этот флаг еще false. Так вы исключите множественные срабатывания кнопки за одно нажатие.
Не знаю, по мне, так:
Считали кнопки 1,2
если нажата одна, проверили - выполняется любое(закрытие-открытие) действие - стоп
не выполняется - старт действия от кнопки.
delay(200);
И не надо долго тычить пальчик. Тот случай, когда делей вполне в тему, а вся задача в тиньку со свистом поместится. ИМХО.
То ТС, это имеет право на жизнь, если не лезет помеха от реле, что весьма возможно и приделать концевики на шторы или пытаться как то запомнить их положение в момент остановки, концевики надежней.
И не надо долго тычить пальчик.
А как же защита от дурака?)))
юзайте титановый велосипед, местный продукт
та, да - пордукт... местный.
сцуко, до слёз.
!Здрасте, всем.
вот это точно небезопасная архитектура:
36
pinMode(PIN_OPEN, OUTPUT);
37
pinMode(PIN_CLOSE, OUTPUT);
достаточно чуть намутить в коде и рискуешь врубить открывание и закрывание одновременно.
безопасно: одно реле на переключение режима "открывать/закрывать штору", второе реле - режим "старт/стоп открывания/закрывания".
тогда, при любых раскладах будет происходить что-то однозначно вменяемое.
ну, и аппаратные концевики - обязательно.
Считали кнопки 1,2
если нажата одна, проверили - выполняется любое(закрытие-открытие) действие - стоп
не выполняется - старт действия от кнопки.
Так мой код именно это и делает. Но с глюками :). delay пробовал вставлять после ого как обнаружено нажатие кнопки, но не работает. Все равно по симптомам похоже на то, что я очень медленно нажимаю на кнопку и за это время код успевает выполниться несколько раз.
Основную идею я уловил. Надо отслеживать не нажатие кнопки а изменение ее состояния. В библиотеке bounce2, действительно есть функция отслеживания изменения состояния. Причем можно установить какое изменение (в HIGH или в LOW) считать нажатием. Переделал код. Сейчас вроде работает четко. Есть идея отказаться от библиотеки и прописать все в коде. Там вроде несложно должно быть. Еще я хочу подавление дребезга кнопок сделать аппаратное, чтобы код упростить до минимума. И пока идут с Китая mc14490, я делаю предварительные наброски программы.
Концевики предусмотрены.
Спустя некоторое время чуть переписал код. Теперь код отслеживает изменение состояния кнопок и без библиотек. Вопрос такой возник. Поскольку отслеживается изменения состояния кнопки, то дребезг кнопок не влияет на работу кода. Но возможность поставить MC14490P для подавления дребезга у меня есть. Вопрос стоит ли добавлять аппаратное подавление дребезга к данному коду?
При delay(200) ваще пофигу должен быть дребезг при переключении.
вот это точно небезопасная архитектура:
36
pinMode(PIN_OPEN, OUTPUT);
37
pinMode(PIN_CLOSE, OUTPUT);
достаточно чуть намутить в коде и рискуешь врубить открывание и закрывание одновременно.
безопасно: одно реле на переключение режима "открывать/закрывать штору", второе реле - режим "старт/стоп открывания/закрывания".
тогда, при любых раскладах будет происходить что-то однозначно вменяемое.
ну, и аппаратные концевики - обязательно.
спрашивал выше - спрошу ещё раз: что произойдёт, если силовая часть окажется неуправляемой контроллером и на управляющих пинах силовой платы двигателя шторы начнут генериться случайные сигналы?
может нужно так сделать:
25
pinMode(PIN_OPEN_CLOSE, OUTPUT);
26
pinMode(PIN_START_STOP, OUTPUT);
и, затем уже и титановый велосипед цеплять.
спрашивал выше - спрошу ещё раз: что произойдёт, если силовая часть окажется неуправляемой контроллером и на управляющих пинах силовой платы двигателя шторы начнут генериться случайные сигналы?
может нужно так сделать:
25
pinMode(PIN_OPEN_CLOSE, OUTPUT);
26
pinMode(PIN_START_STOP, OUTPUT);
и, затем уже и титановый велосипед цеплять.
Я обдумал Ваше предложение еще в первый раз. Оно также не исключает возможности "генериться случайным сигналам на управляющих пинах". Хотя и с меньшей вероятностью.
А еще я хочу использовать твердотельные реле. Они только на вкл/выкл работают (те, которые у меня). Поэтому для переключения направления не подходят.
Я обдумал Ваше предложение еще в первый раз.
обдумал, но на прямой вопрос, заданный два раза отвечать не буду...(с)
ок. попытка номер три - опубликуйте сюда схему силовой части шторы.
Прошу прощения, на вопрос отвечаю. Если на пины будет подаваться неизвестно какой сигнал и неизвестно когда, то со шторами будет неизвестно что. Будут жить своей жизнью.
"Схему" прикладываю. Надеюсь Вас не покоробит от картинки из Fritzing. Вроде никаких подводных камней? два реле управляются двумя пинами ардуино. Провода от ардуино до реле максимально короткие и толстые.
я спрашивал, сгорит ли ваш дом после включения шторы на закрытие и открытие одномоментно?
если "да", то нужно воспользоваться моим советом.
Прошу прощения, на вопрос отвечаю. Если на пины будет подаваться неизвестно какой сигнал и неизвестно когда, то со шторами будет неизвестно что. Будут жить своей жизнью.
"Схему" прикладываю. Надеюсь Вас не покоробит от картинки из Fritzing. Вроде никаких подводных камней? два реле управляются двумя пинами ардуино. Провода от ардуино до реле максимально короткие и толстые.
С некоторой модификацией: одно реле твердотельное, второе эл.магнитное с перекидным контактом; контакты не будут срабатывать под напряжением, так что проблемы искрения, помех и т.п. неактуальны.
==============
и логика может быть такой (борьба с дребезгом не нужна):
при нажатии кнопки "против движения"
мотор стоп;
делэй;
если кнопка еще не отпущена, включаем мотор, куда надо;
какой вообще в этом всём смысл, если управление шторой ручное?
один тумблер на три положения и два концевика достаточны для комфортной эксплуатации шторы.
О_о
Как учат нас основатели дзена, смысла вообще нигде ни в чем нет.
А вообще, Вы додумываете то, чего я нигде не писал. Даже на "недосхеме" выше указан модуль ttl-rs485. С помощью которого, модули будут объединяться в сеть и иметь возможность управляться еще и удаленно. Если я про них не спрашиваю, это не значит, что их нет. Модули едут, код пишется. Я задаю простые вопросы, ответы на которые смогу понять.
Вы сами додумали за меня, что я собираюсь сделать, и объявили это фигней :) Как так-то?
Про использование твердотельного и электромагнитного реле я подумаю.
Почитайте тему http://arduino.ru/forum/programmirovanie/proshu-pomoshchi-problema-s-odnovremennoi-rabotoi-shagovykh-dvigatelei
Может найдете не только ответы но и готовое решение
Как учат нас основатели дзена, смысла вообще нигде ни в чем нет.
А вообще, Вы додумываете то, чего я нигде не писал. Даже на "недосхеме" выше указан модуль ttl-rs485. С помощью которого, модули будут объединяться в сеть и иметь возможность управляться еще и удаленно. Если я про них не спрашиваю, это не значит, что их нет. Модули едут, код пишется. Я задаю простые вопросы, ответы на которые смогу понять.
Вы сами додумали за меня, что я собираюсь сделать, и объявили это фигней :) Как так-то?
Про использование твердотельного и электромагнитного реле я подумаю.
я тебе показал архитектурную ошибку в силовой части, следствием неустранения которой ты рискуешь дистанционно сжечь свой дом.
я три раза повторил один и тот же вопрос в разных формулировках: что произойдёт, если будут включены одномоментно режимы открытия и закрытия шторы?
ответа я не получил, поэтому что бы ты не самоубился, начитавшись форума, предложил самый безопасный вариант.
Да ладно-ладно... вот с твердотельным и электромагнитным реле вроде нормальная идея.
Спасибо за советы.
Да ладно-ладно... вот с твердотельным и электромагнитным реле вроде нормальная идея.
...повбивав бы. О_о
Как учат нас основатели дзена, смысла вообще нигде ни в чем нет.
А вообще, Вы додумываете то, чего я нигде не писал.
Вы сами додумали за меня, что я собираюсь сделать, и объявили это фигней :) Как так-то?