Функция устранения дребезга кнопки. Не пойму что не так.

kost82
Offline
Зарегистрирован: 30.11.2015

Добрый день!

Пишу скетч в котором надо отслеживать нажатие тактовых кнопок. Для устранения дребезга написал небольшую функцию (ну как написал... немного изменил функцию из учебника). Здесь приведу ее упрощенный вид:

boolean debounce (boolean last) {
  boolean current = digitalRead(BUTTON);
  Serial.println(last);
  Serial.println(current);
  if (last != current) {
    delay(5);
    return digitalRead(BUTTON);
   }
}

Вызов функции такой:

if (!isStarted) {
    currentButton = debounce(LOW);
    Serial.println(currentButton);
    if (currentButton == HIGH)
    {
      isStarted = true;
      digitalWrite(LED,HIGH);
    }
  }

Кнопка подтянута к "земле" и повешена на цифровой пин №5 Ардуино Про Мини:

#define BUTTON 5

Что имеем в мониторе порта: Serial.println(last) - выводит 0, Serial.println(current) - тоже выводит 0, затем почему-то срабатывает условие if (last != current) и в итоге Serial.println(currentButton) почему-то выводит 142.

Пробовал менять везде LOW и HIGH на true и false - результат тот же самый.

У меня два вопроса: 1. Почему срабатывает (last != current) и 2. Что такое 142 в мониторе порта? Помогите разобраться плиз. Где-то туплю, но не могу понять где.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

kost82 пишет:

Здесь приведу ее упрощенный вид:

Вы издеваетесь? Вот откуда мне знать, у Вас функция неправильно написана или эта неправильность вкралась при "упрощении вида"?  Упрощённый вид будете приводить своей бабушке. Если Вам нужна помощь, приводите именно тот скетч, который не работает.

По Вашей функции debounce. Вопрос на засыаку: что именно она возвращает, если условие в строке 5 оказалось ложным?

 

kost82
Offline
Зарегистрирован: 30.11.2015

Я ее упростил и в этом виде проверил, что она тоже не работает.

Исходный вид:

boolean debounce (boolean last, int buttonPin) {
  boolean current = digitalRead(buttonPin);
  Serial.println(last);
  Serial.println(current);
  if (last != current) {
    delay(5);
    return digitalRead(buttonPin);
  }
}

Ну и вызов ее меняется, соответственно:

currentButton = debounce(LOW, BUTTON);

По задумке, если условие ложное при том, что параметр last = LOW, функция должна возвращать булево значение HIGH, считанное с 5-го контакта, а возвращает почему-то 142 (по крайней мере так в мониторе порта выводится это значение)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Повторя во второй раз

Вопрос на засыпку: что именно она возвращает, если условие в строке 5 оказалось ложным?

Не фантазируйте, а просто проведите пальце по коду и скажите что она возвращает. Задмки никому, кроме Вас неинтерсны. Давайте польцем по коду и отвечайте по факту.

kost82
Offline
Зарегистрирован: 30.11.2015

А, все, понял Вас, спасибо за наводку. Да, действительно, ничего не возвращает. Надо добавить строчку в конце:

return LOW; 

К сожалению сейчас ардуинки нет под рукой, вечером попробую и отпишусь.

Logik
Offline
Зарегистрирован: 05.08.2014

От интересно, чем Вы руководствовались, когда в ф-ию обявленную как debounce (boolean last) передали параметр LOW? Ну писали б ф-ю как const last=LOW, уж тогда бы. Зачем вообще этот параметр ;)

ПС. Я понимаю, что там откуда скопипастили он был, но философский вопрос, а зачем?

kost82
Offline
Зарегистрирован: 30.11.2015

Проверил, все работает, большое спасибо ЕвгениюП. В итоге функция получилась следующей:

boolean debounce (boolean last, int buttonPin) {
  boolean current = digitalRead(buttonPin);
  if (last != current) {
    delay(5);
    return digitalRead(buttonPin);
  }
  return last;
}

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

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