Сообщение от
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