Запуск функции при долгом зажатии кнопки
- Войдите на сайт для отправки комментариев
Вс, 07/08/2016 - 06:52
Такая проблема, вроде и не сложная, но не могу понять как решить. Переделал функцию button1() на кнопке №1, что бы при обычных (коротких) нажатиях переключался regim1 на значения 0 или 1, а при удержании этой кнопки 2 или более секунд включался режим auto с функции pir() (датчика движения). Так вот, кнопка отлично переключается во всех трёх режимах, но почему то при выборе auto режима функция pir() не срабатывает. Возможно где то перепутал с условиями проверок в функции button1()....
*** boolean Status1 = true; // объявляем Status1 реле в 0, инверсия... boolean btnPress1 = false; // объявляем что кнопка №1 не нажата "0" boolean lastbtnStat1 = false; // временная переменная для хранения статуса1 int regim1 = 0; // Режимы по умолчанию при включении bool button_long_state = false; // Булево значение для выбора режима button1() uint32_t ms_button = 0; // Беззнаковый тип конкретного размера для выбора режима button1() *** void button1() { // Функция для кнопки №1 btnPress1 = digitalRead(BUTTON_1); // Считываем значение кнопки в btnPress1 Status1 = digitalRead(RELAY_1); // Считываем значение реле в Status1 if (btnPress1 && !lastbtnStat1) { // Если btnPress1 нажата и lastbtnStat1 ИСТИНА... delay(30); // защита от дребезга btnPress1 = digitalRead(BUTTON_1); // ... записываем результат в btnPress1 } uint32_t ms = millis(); //Задаём переменную для хранения времени // Фиксируем нажатие кнопки (более 10 мкр./сек.) if (btnPress1 == false && !lastbtnStat1 && (ms - ms_button) > 10) { lastbtnStat1 = true; button_long_state = false; ms_button = ms; } // Фиксируем длинное нажатие кнопки (больше или равно 2-м секундам) if ( (btnPress1 == false) && (!button_long_state) && (( ms - ms_button ) >= 2000) ) { button_long_state = true; regim1 = 2; pir(); } // Фиксируем отпускание кнопки (более 10 мкр./сек.) if (btnPress1 == true && !lastbtnStat1 && ( ms - ms_button ) > 10) { lastbtnStat1 = false; ms_button = ms; // Цикл проверки/переключения 0 и 1 режима if (btnPress1) { // Если кнопка нажата, то... regim1++; // переключаем на слежующий режим if (regim1 > 1) { // если действующий режим > второго, то... regim1 = 0; // возвращаемся на нулевой режим } } if (regim1 == 0) { // Если режим 1=0, то... Status1 = true; // Status1 ИСТИНА (инверсия для Реле) digitalWrite(RELAY_1, Status1); // Выключаем Реле №1 } if (regim1 == 1) { // Если режим 1=1, то... Status1 = false; // Status1 ЛОЖЬ (инверсия для Реле) digitalWrite(RELAY_1, Status1); // Включаем реле №1 } } lastbtnStat1 = btnPress1; // Копируем значение из кнопки в lastbtnStat1 }
Попробуем разобраться теоретически. Кнопка висит на земле. 0 нажата 1 нет. Что бы избежать дребезга и многократного срабатывания ловят переход 1-0 (или 0-1) . Считали пауза считали . Но все вся эта песня накрывается если начинается начинаем отделять короткое нажатие от длиного. Это как комьютерная мышка. Вещь простая, но что бы она работала нужно взаимодействие всей системы.
Вот какой длительности должно быть у вас длиное нажатие . Думаю 1 сек. Так вот если делать выборки с периодом 0.6 сек будет следующее. 1-1-1 клавиша не нажата. 1-0-1 короткое нажатие . 1-0-0 длительное нажатие. То есть в реальности если пользоваться таким подходом программирования , то button1(). будет длиться не меньше 1-1,5 сек. И не важно было ли нажатие, кратковеременое нажатие или длинное нажатие. И ваша система будет не реагировать ни на что, так как опрашивает клавишу.
Вот мой вариант. Попробуйте разобраться. Вот только такой стиль непривычен для остальных.
qwone, Ваши рассуждения неубедительны.
Измеряем время между нажатием и отпусканием клавиши. В зависимости от величины измеренного интервала:
- если короче 50 мс - игнорируем (считаем, что это дребезг),
- если от 50 до 2000 мс - интерпретируем как короткое нажатие,
- если больше 2000 мс- интерпретируем как длинное.
Кнопка срабатывает в момент отпускания. Никаких дополнительных задержек нет.
есть куча готовых библиотек с учётом длительного нажатия кнопки
да и Клапауций здесь выкладывал свой класс для кнопки
есть куча готовых библиотек с учётом длительного нажатия кнопки
да и Клапауций здесь выкладывал свой класс для кнопки
Поделитесь ссылочками или названиями библиотек, которые выполняют те действия, которые нужны в конкретном случае для моего проекта, спасибо.
На пару тем выше Вашей смотрите.
OneButton
ClickButton
http://arduino.ru/forum/programmirovanie/klass-titanovyi-velosiped-dlya-...
Такая пробемка с преобразованием данных появилась. При компиляции ругается на: btnPress1 = digitalRead(BUTTON_1);
Появляется такая ошибка при незакомментированном pinMode:
Ошибка такая, если закомментирываю pinMode:
Правильно ругается.
Даже не видя библиотеку, видно, что читаете состояние кнопки Вы явно неправильно.
Судя по строке 17, BUTTON_1 - это объект, а для digitalRead нужен номер пина.
есть куча готовых библиотек с учётом длительного нажатия кнопки
да и Клапауций здесь выкладывал свой класс для кнопки
я запрещаю кретинам пользоваться умными вещами
delay(30);
// защита от дребезга
Ладно выложу свой рабочий код . Мож потом пригодится кому-то
Это яндекс диск https://yadi.sk/d/B-xRa1fXu3aEq
ПС: В качестве кнопки для отладки я использовал Джойстик http://greenchip.com.ua/23-0-146-0.html
В предыдущем посте Калапуцций носом ткнул в дилей30, а Вы следом дилей30 и выложили..... )
Клапауций отвечает за свой код, а я за свой. Свой я проверяю на макетке.
1)Если у вас прерывание в программе найдите замену. 2) этот код будет работать в простых не накрученых программах, за сложные я не отвечаю.
А теперь тоже самое но на базе Енкодера http://www.banggood.com/ru/KY-040-Rotary-Decoder-Encoder-Module-For-Arduino-AVR-PIC-p-914010.html
"Короткое нажатие" "длиное нажатие" "по часовой" и "против часовой".
Код на диске http://yadi.sk/d/iZ7XcUs-u3ss7
бля. delay(30);
бля. delay(30);
Точно Делай 30. Без этого ну никак.
Точно Делай 30. Без этого ну никак.
ну, прекращай этот тупняк - или используй делай везде, или не используй нигде
Раз не нравится delay() используй antidelay();
Раз не нравится delay() используй antidelay();
и, в чём разница?
чЁ сума сходить и так фанатически реагировать на функцию delay? Это же не супер проект всемирный какой то, главное что бы программа работала достаточно стабильно - остальное дело хозяйское, кто как хочет, тот так и создаёт код.
чЁ сума сходить и так фанатически реагировать на функцию delay? Это же не супер проект всемирный какой то, главное что бы программа работала достаточно стабильно - остальное дело хозяйское, кто как хочет, тот так и создаёт код.
у тебя на автомобиле диски одинаковые или три автомобильные, а один от велосипеда?
как по мне - если в коде, который наследует принцип Мигаем светодиодом без delay() , внезапно попадается delay, то это свидетельствует о том, что пейсатель кода нихрена не понял и не поймёт никогда.
Против delay() можно сказать одно . Команда режет прерывание. antidelay() же этого не делает. Если чел не понимает разницы, то это только его проблемы. Если при этом он и "заводится", то можно забить на комплексы этого чела. Программа работает. Кто хочет может взять код, кто не хочет, тот может идти лесом. Я не пользуюсь принципом МИГАЕМ БЕЗ DELAY. Я прользуюсь инструментом millis.Когда решает проблему использую, только и всего. Если у вас есть личный автомобиль это не значит, что вы обязаны ездить на работу на нем. Можно ездить на работу на маршрутке, автобусе, трамвае, на электричке. Хотя бы потому что, так дешевле и удобнее для некоторых людей.
Можно ездить на работу...
ясно - ты из тех, кто ходит на работу пешком в разных носках.
Для тех кто из леса добавлю. Я хожу на работу еще и разными ногами- одной правой и одной левой. А не тремя правыми ногами.
Клапауций 232, Не надо быть таким принципиальным человеком, мы все поняли, что ты офигенный программист, можешь не доказывать это. Если не нравится delay() - не пользуйся, твоё дело и что то доказывать ненужно никому.
чё ругаться то.
ну пусть с делеями код используют если хочется.
я делеи не люблю, хотя тоже иногда применяю))))
Ладно выложу свой рабочий код . Мож потом пригодится кому-то
Это яндекс диск https://yadi.sk/d/B-xRa1fXu3aEq
ПС: В качестве кнопки для отладки я использовал Джойстик http://greenchip.com.ua/23-0-146-0.html
Спасибо, поразбираюсь как он работает на будущее
Продолжаю выкладывать программы на эту тему .
С помощью этого джойстика http://greenchip.com.ua/23-0-146-0.html и программы можно подавать команды на 9 устройств(левовверх-0 ,, правовниз 8) Для примера 8 устройство это светодиод 13 короткое включить длиное выключить
Место для скачки программы https://yadi.sk/d/SYEYuaJ0u5mAr