2015-07-07 2 views
1

Я пытаюсь работать с простой схемой Arduino, которая увеличивает счетную переменную при нажатии кнопки в цепи (подключенной как INPUT to PIN 8). Мой код такой же простой:Использование PushButton в качестве триггера в Arduino

#include <LiquidCrystal.h> 

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 
int c = 0, btnPIN, btnVal; 

void setup() 
{ 
    btnPIN = 8; 
    pinMode(btnPIN, INPUT); 

    lcd.begin(16,2); 
    lcd.clear(); 
} 
void void loop() 
{ 
    btnVal = digitalRead(btnPIN); 
    if (btnVal == LOW) 
    { 
     c++; 
     lcd.clear(); 
     lcd.print(c); 
    } 
} 

Проблема: счетчик увеличивается более чем на 1 при каждом нажатии кнопки. Немного печатается на последовательном мониторе, что каждый раз, когда кнопка нажата, а напряжение LOW, условный код выполняется несколько раз, а счетчик увеличивается на несколько раз вместо 1.

Возможно, мне нужно напишите какую-нибудь логику, которая проверяет, была ли кнопка первоначально отключена, затем нажата, а затем снова отпущена, а затем эти шаги вызовут требуемое действие.

Решение, которое я сейчас работаю с как в соответствии с (который прекрасно работает):

int btnStatus = 0; 
void loop() 
{ 
    btnVal = digitalRead(btnPIN); 

    if (btnVal == LOW) 
     btnStatus = 1; 
    if(btnStatus == 1 && btnVal == HIGH)  
    { 
     c++; 
     lcd.clear(); 
     lcd.print(c); 
     btnStatus = 0; 
    } 
} 

Я не уверен, если есть более простое решение, доступное или, если такой подход является неправильным по другим причинам? Любые советы были бы очень желанными!

ответ

1

Ваша идея правильная, вам нужно отслеживать предыдущее состояние кнопки, чтобы узнать, является ли это новое нажатие или просто удерживается. Ваш код может быть переписан более похожим на государственной машине, однако:

typedef enum { 
    BTN_STATE_RELEASED, 
    BTN_STATE_PRESSED 
} ButtonState; 

ButtonState btnStatus = BTN_STATE_RELEASED; 

void increment_counter() 
{ 
    c++; 
    lcd.clear(); 
    lcd.print(c); 
} 

void loop() 
{ 
    btnVal = digitalRead(btnPIN); 

    switch(btnStatus) 
    { 
    case BTN_STATE_PRESSED: 
     // Handle button release 
     if(btnVal == HIGH) 
     { 
      btnStatus = BTN_STATE_RELEASED; 
     } 

     break; 

    case BTN_STATE_RELEASED: 
     // Handle button press 
     if(btnVal == LOW) 
     { 
      increment_counter(); 
      btnStatus = BTN_STATE_PRESSED; 
     } 
     break; 
    } 
} 

Это был переписан, чтобы использовать перечисление для отслеживания состояния системы (немного избыточна для простой кнопки, но важная концепция знать, в случае, если ваша система становится более сложной).

Код для обновления дисплея также был перемещен в его собственную функцию, чтобы сделать его лучше отделенным между изменением отображения и фактическим обновлением состояния.

+0

Спасибо! Этот подход выглядит как более чистый и организованный способ добиться успеха, поскольку схема усложняется. Я на самом деле собираюсь использовать три кнопки, чтобы это помогло! –

2

Другая проблема, с которой вы можете столкнуться, состоит в том, что механические кнопки bounce. То есть, они прыгают между двумя позициями несколько раз быстро, прежде чем перейти к последней позиции. Это стандартная операция, поэтому необходимо «отменить» кнопку.

Существует очень много способов сделать это, но Here - это учебник с использованием Arduino.

Основная проблема, как вы, вероятно, выяснили, заключается в том, что функция loop вызывается несколько раз, пока кнопка не работает. Это то, что исправлено вашим кодом, и ваш выглядит хорошим решением, и я действительно не вижу более простого способа. Для другого способа, возможно, вы могли бы попробовать просто добавить звонок в delay в конце loop, чтобы немного замедлить его. Вам придется немного поиграть с задержкой, но это может сработать. На самом деле, ваше решение выглядит просто отлично.

+0

Спасибо, я не знал о проблеме отказов. –