Задумал я как-то в одной из конструкций применить вот такую кнопку с индикацией состояния:
Внутри — пара замыкающих или переключающих контактов и светодиод (опционально — уже с гасящим резистором на выбор для питания от 5, 12, или 24 В). Все бы с ней хорошо, но разместить кнопку планировал на приборной панели автомобиля, а управляющий блок — в моторном отсеке. А тянуть отдельные провода для контакта и для индикации уж очень не хотелось.
Как это решить, и что для этого нужно — под катом
В итоге в голову пришло вот такое решение:
Работать будет с портами ВВ микроконтроллера, для которых есть:
a) двунаправленный режим
б) безопасное ограничение по выходному току (в STM32 ЕМНИП регулируется программно)
в) виртуальный порт, позволяющий считывать сигнал прямо с выводов (в AVR PINx)
Алгоритм такой:
1. периодически проверяем бит порта PIN, к которому подключена кнопка (например, раз в 20 мс)
1а. на время проверки, если выходной PORT был равен 0, ставим его в 1 (сама проверка — несколько микросекунд — глазом не заметно)
2. если на PIN обнаружили 0, значит кнопка нажата — запоминаем факт первичного обнаружения (для алгоритма антидребезга)
2a. если при этом на PORT был высокий уровень и мы обнаружили нажатие, снимаем его до тех пор, пока периодическая проверка п.1 не покажет устойчивое отжатие кнопки (3-5 проверок подряд) — так как светодиод и так не будет светиться из-за шунтирования контактами кнопки, а уменьшить выходной ток через порт, ограниченный при нажатии кнопки лишь выходным каскадом, очень полезно во всех смыслах
3. если подтвердили нажатие или отпускание в течение нескольких циклов проверки — обрабатываем его в программе, и зажигаем соответственно светодиод через PORT
Недостаток такого включения в том, что индикатор будет погашен в течение всего времени удержания кнопки человеком — то есть если пргораммно реализовывать toggle switch, то переход из вкл в выкл визуально произойдет в момент нажатия, а из выкл во вкл — в момент отпускания — это может быть не совсем удобно
Теперь для МК, которые не умеют отслеживать состояние непосредственно выводов порта, либо не имеют средств ограничения выходного тока (например, старые семейства 8051 и их клоны):
Здесь придется пожертвовать еще одной линией ВВ, настроенной на вход, и разделить гасящий резистор на две части. Алгоритм при этом остается прежним, разве что переводить выходной порт в 0 на все время, пока обнаружено нажатие кнопки, не обязательно (но по-прежнему желательно для автономных систем с точки зрения уменьшения потребляемого тока). Пропорцию значений резисторов можно выбрать и не такую экстремальную (сажать выход на землю через 39 Ом, даже на миллисекунды для некоторых МК может оказаться жестковато) — важно только, чтобы падение напряжения на светодиоде + его нижней половине ограничительного резистора при высоком уровне выходного порта было с запасом больше, чем Vcc/2
И наконец, вариант схемы для нескольких кнопок с индикацией — здесь можно использовать одну входную линию на всех, развязав диодами:
Pull-up входного порта (нарисован пунктиром справа) для исключения слабой засветки кнопок через развязывающие диоды можно включать только в момент сканирования состояния. Сканировать множественные кнопки, естественно, по очереди.
Вот такая идея — на практике правда пока проверить не успел, даже нарисовал только на бумажке
Внутри — пара замыкающих или переключающих контактов и светодиод (опционально — уже с гасящим резистором на выбор для питания от 5, 12, или 24 В). Все бы с ней хорошо, но разместить кнопку планировал на приборной панели автомобиля, а управляющий блок — в моторном отсеке. А тянуть отдельные провода для контакта и для индикации уж очень не хотелось.
Как это решить, и что для этого нужно — под катом
В итоге в голову пришло вот такое решение:
Работать будет с портами ВВ микроконтроллера, для которых есть:
a) двунаправленный режим
б) безопасное ограничение по выходному току (в STM32 ЕМНИП регулируется программно)
в) виртуальный порт, позволяющий считывать сигнал прямо с выводов (в AVR PINx)
Алгоритм такой:
1. периодически проверяем бит порта PIN, к которому подключена кнопка (например, раз в 20 мс)
1а. на время проверки, если выходной PORT был равен 0, ставим его в 1 (сама проверка — несколько микросекунд — глазом не заметно)
2. если на PIN обнаружили 0, значит кнопка нажата — запоминаем факт первичного обнаружения (для алгоритма антидребезга)
2a. если при этом на PORT был высокий уровень и мы обнаружили нажатие, снимаем его до тех пор, пока периодическая проверка п.1 не покажет устойчивое отжатие кнопки (3-5 проверок подряд) — так как светодиод и так не будет светиться из-за шунтирования контактами кнопки, а уменьшить выходной ток через порт, ограниченный при нажатии кнопки лишь выходным каскадом, очень полезно во всех смыслах
3. если подтвердили нажатие или отпускание в течение нескольких циклов проверки — обрабатываем его в программе, и зажигаем соответственно светодиод через PORT
Недостаток такого включения в том, что индикатор будет погашен в течение всего времени удержания кнопки человеком — то есть если пргораммно реализовывать toggle switch, то переход из вкл в выкл визуально произойдет в момент нажатия, а из выкл во вкл — в момент отпускания — это может быть не совсем удобно
Теперь для МК, которые не умеют отслеживать состояние непосредственно выводов порта, либо не имеют средств ограничения выходного тока (например, старые семейства 8051 и их клоны):
Здесь придется пожертвовать еще одной линией ВВ, настроенной на вход, и разделить гасящий резистор на две части. Алгоритм при этом остается прежним, разве что переводить выходной порт в 0 на все время, пока обнаружено нажатие кнопки, не обязательно (но по-прежнему желательно для автономных систем с точки зрения уменьшения потребляемого тока). Пропорцию значений резисторов можно выбрать и не такую экстремальную (сажать выход на землю через 39 Ом, даже на миллисекунды для некоторых МК может оказаться жестковато) — важно только, чтобы падение напряжения на светодиоде + его нижней половине ограничительного резистора при высоком уровне выходного порта было с запасом больше, чем Vcc/2
И наконец, вариант схемы для нескольких кнопок с индикацией — здесь можно использовать одну входную линию на всех, развязав диодами:
Pull-up входного порта (нарисован пунктиром справа) для исключения слабой засветки кнопок через развязывающие диоды можно включать только в момент сканирования состояния. Сканировать множественные кнопки, естественно, по очереди.
Вот такая идея — на практике правда пока проверить не успел, даже нарисовал только на бумажке
eta4ever
А я поначалу подумал, что действительно 1-Wire, что в кнопку был имплантирован контроллер…
gleb_l Автор
маркетинговая ловушка. Надо было 1-wire еще и в тэги добавить, но пока держусь :)
вообще, при нынешних ценах на чипы, можно запросто рядом с каждой кнопкой расположить какую-нибудь тиньку, которая принимала-отправляла бы команды модуляцией по питающему проводу
eta4ever
Я так поглядел, 1-Wire Slave довольно костыльно реализуется, а жаль.
gleb_l Автор
что-то шутки даже со смайлом в конце предложения идут не очень — добавил определенности, закавычив широкоизвестное название протокола во избежание нежелательных ассоциаций.
А вообще, в данном случае достаточно именно «проволочного» решения на «клиентской стороне» — без всяких контроллеров в кнопках as long as все можно сделать аппаратно-программно на «сервере»
propell-ant
так, на всякий случай, если кому-то интересно
человечек сделал клиента 1w на avr
avr.ru/ready/measure/mass/debet/part3
ploop
Да их кто только не делал, и я в том числе (это следующий уровень после миганий светодиодами). Дать код на ассемблере? :)
propell-ant
дать!
хабр индексируется лучше очень многих ресурсов — легче найти новичкам
ploop
Только вряд ли кому поможет кусок, вырванный из контекста, но ладно:
eta4ever
Ага, а теперь то же самое с паразитным питанием, чтобы реально двумя проводами обойтись.
Где три провода, там и четыре, а где четыре — там и i2c или rs-485, без велосипедов.
shushu
Я по подобному принципу лет 15 назад светодиод на выключатель освещения в квартире цеплял :)
KonstantinSoloviov
А зачем вы шунтируете кнопкой и диод и резистор? Может только диод?
gleb_l Автор
смысл в том, чтобы пересилить выход порта и притянуть его к нулю, и это притягивание заметил МК. Если просто закоротить диод, то резистор не позволит этого сделать — просто чуть увеличится выходной ток.
KonstantinSoloviov
а почему бы не инвертировать режим работы вывода (т.е. переключить выход на вход) на те самые тестовые 20мс? и «перетягивать» ничего не придется
gleb_l Автор
не получится — так как светодиод с резистором и так притянут вход к нулю, даже если включить внутренний pull-up — так как сопротивление pull-up'а на два-три порядка больше, чем гасящего резистора — в итоге, на нем почти ничего не упадет, плюс светодиод под микротоком (ну допустим, 1 вольт) — и МК не почувствует разницы между закороченным и свободным светодиодом — оба уровня будут ниже входного порога
KonstantinSoloviov
пожалуй, а как на счет АЦП? должна же быть заметна разница!
gleb_l Автор
на АЦП конечно да, только использовать каналы АЦП — роскошь для такого простого применения, мне кажется. Я тоже сначала думал сделать на АЦП или на каналах-компараторах — но решение на обычных портах ВВ имхо гораздо более универсальное.
gleb_l Автор
можно, конечно, сместить диапазон delta-U при замкнутом и разомкнутом светодиоде так, чтобы он находился посередине порога переключения, например, включив в земляной провод 2-3 диода в прямом направлении.
Но, во-первых, это лишние элементы, во-вторых из монтажных соображений удобно, когда один из концов кнопки сидит на земле (корпусе), в третьих — помехозащищенность метода будет существенно хуже — смещение цифровой земли всего на 0.5 вольта (в начале статьи я упомянул про применение в автомобиле) сделает схему неработоспособной
eps
У Maxim есть DS2413, микросхема с 2 вводами-выводами, работающая по тому самому 1-Wire.
Используется, например, в Эппловском разъёме MagSafe, где управляет 2 светодиодами. Стоит чуть больше доллара оптом.
ploop
У автора не 1-Wire, а «1-Wire», т.е. один провод. Всем известный протокол тут не при чём.
eps
Именно. И у Maxim, создателя настоящего 1-Wire, есть микросхема, выполняющая функции, которые нужны автору.
При этом — все преимущества 1-Wire — готовые библиотеки, шина для нескольких устройств с авто-адресацией и, конечно, надёжность. Это всё оттестировано до нас и работает.
gleb_l Автор
А еще одного провода для собственного питания DS2413 часом не требует? ;)
eps
Нет, там паразитное питание через шину данных. В datasheet пишут, что может давать на нагрузку ток в 20 мА
gleb_l Автор
Это прекрасно, а сам светодиод питать тоже паразиткой с шины? Чип-то получит команду на его включение, а кто даст энергию ему гореть? Или 1-wire переживет шунтирование светодиодом с резистором? ;)
eps
Немного тока с неё взять получится, но, говорят, мало. Единицы милиампер и 5 вольт. На самом деле, вообще никакой конкретной информации нет.
Можно взять напряжение для нагрузки на месте (всё-таки это автомобиль) — но это не так интересно.
(не заметил, что там всего лишь открытый сток)
Big-Boss
Просто вставлю…
www.youtube.com/watch?v=z3XZDRLULs4
gleb_l Автор
Ага, примерно так :)
imwode
Проблема высосана из пальца, извините
imwode
Вот код для дуни:
Симулятор: 123d.circuits.io/circuits/851507-pb-led
gleb_l Автор
Не извиняю — посчитайте количество проводов, связывающих кнопку-индикатор с МК системой в вашем случае
imwode
ээээ, 1?
Хочешь сказать, три? В твоем тогда два. В чем проблема цапануть +12В под приборкой для постоянной индикации без всяких выкрутасов?
ploop
Только вот надо +5, а не +12.
imwode
Так надо, чтобы подсветка всегда работала или время от времени? Если всегда, то хоть 220. А если время от времени, то моя схема не пойдет — подсветка будет гореть всегда, когда кнопка нажата.
ploop
Так в том и смысл — подсветка должна от МК управляться. В частности, кнопка нормально разомкнута (без фиксации), а подсветка зажигается электроникой. Такое решение позволит, например, помигать ей в некоторых ситуациях, или погасить автоматически при каком-то событии.
k0der1
Можно узнать модель кнопки. Спасибо.
Muzzy0
Последнюю схему не понял. Как при одном входе понять, какая кнопка нажата?
ploop
Сканировать по очереди, например.
Но если кнопок много, то и линий много, проще коммутатор сделать и передавать уже настоящей 1-wire
Muzzy0
Так а что сканировать по очереди, если физический вход один? Например, что мы получим в случае, если нажато несколько кнопок одновеременно?
ploop
Вход один, выходы разные. В каждый конкретный момент времени работает только один выход, и вход знает, с каким выходом сейчас работает. И так по кругу с высокой частотой.
Muzzy0
так кнопка, судя по рисунку, вход прямо на землю роняет. При нажатии любой из кнопок у нас на входе земля независимо от состояния выходов. Верно?
ploop
А, ну да.
Вообще, в этом случае непонятно, зачем там вход. Можно же с каждой кнопкой работать по отдельности как в первой схеме.
KurilkaRymin
Muzzy0
Это больше похоже на правду :) в исходном посте про АЦП ни слова.
Alexeyslav
Ха… все выходные не мог дочитать статью до конца, а особенно комментарии…
Товарищи! Вы где усыпили своего инженера?
Не надо ничего замыкать! Подключите кнопкой параллельно светодиоду и резистору… конденсатор! Он не шунтирует цепь, по крайней мере надолго, и если ограничить ток его заряда резистором в 100 Ом он вообще не будет создавать нагрузку порту и мешать светодиоду. Зато его наличие легко определяется по инерционности — когда светодиод включен, короткое отключение порта в режим входа и через определенное время смотрим — есть напряжение, значит кнопка замкнута нет напряжения — кнопка разомкнута.
Если светодиод погашен — выдаем короткий импульс «1» по окончанию импульса через несколько микросекунд смотрим — есть напряжение(паразитная емкость быстро зарядится, но будет держать заряд еще считанные микросекунды) значит кнопка разомкнута, если зарядится не успеет — копка замкнута и подключен значительно больший конденсатор, которому не хватило времени чтобы зарядится.
Немного усложнит опрос кнопки но… преимущества на лицо.
gleb_l Автор
Да, динамикой можно красиво решить задачу — однако суть моей идеи в том, что в месте установки кнопки не нужно никаких дополнительных элементов вообще — так как гасящий резистор уже есть внутри кнопки. Массовый провод подкладывается под гайку крепления, и в МК систему идет всего один провод, а все остальное делается чисто программно. Долгого шунтирования же цепи не будет, т.к. алгоритм обработки нажатия, увидев первое, переведет выходной порт в 0, с короткими 1 только на время очередного опроса. Я вижу существенное преимущество вашего решения только в следующем (помимо того, что оно, конечно, красивое) — в возможности выполнять индикацию от МК системы в то время, пока кнопка нажата — если это в силу каких-то причин необходимо, то стоит выбрать его
И чтобы не писать несколько ответов — кнопки такие продаются на aliexpress.com, а вариант схемы с одним входом, развязанном диодами, конечно, работать не будет — это я загнул. Нужно будет использовать первый или второй вариант
BTW, некоторые кнопки имеют НЗ контакты (но они вроде как дороже, чем НР) — их можно включить последовательно со светодиодом/резистором, и проверять порт в режиме чтения на 1