"Это точно" (с)
Не меняя сути моего предложения, слегка модифицированный и оптимизированный вариант:
Такая схема, при всей простоте, обеспечивает прекрасную помехоустойчивость. Кнопки можно выносить на несколько метров, а все резисторы надо располагать поближе к микроконтроллеру.
Алгоритм тот же что и ранее, но распишу его более подробно:
- Опрос производится циклически, длительность полного цикла 10 мс. Можно и по прерываниям, но будет сложнее.
- Цикл исполняется с шагом 0.5 мс. Для другого шага надо пересчитать номиналы деталей в схеме
- В начале цикла настраиваем GPIO пин на вывод и подаем на него "единицу", чтобы зарядить С1.
- Первый шаг цикла (после 0.5 мс с начала цикла). С1 заряжен. Настраиваем GPIO пин на ввод, обнуляем счетчик cnt.
- В шагах 2...19 проверяем сигнал на GPIO пине. Если там высокий уровень (т.е. "единица"), то инкрементируем счетчик cnt.
- После 19-го шага (это 10 мс с начала цикла) проверяем состояние счетчика cnt:
- если там число менее 9 - то обе кнопки нажаты (С1 разряжен через параллельно соединенные R1 и R2)
- если там число от 9 до 13 - нажата кнопка SW1 (С1 разряжен через R1)
- если там число от 14 до 18 - нажата кнопка SW2 (С1 разряжен через R2)
- если там число более 18 - то обе кнопки отжаты (С1 вообще не успел разрядиться)
- Повторяем цикл (п. 3)
Окончательное принятие решения о том, какие кнопки нажаты, производится, скажем, по результатам последних 10 циклов. Если все результаты одинаковые, они принимаются достоверными.
Оптимальное отношение сопротивлений R2 к R1 равно 1.618, что есть "золотое сечение". Что означает, что вместо 47к лучше использовать 51к, но это менее популярный номинал из ряда Е24, тогда как 33к и 47к - из ряда Е12.