Светодиод и кнопка на одном выводе

Dinosaur
Dinosaur аватар
Offline
Зарегистрирован: 01.01.2018

Добрый день, камрады

В процессе ковыряния кухонной вытяжки, попала в руки плата управления и индикации: кнопки и светиодиоды, казалось бы ничего примечательного, но посмотрите на схему - микроконтроллер на одном выводе и читает состояние кнопки, и управляет светодиодом. Вопрос - как это организовано (общая концепция)? К сожалению основная плата дохлая и проследить логику работы тестером не представляется возможным.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так тут можно миллион способов придумать.

Например, если выводы обозвать (слева направо) ALL_BUTTONS, BTN1, BTN2, BTN3, BTN4 и ALL_LEDS и подключить к соответствующим пинам. При этом ALL_LEDS – через транзистор по неинвертирующей схеме. Тогда вот такой скетч будет спокойно опрашивать все кнопки и управлять всеми светодиодами.

#define	ALL_BUTTONS	2 // PD2
#define	ALL_LEDS	3 // PD3
#define	BTN1	4 // PD4
#define	BTN2	5 // PD5
#define	BTN3	6 // PD6
#define	BTN4	7 // PD7
#define	LED1	BTN1
#define	LED2	BTN2
#define	LED3	BTN3
#define	LED4	BTN4

void setup() { 
   pinMode(BTN1,OUTPUT);
   pinMode(BTN2,OUTPUT);
   pinMode(BTN3,OUTPUT);
   pinMode(BTN4,OUTPUT);
   pinMode(ALL_LEDS, OUTPUT);
   pinMode(ALL_BUTTONS, OUTPUT);
}

//	Текущее состояние кнопок (true - если нажата)
static bool btn1 = false, btn2 = false, btn3 = false, btn4 =false;

//
//	Опрос кнопок
//
void checkButtons(void) {
   // пины кнопок на ввод
   pinMode(BTN1,INPUT);
   pinMode(BTN2,INPUT);
   pinMode(BTN3,INPUT);
   pinMode(BTN4,INPUT);
   // общий пин в HIGH
   digitalWrite(ALL_BUTTONS, HIGH);
   // Читаем все кнопки
   btn1 = digitalRead(BTN1);
   btn2 = digitalRead(BTN2);
   btn3 = digitalRead(BTN3);
   btn4 = digitalRead(BTN4);
   // возвращаем всё обратно
   digitalWrite(ALL_BUTTONS, LOW);
   pinMode(BTN1,OUTPUT);
   pinMode(BTN2,OUTPUT);
   pinMode(BTN3,OUTPUT);
   pinMode(BTN4,OUTPUT);
}

//
// Зажигаем/гасим светодиоды в соответсвие с кнопками	
//
void ledsShow(void) {
   digitalWrite(LED1, !btn1);
   digitalWrite(LED2, !btn2);
   digitalWrite(LED3, !btn3);
   digitalWrite(LED4, !btn4);
   digitalWrite(ALL_LEDS,HIGH);
   delay(20); // Пусть погорят маленько
   digitalWrite(ALL_LEDS,LOW);
}

void loop() {
   checkButtons();
   ledsShow();
}

Скетч зажигает светодиоды соответствующие кнопкам, но это необязательно, можно писать как угодно – кнопки и светодиоды независимы друг отдруга.

Проверяйте - всё работает.

Если нужна борьба с дребезгом, то задержку в строке 57 уменьшить до 10 и принимать изменение состояние кнопки только если она два опроса подряд держится в новом состоянии.

Dinosaur
Dinosaur аватар
Offline
Зарегистрирован: 01.01.2018

Евгений, спасибо за ответ. Если я правильно понимаю логику работы скетча, светодиоды будут "часто-часто мигать" (выключаться на время чтения состояния пинов, и включаться после завершения чтения состояния пинов)?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Таки да. Это нормально. Светодиоды в 99% схем не горят постоянно, а "часто-часто мигают". Просто достаточно часто, чтобы глаз этого не замечал. Погуглите "динамическая индикация" узнаете как обычно семисегментные индикаторы пожключают.

Dinosaur
Dinosaur аватар
Offline
Зарегистрирован: 01.01.2018

Правильно ли я понимаю, что единственный профит такого решения - экономия выводов микроконтроллера (за счёт снижения производительности работы) или есть другие плюшки?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, там много всего. При таком скетче, как у меня - да. А если написать по-другому (к той же схеме), то можно получить систему в которой в каждый отдельный момент времени светится только один светодиод (и на глаз это совершенно незаметно, кажется, что светятся все). Тогда получаем ещё и экомонию по току. Всё-таки каждый светодиод - это 5-20 миллиампер. Можно также написать, чтобы в каждый момент времени реально замкнутой была только одна кнопка, тоже некоторый ток экономится. Можно и ещё подумать.

Dinosaur
Dinosaur аватар
Offline
Зарегистрирован: 01.01.2018

Понял, учитывая что вытяжка работает от сети переменного тока, вряд ли эти ухищрения имеют смысл. Спасибо за ликбез. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Dinosaur пишет:

Понял, учитывая что вытяжка работает от сети переменного тока, вряд ли эти ухищрения имеют смысл. Спасибо за ликбез. 

Нет! Вы не поняли смысла ухищрений.

Дело тут не том, чтобы сэкономить на оплате энергии, а в том, что у контроллеров есть ограничения на проходящий через них ток. Например, у ATMega328P это 200мА - абсолютный максимум.

Теперь, допустим Вы хотите включить 16 светодиодов, по 20 мА. Пинов-то хватит, а вот ток будет уже 320мА! Т.е. Ваш контроллер элементарно сгорит. Можно, конечно включить по 10мА - они достаточно яркие, но 160мА при абсолютном максимуме в 200 - это тоже многовато.

Т.е. экономия тут в основном такая, а не "счётчиковая".

Dinosaur
Dinosaur аватар
Offline
Зарегистрирован: 01.01.2018

А, вот теперь фишку понял, в подобном ключе проблему не рассматривал, видимо потому что ещё не сжигал подобным образом мк :)

bwn
Offline
Зарегистрирован: 25.08.2014

Dinosaur пишет:

видимо потому что ещё не сжигал подобным образом мк :)

Ви таки еще такой молодой, все у Вас впереди, и радикулит, и маразм, и простатит.))))))