Для блока питания необходимо будет сделать панель управления состоящую из блока кнопок. Если просто подвести через кнопку питание через сопротивление, то получим:
- дребезг при нажатии - когда нпаряжение на ножке контроллера меняется не один раз а много раз 0-5В-0-5В-0-5В... обусловлен дребез несовершенством механизма самой кнопки
- отсуствие инерционности, случайные нажатия и отпускания заставят контроллер выполнять какие-то действия, а хотелось бы инерционности. например дать возможность нажимать кнопку не более раз в 0.1 секунды. Подобные проблемы хорошо описаны в видеоуроке на сайте Амперки Только в видеоуроке упрощенный рассчет и разрядка не верная, т.к конденсатор при замыкании кнопки буде чень быстро разряжаться через сопротивление кнопки.
Можно на програмном уровне сделать искуственную задержку на 0.1 секнду, как описанно здесь
#define BUTTON_PIN 3
#define LED_PIN 13
boolean buttonWasUp = true; // была ли кнопка отпущена?
boolean ledEnabled = false; // включен ли свет?
void setup()
{
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop()
{
// определить момент «клика» несколько сложнее, чем факт того,
// что кнопка сейчас просто нажата. Для определения клика мы
// сначала понимаем, отпущена ли кнопка прямо сейчас...
boolean buttonIsUp = digitalRead(BUTTON_PIN);
// ...если «кнопка была отпущена и (&&) не отпущена сейчас»...
if (buttonWasUp && !buttonIsUp) {
// ...может это «клик», а может и ложный сигнал (дребезг),
// возникающий в момент замыкания/размыкания пластин кнопки,
// поэтому даём кнопке полностью «успокоиться»...
delay(10);
// ...и считываем сигнал снова
buttonIsUp = digitalRead(BUTTON_PIN);
if (!buttonIsUp) { // если она всё ещё нажата...
// ...это клик! Переворачиваем сигнал светодиода
ledEnabled = !ledEnabled;
digitalWrite(LED_PIN, ledEnabled);
}
}
// запоминаем последнее состояние кнопки для новой итерации
buttonWasUp = buttonIsUp;
}
Но желательно не нагружать однозадачный микроконтроллер, который у меня и так предполагается будет заружен постоянным сканированием выходных сигналов и выводом на экран. Поэтому задержку и подавление шума переложу на апаратную часть.
Для этого необходимо:
- кнопка
- 74HC14 или инвертирующий триггер Шмитта (на него можно аж 6 кнопок навесить). Что это такое?
- резисторы 100К и 47К
- емкость 1мкФ
Вот схема:
Так она выглядит на макетной плате:
А теперь немного математики
Зачем все это и почему именно такие номиналы: номиналы определют время зарядки и разрядки емкости. За постоянную я принимаю номинал емкости, дальше веду рассчет сопротивлений под нужный мне временной промежуток.
Экспериментально установил, что гестерезис у триггера шмитта на отметках 2Вольта при ниспадающем фронте и 2.5В при возрастающем. Вот доказательство:
Т.е емкость с резисторами обеспечивает нужный плавный переход от высокого к низкому уровню и наоборот, а инвертирующий триггер делает это переход цифровым, срабатывая по достижению уровня.
Ситуация 1
переход от 5В к 2В, т.е ниспадающий фронт и время разрядки емкости до 2В от 5В должно быть 0.1 секунды.
Vпит=5В
верхний уровень, Vтриггера_нисп=2В
напряжение срабатывания триггера при ниспадающем фронте, требуемре время t=0.1 секунды
.
Когда происходит разрядка - когда кнопка нажата, тогда через цепочку C1-R2-кнопка-земля
утекает накопленный емкостью заряд. И разряжается он по формуле:
Vискомое=Vначальное*exp(-t/(R2*C1))
где Vискомое это напряжение при котором срабатывает триггер, а Vначальное - это напряжение питания
Vтриггера_нисп/Vпит=exp(-t/(R2*C1))
ln(Vтриггера_нисп/Vпит)=-t/(R2*C2)
откуда получаем:
R2=-(t/(ln(Vтриггера_нисп/Vпит)*C1))=-(0.1c/(ln(2В/5В)*0.000001Ф))=109135 примерно 100К
Ситуация 2
переход от 0В к 2.5В, когда триггер срабатывает уже по восходящему фронту. Емкость в этот момент заряжается через источник питания-R1-R2-C1-земля
. И за 0.1 секнуды должна набрать заряд 2.5 вольта от 0В.
Формула зарядки:
Vискомое=Vпит*(1-exp(-t/(R*C1)))
, где R=R1+R2
Vискомое=2.5В, Vпит как и ранее 5В, t=0.1 секунды емкость C1 неизменна.
преобразуем формулу:
Vискомое/Vпит=1-exp(-t/(R*C1))
1-Vискомое/Vпит=exp(-t/(R*C1))
ln(1-Vискомое/Vпит)=-t/(R*C1)
R=-t/(C1*ln(1-Vискомое/Vпит))=-0.1/(0.000001*ln(1-2.5/5))=144269
примерно 147К.
Т.к R2 мы уже знаем, высчитаем R1=R-R2=147К-100К=47К
.
А теперь практический пример:
это время разрядки, видно что длилось оно до срабатывания 66милли секунд. Из-за погрешностей при выборе сопротивления, но меня такой интервал устраивает.
а вот зарядка ровно легла на рассчетный период = 100милли секунд.
И вот пример частого нажатия кнопки:
Как видно - триггер сработал один раз, шумов не видно.
Красный график осциллографа показывает, какой сигнал будет на контроллере при нажатии и отпускании кнопки.