Добрый День! Это мое первое сообщение на этом форуме, прошу не пинать
Подскажите пожалуйста алгоритм преодаления дребезга контактов 1) с исключением повтора нажатия кнопки 2) без использования задрежки
в кратце о схеме на одном входе atmega8 речезе АЦП подключено 10 кнопок, через резистры разных номиналов происходит деление напряжения.
алгоритм работы такой 1) настроено прерывание по изменению АЦП 2) если оно входит в заданный диапазон значений, то переменной присваивается номер нажатой кнопки (Key) 3) если этот номер повторяется в течении 100 преобразований то значит дребезга нет 4) вызываю функцию соответсвующей нажатой кнопке (функция тригерная - первый заход один результат, второй другой) 5) ...
вот тут и начинается проблема функия вызывается много раз
добавил еще один флаг, который обнуляется каждую секунду, стало лучше , но тк секундный таймер тикает постоянно, а нажатие может попасть в середину или конец секунды и соответственно происходит задвоение нажатия
Код:
//защита от дребезга и не только. если нажата какая-нибудь кнопка //сравниваем совпадают ли текущее состояние и предыдущее //если совпадают - проверяем счетчик comp, если нет обнуляем его //кнопка считается нажатой если она удерживается в течении 100
if (Key) { if (Key == LastState) { if (comp > 100) { if (Key!=LastBut) { Key_p=Key; out_trig(); // выполняю действия LastBut = Key; // переменную lastBut сбрасываю каждую секунду } else {
воспользуйтесь поиском по форуму: я давал ссылку на свои исходники, в котрых есть почти универсальный алгоритм работы с кнопками, воспользуйтесь. избежать повтора реакции можно только сравнением текущего кода кнопки с предыдущим, никакие таймеры тут не требуются
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
с дребезгом более менее все ок, проблема с повтором
как обойтись без таймера?
если я нажимаю одну и туже кнопку два раза подряд то должна срабатывать соответсвенная функция как отличить мое повторное нажатие от "задвоения" результата от АЦП?
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
с дребезгом более менее все ок, проблема с повтором как обойтись без таймера?
не смотрел исходники ARV, извиняюсь, если повторяю алгоритм. У меня было реализовано почти как у Вас, karimm, но я ввел флаг не секундного таймера, а флаг того, что кнопка уже нажата. в прерывании, где Вы определяете нажатую кнопку, после проверки значения счетчика длительности нажатия (в Вашем коде это переменная comp), добавьте проверку этого флага. Если флаг уже возведен, то значит функция, назначенная кнопке уже была выполнена и еще раз ее выполнять не нужно. Если флаг не возведен, выполняете действие и возводите этот флаг. В самом начале прерывания, если не нажата ни одна кнопка (у Вас же есть такое значение АЦП?), сбрасываете этот флаг.
Еще, т.к. у Вас много кнопок, а на каждую заводить счетчик comp нет смысла, и значения АЦП могут иногда скакать, я бы посоветовал Вам завести счетчик прерываний, а не счетчик для каждой кнопки, просто суммировать 128 значений АЦП подряд, а на 128ое прерывание делить значение суммы на 128 (= сдвиг на 7 разрядов вправо) и проверять в какой интервал попадает усредненное значение. Я так делал. Стабильных нажатий стало больше.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
не понял зачем заводить переменную для каждой кнопки?
вот как сделал определение нажатой кнопки
есть массив btn_arr в котором записаны расчетные значения ацп для каждой кнопки, для того чотбы точно отловить нужную кнопку проверяю входит ли значение полученное с АЦП в диапазон х+rk дальше все понятно
у меня в схеме параллельно кнопкам размещен конденсатор, и пока он разряжается/заряжается показания АЦП могут плавать, по этому решил вылавливать поворные попадания в заданный диапазон
Ну вот смотрите: у вас программа работает так: 1) прерывание АЦП - выявление кода нажатой кнопки. (ну пусть 100 тактов) 2) устранение дребезга и выполнение действия (ну пусть 50 тактов) 3) возврат к пункту 1) (и так 100 раз). итого за 100 прерываний АЦП - забито 15000 тактов процессорного времени
Я предложил (для простоты возьмем не 128, как я сказал, а 100 прерываний): 1) прерывание АЦП, суммирование результата (пусть 20 тактов) 2) 100 прерываний прошло? (пусть 20 тактов) да) деление на 100 и выявление нажатой кнопки (пусть 300 тактов, в случае деления на 128 это около 10+100 тактов) нет) выход 3) устранение дребезга если было выявление нажатой кнопки(если (Key!=KEY_NULL) ) (50 тактов) итого за 100 прерываний АЦП - забито (20+20)*100+300+50=4350 тактов. выигрыш в 3 раза. и еще не нужны кондеры на входе АЦП)
насчет счетчиков на каждую кнопку, я погорячился, сначала не разглядел полностью Ваш алгоритм.
Если в Асме разбираешься, то посмотри, как сделано подавление, задержки и автоповтор. Из основного цикла подпрограмма вызывается, проверяется код нажатой кнопки и выполняется действие. Для твоего случая нужно только изменить ПП предварительного ввода.
//защита от дребезга и не только. если нажата какая-нибудь кнопка //сравниваем совпадают ли текущее состояние и предыдущее //если совпадают - проверяем счетчик comp, если нет обнуляем его //кнопка считается нажатой если она удерживается в течении 100
if (Key) { if (comp++ > 100) { Key_p=Key; out_trig(); // выполняю действия } } else // кнопка не нажата { comp = 0;
} StartConvAdc(); //запускаем преобразование и выходим
2) ... вставить нужное:
Код:
// Где-нибуть выше int KeyPressed = 0;
...
//защита от дребезга и не только. //кнопка считается нажатой если она удерживается в течении 100
if (Key) { if (!KeyPressed && comp++ > 100) { KeyPressed = 1; //Key_p=Key; //out_trig(); // выполняю действия out_trig(Key); // Лучше всё же так. По усмотрению. } } else // кнопка не нажата comp = KeyPressed = 0;
StartConvAdc(); //запускаем преобразование и выходим
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 13
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения