КАК УСТРАНИТЬ ДРЕБЕЗГ КОНТАКТОВ [Уроки Arduino #8]

preview_player
Показать описание
__________________________________________________
В уроке использовались следующие компоненты:
В следующих уроках вам может потребоваться:
______________________________________
В этом выпуске вы узнаете: что такое дребезг контактов у кнопок, как устранить дребезг контактов в проектах ардуино с кнопками
___
Смотрите наши видео, в которых мы простым языком рассказываем о радиотехнике, электронике и радиоэлектронике!
Наши уроки будут особенно полезны для начинающих радиолюбителей и студентов радиотехнических ВУЗов.
В видеороликах мы даём основы электроники: определения, описания, схемы и принцип работы различных элементов радиотехники.
В наших видео вы узнаете: что такое транзистор, диод, конденсатор, резистор, микросхема, электрический ток и много других разных интересных вещей и явлений, связанных с электроникой.
Рекомендации по теме
Комментарии
Автор

До этого урока все было понятно. Неплохо было бы прилагать описание всех новых функций или переменных в каждом видео. Спасибо за внимание.

maksymnepomiashchyi
Автор

Тримайте Скетч


int led = 9;
int button = 2;
boolean lastButton = LOW;
boolean currentButton = LOW;
boolean ledOn = false;
void setup() {
pinMode(led, OUTPUT);
}
boolean debounce(boolean last){
boolean current = digitalRead(button);
if(last != current){
delay(5);
current = digitalRead(button);
return current;
}
}

void loop() {
currentButton = debounce(lastButton);
if(lastButton == LOW && currentButton ==HIGH){
ledOn = !ledOn;
}
lastButton = currentButton;
digitalWrite(led, ledOn);
}

maksymkrokhmaliuk
Автор

в функции debounce вне тела if{ } следует добавить return, иначе при last == current тело if { } не выполнится и функция не будет иметь возвращаемый параметр

jeqoner
Автор

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

anlaz
Автор

Спасибо автору за интересный и познавательный канал, часто смотрю Ваши видео.
Но не смог удержаться от критики данного "урока":
- в части касающейся устранения дребезга контактов - это не урок, а скороговорка по мотивам Блюма (урок создаётся чтобы научить, здесь же НЕ программисту абсолютно ничего не понятно);
- постарайтесь правильно произносить транскрипции английских слов (раз уж видео относится к категории НАУКА и техника), реально режет слух;
- повторюсь, не торопитесь, для Вас это может очень просто, но когда начинающий слышит "многоновыхслов" ещё и с не правильной транскрипцией, получается каша в голове.

МаксимовАндрей-цш
Автор

Так тоже можно:
const int LED=9;
const int BUTTON=2;
bool isWork = false;
bool isReady = true;
void setup ()
{
pinMode (LED, OUTPUT);
pinMode (BUTTON, INPUT);
}
void loop()
{
if(digitalRead(BUTTON)==HIGH && isReady == true)
{
delay(5);
isWork = !isWork;
digitalWrite(LED, isWork);
isReady = false;
}
else if (digitalRead(BUTTON)==LOW && isReady == false)
{
isReady = true;
}
}

Dizel
Автор

Давайте попробую объяснить откуда что взялось.
Ниже код и построчно порядок его выполнения:

пропустим выполнение присвоения значений переменным (тут думаю всё понятно), начнём с цикла:

const int LED=9;
const int BUTTON=2;
boolean lastButton = LOW;
boolean currentButton = LOW;
boolean ledOn = false;

void setup ()
{
pinMode(LED, OUTPUT);
pinMode(BUTTON, INPUT);
}

boolean debounce(boolean last) // (2) Начало функции debounce, в скобках объявляется новая переменная last, так же как они прописывались в самом начале кода, этой переменной сразу задаётся значение lastButton, переданное из первого пункта (значение LOW)
{
boolean current = digitalRead(BUTTON); // (3) Объявляется новая переменная current, ей присваивается значение считанное с контакта кнопки, если мы её нажали то значение HIGH
if (last != current) // (4) Проверка на выполнение условия - Если last (значение LOW) не равно current (значение HIGH), а в нашем примере это так то выполняется следующий код в фигурных скобках
{
delay (5); // (5) задержка 5 мсек, за это время дребезг кнопки успокаивается
current = digitalRead(BUTTON); // (6) переменной current задаётся значение с кнопки (значение HIGH)
return current; // (7) эта строчка передаёт значение переменной current как значение функции debounce, возвращаемся к первому пункту (на пункт 8)
}
}
void loop()
{
currentButton = debounce(lastButton); // (1) переменной currentButton присваивается значение lastButton, после выполнения функции debounce. Для этого программа переходит выполнять функцию debounce и передаёт в неё значение в скобках - lastButton.
// (8) теперь когда выполнилась функция debounce - она фактически приняла значение переменной current (значение HIGH), то есть currentButton = debounce(lastButton) = current = HIGH
if (lastButton == LOW && currentButton == HIGH) // (9) Проверка на выполнение условия: если lastButton(значение LOW) равно LOW и если currentButton (значение HIGH) = HIGH то выполняется то выполняется следующий код в фигурных скобках
{
ledOn = ! ledOn; // (10) Значение переменной ledOn становится противоположным, в данном случае оно было false(пер. - "ложное", выключен, LOW), становится true (пер. "правда", включено, HIGH)
}
lastButton = currentButton; // (11) переменной lastButton (значение LOW) присваивается значение currentButton (значение HIGH)
digitalWrite(LED, ledOn); // (12) передает на контакт с номером LED значение переменной ledOn (значение true, тоже самое что HIGH), диод загорается.
}

Поправьте знатоки если что не так, сам учусь, тоже трудно понять было, хорошо что есть кому объяснить.

Bk-qwtg
Автор

Оставляйте ссылку на скетч в описании!

egor_manakovv
Автор

Я просто паял "кандик" параллельно с кнопкой. Пока кнопка не нажата, кандик заряжен, когда нажимаем, мы закорачиваем контакты и сбрасываем заряд. Т.к. заряд не пополняется мгновенно, то пока идет дребезг контактов кнопки кандик все еще разряжен(точнее не до заряжен). Когда кнопка отпущена полностью идет зарядка и выполняется действие от кнопки.
Если коротко, то срабатывание кнопки происходит не по нажатию, а по отпусканию.

Автор

Спасибо за урок. Очень быстро описываете программный код и очень трудно понять. :(

aras_mileska
Автор

"ожидаем 5 секунд". Я понимаю что автор возможно оговорился, но в delay() значения задаются в мс, и поэтому есть немного разница между 5с и 5мс. Но в целом видео очень полезное.

vladchernov
Автор

Вроде всё доступно и просто.

Хочется отметить однако, что использование функции бесполезного простоя delay() не есть труъ в общем случае, ведь камушек остаётся не занят ничем, а только ждёт столько, сколько скажут.

Для простых задач быстрого кодинга прокатит, но для более сложных всё-таки хочется обработку нажатия кнопок с учётом дребезга вывести на прерывания. Самым простым и эффективным мне видятся прерывания по таймеру (~ 1 ms) с использованием сдвигового регистра для набора статистики нажатия на кнопку. Для таких кнопок работает на ура. Но бывают и более проблемные варианты, когда используется, например, плёночная клавиатура, для которой в любой момент времени во время нажатия может прийти ложный сигнал отпускания с длительностью до 5 ms. В этом случае приходится использовать счётчики нажатия с условиями по нажатию и отпусканию. Это весьма усложняет механизм, зато делает возможным анализ и таких вещей, как двойное нажатие, длительное удержание и другие более экзотические варианты.

KKKompot
Автор

у меня вопрос по "функции сглаживания дребезга" : там вместо введенных переменных currentButton и lastButton пишет просто current и last, это их сокращенный вид, который тоже понятен программе? или я что-то не понимаю?

MrSploker
Автор

Уважаемые радиолюбители, подскажите, пожалуйста, почему файлы-sketch  для Arduino могут иметь различные расширения:  одни файлы имеют расширение INO (.ino), а другие - PDE (.pde)? В чём отличие таких файлов? Каким образом в программном обеспечении Arduino можно изменить по умолчанию тип расширения сохраняемого файла-sketch? Спасибо! С уважением, Валерий.

ВалерийМелехов-мг
Автор

"return current" нужно поместить после блока if.

zlodes
Автор

Ооочень быстро говорит, я не успеваю осмыслить сказанное((

nahatakobato
Автор

Хорошее видео. Ну да, приходится в интернет заходить и смотреть обозначение операторов, функций и всего непонятного))) Зато много читаешь и узнаешь что-то новое. Очень хорошее видео. Код написал и на тебе ошибку))), а где и что делать. Искал, перечитывал код и когда перечитывал, то и суть кода становится ясна. Да есть свои нюансы, но зато ты их сам исправляешь, а это важно (мыслишь Ты, а не тот кто рассказывает). Скажу от себя, каждый воспринимает информацию по своему, кому-то подавай всё готовое, а кто-то любит что-то сам додумать. У меня знание ПК и всех этих кодов Нулевое, но я всё понимаю, да не с первого раза, не за 6 минут, а за 20. Молодец, так держать.

starwind
Автор

Здравствуйте. Не могли бы вы пояснить мне некоторый момент из данного урока. После первого нажатия кнопки удовлетворяется условие (lastButton == LOW && currentButton == HIGH) из цикла loop() и переменная ledOn приобретает значение HIGH и светодиод загорается, это понятно. Но почему после второго нажатия происходит присвоение переменной ledOn значения LOW, ведь для этого нет никаких видимых причин?

movsarayubov
Автор

int LEDpin = 9; // Светодиод на входе 9
int switchPin = 2; // выключатель на порту 2, замыкает на землю

boolean running = false;

void setup()
{
pinMode(LEDpin, OUTPUT);
pinMode(switchPin, INPUT);
digitalWrite(switchPin, HIGH); // включаем подтягивающий резистор
}

void loop()
{
if (digitalRead(switchPin) == LOW)
{ // выключатель нажат, т.к. подтягивающий резистор будет давайть HIGH на входе, если не замкнут напрямую на землю
delay(500); // ждем 0.5сек
running = !running; // меняем значение булевой переменной
digitalWrite(LEDpin, running); // включаем или выключаем светодиод.
}
}
Делэй решает проблему дребезг контактов.

Grey-cd
Автор

Здравствуйте, Я с большим трудом продираюсь через дебри программирования.
У меня к вам просьба.
Прошу написать несколько строчек кода, которые выполняют следующее:

На воды D2 и D3 заранее подаются команды в двоичном коде
00
01
10
11

Как заставить скетч на каждое из этих двоичных чисел выполнять различные части программы.

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

anlaz