Клавиатура и дребезг контактов.
Надо соорудить маленькую клавиатурку.
Нашел пример матричной клавиатуры и библиотечки к ней, но она хороша, когда надо использовать много кнопок.
http://www.arduino.cc/playground/Main/KeypadTutorial
Для клавиатуры из 3х кнопок проще использовать 3 пина ардуины, на которые комутировать лог. "1" и readDigitalPin();
Но как обстоят дела с дребезгом контактов и как определять что кнопка зажата на долгое время (как при настройке часов) и в этом случае изменять какое-то значение не плавно, а с каким-то промежутком?
Re: Клавиатура и дребезг контактов.
Re: Клавиатура и дребезг контактов.
спасибо, буду иметь ввиду.
Re: Клавиатура и дребезг контактов.
Цитата:
Сообщение от
nevsky
Но как обстоят дела с дребезгом контактов и как определять что кнопка зажата на долгое время
Я для этих целей пользуюсь прерываниями:
Код:
#define sbi(port, bit) (port) |= (1 << (bit))
#define cbi(port, bit) (port) &= ~(1 << (bit))
// Ножка, на которой кнопка
#define BUT 1
// сколько времени запущены
volatile unsigned long uptime = 0;
// нажата ли кнопка
volatile byte pressed = 0;
// Через сколько секунд считать, что кнопка нажата
#define PRESSED 2
void setup()
{
// поддтягиваем кнопку к +5В - т.е. кнопка между выводом BUT и землей (0В)
digitalWrite(BUT, HIGH);
TCCR1A = 0;
// устанавливаем /8 - получается 16MHz/8
// т.е. счетчик таймера увеличивается на одно значение каждые
// 0,0000005 секунд
cbi(TCCR1B, CS12);
sbi(TCCR1B, CS11);
cbi(TCCR1B, CS10);
// устанавливаем начальное значение счетчика в 65535 - 20000 = 45535 = 0xB1DF
// т.е. прерывание будет раз 0.01 секунду
// (16MHz/8/20000 - 100 раз в секунду)
TCNT1 = 0xB1DF;
// разрешаем прерывания таймера по переполнению
sbi(TIMSK1, TOIE2);
}
ISR(TIMER1_OVF_vect)
{
// храним число прерываний = для
static unsigned char loop_cnt = 0;
// заново устанавливаем счетчик
TCNT1 = 0xB1DF;
loop_cnt++;
if (loop_cnt == 100) // секундный интервал
{
uptime++;
loop_cnt = 0;
// для наглядности моргаем светодиодом на 13-й ноге
digitalWrite(13, !digitalRead(13));
// проверяем, как долго нажата кнопка - если более PRESSED секунд - то устанавливаем, что нажата
static unsigned char tp_cnt = 0;
if (digitalRead(BUT) == 0)
{
// нажата
tp_cnt++;
if (tp_cnt > PRESSED)
{
pressed = 1;
}
}
else
{
// отжата
pressed = 0;
tp_cnt = 0;
}
}
}
void loop()
{
// тут проверяем, нажата ли кнопка более PRESSED секунд
if (pressed)
{
// делаем то, что надо
}
}
В данном примере кнопка считается нажатой, если её держат 2 секунды.
Я думаю дальше понятно что и как.
Используя uptime можно легко считать секунды - тоже тут применимо.
Вообще существет либа для антидребезга - Debounce :)
http://www.arduino.cc/en/Tutorial/Debounce
Re: Клавиатура и дребезг контактов.
Я думал о прерываниях, но немного в другую сторону, внешнее прерывание по нажатию на кнопку.
А прерывание по переполнению и читать нажата или нет, это хороший вариант.
можно делать несколько интервалов
Код:
#define PRESSED_ONE 1
#define PRESSED_TWO 2
...
...
...
if (tp_cnt > PRESSED_ONE && tp_cnt < PRESSED_TWO) {
/// Кратковременное нажатие
}
if (tp_cnt > PRESSED_TWO) {
/// Долгое нажатие
}
только сократить временной интервал, не секунду, а 0.25
если надо использвать uptime, то
Код:
if (loop_cnt == 100) {
uptime++;
}
if (loop_cnt == 25) {
...
спасибо всем.
Re: Клавиатура и дребезг контактов.
Цитата:
Сообщение от
nevsky
Я думал о прерываниях, но немного в другую сторону, внешнее прерывание по нажатию на кнопку.
Я тоже по началу так думал.
Но дребезг контактов будет порождать кучу прерываний.
Так что работу по прерыванию таймера с клавиатурой - эту идею я вынес ("спёр") очень давно, когда отладчиком шарился в ПЗУ Ямахи MSX2 году эдак в 91-м :)))
Re: Клавиатура и дребезг контактов.
Получается для того что бы исключить дребезг надо делать задержки по времени, не проще ли применять бездребезговые кнопки или они не нашего формата будут?
Re: Клавиатура и дребезг контактов.
Цитата:
Получается для того что бы исключить дребезг надо делать задержки по времени, не проще ли применять бездребезговые кнопки или они не нашего формата будут?
Тогда наверно проще использовать конденсатор параллельно кнопке.
Re: Клавиатура и дребезг контактов.
Цитата:
Сообщение от
Chip
Тогда наверно проще использовать конденсатор параллельно кнопке.
Кроме конденсатора можно использовать RS-триггер или библиотеку Bounce. Программный способ не удобен задержками в реакции.
Re: Клавиатура и дребезг контактов.
Цитата:
Сообщение от
Азимут
Кроме конденсатора можно использовать RS-триггер или библиотеку
Bounce. Программный способ не удобен задержками в реакции.
Если RS-триггер проще в реализации чем конденсатор, то можно и его использовать
Re: Клавиатура и дребезг контактов.
зачем сложности с таймерами или аппаратными способами - классический способ подавления дребезга контактов:
читаем состояние кнопки многократно. Кнопка считается находящейся в каком-то состоянии (нажата или ненажата), если удалось прочитать подряд это состояние, некоторое количество раз, например 100, зависит от качества кнопки и скорости программы.
Re: Клавиатура и дребезг контактов.
Если использовать задержки , то при коротких нажатиях кнопки будет медленная реакция или нужно например первое нажатие 400мс а потом повторы с интервалом 100мс
Програмное решение здесь
Re: Клавиатура и дребезг контактов.
Нашел MC14490: отфильтровывает дребезг, 6 входов/выходов.