Как починить дребезг контактов?
У меня есть код, который выводит в консоль 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 шт):
Называеться это 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 мс, это не дребезг контактов, а наводки. Электронщики говорят что ножка контроллера "висит в воздухе", и её нужно либо подтянуть к питанию, либо прижать к земле, чтоб не болталась.
Для этого есть два способа.
- Внешний резистор.
Резистор сопротивлением не менее 10 кОм одним контактом соединяется с ножкой контроллера, а другой с питанием или нулём, в зависимости от того, с чем соединяется кнопка в замкнутом состоянии. Если кнопка замыкает на ноль, то к питанию, если на питание, то с нулём. У вас, похоже, последний вариант.
- Внутренний подтягивающий резистор.
У контроллеров Atmega, на которых строится Arduino, есть внутренний подтягивающий резистор, который можно программно подключать и отключать. Но только на линию питания. Придётся изменить схему и скетч так, чтоб кнопка замыкала ножку на землю, а не на питания, а скетч воспринимал HIGH
как "кнопка не нажата", а LOW
как "кнопка нажата".
Включается внутренний резистор довольно просто:
pinMode(pin, INPUT); // назначить порту режим ввода
digitalWrite(pin, HIGH); // включить подтягивающий резистор
Если порт останется в режиме вывода, то замыкание его на землю просто спалит контроллер. Собственно как и замыкание на питание, если в режиме вывода там был нулевой сигнал.