Как починить дребезг контактов?

У меня есть код, который выводит в консоль 0 если ток через кнопку не проходит, и выводит 1, если ток проходит(кнопка on/off).

Так получается, что когда я её нажимаю у меня в консоли 111111111111, всё стабильно.

Но когда я её отпускаю вместо требуемого 0 у меня 011101010101001010101 и тп.

Как это можно починить?

void gameMode2() {
  lcd.clear();

  while (true) {
    int pinState = digitalRead(11);

    if (pinState == HIGH) {
      Serial.println("1");
    } else {
      Serial.println("0");
    }

    delay(100);
  }
}

Ответы (2 шт):

Автор решения: Eugene X

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

Если ты новенький и не хочеться возиться с этим хламом вовсе, то есть крутая библиотека Button2 где за тебя всё это давно написали и вывели всё максимально просто.

Если сделать своими ручками то самый простейший код для реализации

#define button1_pin 7
#define button2_pin 8
int button1_state = 0;
unsigned long button1_debounce = 0;
int button2_state = 0;
unsigned long button2_debounce = 0;

void button_StateChange(int button, int newState) {
  if (newState == HIGH) {
    // кнопка {button} нажата
  } else {
    // кнопка {button} отпущена
  }
}

void setup() {
  pinMode(button1_pin, INPUT_PULLUP);
  pinMode(button2_pin, INPUT_PULLUP);
}

void loop() {
  int state;
  unsigned long time_now;
  // кнопка 1
  state = digitalRead(button1_pin);
  time_now = millis();
  if (state != button1_state) {
    if (time_now < button1_debounce) {
      button1_debounce = time_now + 500;
      button_StateChange(button1_pin, state);
    }
  }
  // кнопка 2
  state = digitalRead(button2_pin);
  time_now = millis();
  if (state != button2_state) {
    if (time_now < button2_debounce) {
      button2_debounce = time_now + 500;
      button_StateChange(button2_pin, state);
    }
  }
}

Если ты клёво разбираешься в схемах и сам делаешь платки то есть пара крутых схемок реализовать это в железе.

Реализация на кондесаторе и резисторе, где конденсатор как раз и работает как задержка Реализация на кондесаторе и резисторе, где конденсатор как раз и работает как задержка

Реализация на быстром диоде Реализация на быстром диоде

→ Ссылка
Автор решения: Герман Борисов

Судя по тому, что смена состояний продолжается значительно дольше 100 мс, это не дребезг контактов, а наводки. Электронщики говорят что ножка контроллера "висит в воздухе", и её нужно либо подтянуть к питанию, либо прижать к земле, чтоб не болталась.

Для этого есть два способа.

  1. Внешний резистор.

Резистор сопротивлением не менее 10 кОм одним контактом соединяется с ножкой контроллера, а другой с питанием или нулём, в зависимости от того, с чем соединяется кнопка в замкнутом состоянии. Если кнопка замыкает на ноль, то к питанию, если на питание, то с нулём. У вас, похоже, последний вариант.

  1. Внутренний подтягивающий резистор.

У контроллеров Atmega, на которых строится Arduino, есть внутренний подтягивающий резистор, который можно программно подключать и отключать. Но только на линию питания. Придётся изменить схему и скетч так, чтоб кнопка замыкала ножку на землю, а не на питания, а скетч воспринимал HIGH как "кнопка не нажата", а LOW как "кнопка нажата".

Включается внутренний резистор довольно просто:

pinMode(pin, INPUT);     // назначить порту режим ввода
digitalWrite(pin, HIGH); // включить подтягивающий резистор

Если порт останется в режиме вывода, то замыкание его на землю просто спалит контроллер. Собственно как и замыкание на питание, если в режиме вывода там был нулевой сигнал.

→ Ссылка