Мультиплексирование

Думаю, каждый сталкивался с нехваткой выводов у выбранного контроллера. Принципиальных путей решения данной проблемы ровно два: менять контроллер на более многоногий или менять схему, чтобы упихнуться в существующие ноги.
Например, классика жанра — кнопки. Когда их две-три, то проще всего повесить каждую на свою ногу, особенно если на этих ногах есть внешнее прерывание. Тогда и работать с ними одно удовольствие. А если кнопок больше десятка? Если идти по первому пути, то с кличем «больше ножек!» выбираем какой-нить TQFP64 и оккупирем два порта. У такого решения есть очевидный плюс — каждая кнопка анализируется независимо от других, поэтому возможны любые аккорды. Минусы тоже очевидны: много ног ушло почти в никуда.

Второй путь — преобразовать схему так, чтобы подсократить количество занимаемых ног. Тут простора для творчества побольше. Начиная от PC-style (отдельный контроллер, который занимается опросом клавиатуры и преобразует нажатие клавиш в удобоваримый последовательный код, хоть в 1-wire) и сдвиговых регистров (как на джойстиках Dendy) заканчивая клавиатурами на резистивных делителях, подключаемых к АЦП. Весь вопрос — в стоимости.

Варианты с матрицей клавиш уже рассматривались, сдвиговый регистр подключали, а вот клавиатура на делителях осталась как-то незаслуженно забыта. Восполним пробел.

Первое, что сразу приходит в голову — поставить цепочку резисторов и кнопками коротить их на землю. Примерно так:

Посмотрим, как оно работает.

  • Если не нажата ни одна кнопка, то выход Vout подтянут к Vref через резистор R1, соответственно Vout = Vref.
  • Если нажата кнопка S1, то она тянет Vout к земле, и на выходе Vout = 0.
  • Если нажата кнопка S2, то схема преобразуется в резистивный делитель: верхнее плечо образует резистор R1, нижнее плечо — R2. Поскольку номиналы этих резисторов равны, то на выходе Vout = Vref / 2.
  • Если нажата кнопка S3, то в нижнее плечо включается резисторы R2 и R3, и коэффициент деления стал 2/3.

Сведем данные в таблицу (исходим из 8-битного АЦП, т.е. при Vout = Vref его значение 255):

Понятное дело, что если взять не одинаковые резисторы, то можно добиться более равномерного распределения. Но, используя принцип Оккама (Не следует множить сущее без необходимости), мы ставим то, что уже закуплено в невообразимых количествах, не расширяя номенклатуру. По динамике значений видно, что уже к 10 кнопке мы не сможем четко распознавать кнопки, а учитывая, что резисторы у нас не идеальные (есть расброс значений), то и калибровать придется каждый экземпляр клавиатуры. Да, можно задействовать несколько входов АЦП, повесив на каждый по своей клавиатурке (благо на той же меге из 8 штук), но мы же не ищем легких путей.

На просторах интернета нашел улучшенную схему построения клавиатуры на резисторных делителях. Все следы ведут на сайт www.edn.com, но там я не нашел оригинала статьи.

Если посмотреть глобально, то принцип остался такой же — одно плечо делителя неизменно, другое формируется из комбинации резисторов в зависимости от нажатых кнопок. Весь пафос в том, что подобрав значения резисторов, можно расширить диапазон изменения напряжения Vout (например, в прошлой схеме напряжения меньше чем Vref/2 получить не удавалось).

Посмотрим подробнее на комбинации резисторов. При нажатии кнопки в верхнее плечо делителя подключается от 0 до 3 резисторов Ra, Rb, Rc и от 0 до 3 резисторов Rd, Re, Rf. Например, при нажатии кнопки S(1,2) соберется такая цепочка: Ra-S(1,2)-Re-Rf

Для упрощения расчетов примем:
Ra = Rb = Rc = R1, Rd= Re = Rf = R2

Формула для расчета выходного напряжения примет вид:

, где x,y – обозначения в скобках соответствующей кнопки (S(x,y)).

Для того, чтобы не перепутать кнопки, соотношение резисторов R1/R2 должно быть не менее 4.

Составим табличку значений АЦП для нажатий кнопки S(x,y):

Из таблички видно, что кнопки различимы, даже с учетом 1% погрешности резисторов.

Мультиплексирование вывода

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

Способ первый, он же простейший — один светодиод — один вывод. Все просто, понятно и мило. Ну и токоограничительный резистор не забыть. По одному на светодиод. Плюсы такого решения — чистейшей воды статика. Ничего не мерцает, можно зажигать в любой комбинации.

Начинаем мультиплицировать.
К одной ножке можно подключить сразу два светодиода, один катодом на землю, другой — анодом на питание. Естественно, каждый через свой токоограничительный резистор. Подобная схема разбиралась DiHalt’ом в разделе «отладка». В чем пафос — когда ножка процессора находится в состоянии «1», то горит нижний светодиод. Когда «0» — верхний. Когда ножка находится в состоянии «input» (High-Z), то не горит ни один светодиод. На самом деле могут тускло светиться оба, но ведь всегда можно подобрать сопротивление резисторов так, чтобы напряжения на оба светодиода не хватало.
Итак, коэффициент мультипликации 2 (на один вывод можно посадить два светодиода).

Уже лучше. Но обратим внимание, что оба светодиода гореть одновременно уже не смогут. Поэтому, чтобы у пользователя создалось впечатление, что горят оба светодиода, надо их переключать с частотой не менее 50Гц. При этом получается, что половину времени горит один светодиод, половину — другой. Из-за того, что у светодиодов практически нет инертности, то и яркость свечения светодиода визуально упадет в два раза.

Едем дальше. А давайте-ка организуем матрицу светодиодов. Посмотрим на схему включения стандартной светодиодной матрицы 8х8:

Что у нас тут? Светодиоды собраны в строки и столбцы. Если подать «1» в столбец, а одну (или несколько) строк соединить с землей, то загорятся светодиоды на пересечении этихстрок и столбца. Естественно, если допустимый ток через ножку процессора не позволяет кормить сразу несколько светодиодов, то его всегда можно умощнить транзистором. Ну или зажигать по одному светодиоду за раз. Только это совсем грустно будет.

Итак, подобьем итоги — на 16 ножек получается 64 светодиода. Коэффициент мультипликации 4. И с увеличением матрицы он будет расти, ведь с применением 2N ножек мы сможем подключить N*N светодиодов.

Обратим внимание, в каком режиме работают задействованные выводы: столбцы — либо «1» либо отключены, строки — либо «0», либо отключены. Как-то недогружены. Наверно этой мыслью задался дядька Чарли Аллен (или Эллен, если правильно произносить). И предложил схему, которая с его легкой руки стала называться «Чарлиплексинг». В чем суть? Предложение такое — между каждой парой ножек контроллера подключить по паре встречно-параллельных светодиодов. Опять же, подобная схема рассматривалась DiHalt’ом в курсе обучения, но тогда она так гордо не называлась.

Как оно работает? Если на ногу 1 подать единичку, а на ногу 2 — нолик, то загорится светодиод Led1, если подать уровни наоборот, то загорится Led2. Все вроде просто. Посчитаем — с помощью N ножек мы можем управлять N*(N-1) светодиодами. Это почти в два раза лучше, чем в случае с полной матрицей. Но если в матрице мы могли зажечь целиком колонку, то тут такой фокус пройдет с трудом — выход контроллера не потянет. Например, мы ногу 2 опустили в ноль, а 1 и 3 — в единицу. При этом загорятся светодиоды Led1 и Led4 (одновременно, без всякого мухлежа), но через ногу 2 пойдет двойной ток. А если ножек будет 8, то и восьмикратный. Что делать? Конечно же подпирать транзистором.

Что тут? Практически схема матричного мультиплицирования, но с одним но — колонки подключены через транзисторы к тем же выводам строк. Соответственно, подав «1» на строку, мы тем самым подаем и «1» на соответствующую колонку (открыв транзистор). При этом мы можем зажечь всю колонку, мощи транзистора хватит.

Коэффициент мультипликации здесь — как и при применении чарлиплексинга, а частота обновления (а значит и яркость) может быть на порядок лучше.

Ну и завершающий шажок, чтобы совсем порвать мозг — жлобоплексинг. Попробуем подключить к трем выводам процессора 12 светодиодов (!).

Разберемся. Как подключены светодиоды D2-D7 должно быть понятно. Классический чарлиплексинг. А вот остальные — это уже интересней.
Резисторы R1, R2, R4 образуют делитель напряжения. При этих номиналах разница потенциалов на резисторе R2 (а соответстенно и между базами транзисторов) будет чуть больше чем 1.6 вольта. Учитывая, что между эммитерами транзисторов подключена минимум цепочка из двух светодиодов, то этого напряжения недостаточно, чтобы открыть транзистор. А теперь представим, что на один из выводов процессора подали логическую «1». При этом напряжения достаточно, чтобы скомпенсировать падение напряжения на нижнем желтом диоде, нижний транзистор открывается и через светодиод течет ток, зажигая его. Аналогично зажигаются и верхние, красные светодиоды (D8-D10), только в этот раз на нужные выходы подается логический «0».
Когда мы управляем внутренними шестью светодиодами (D2-D7) то на одной из ног у нас обязательно будет «1», а на какой-то другой — «0». При этом оба транзистора закрыты, соответственно ни верхние, ни нижние светодиоды не горят.

Итого — N*(N-1) + 2N = N*(N+1)

По-моему, чемпион по жлобоплексингу определен :)

64 thoughts on “Мультиплексирование”

  1. круто
    и интересно
    хм дома лежит клава с резисторным делителем
    все думал как она работает
    теперь понял
    спасибо за статью

  2. «Из-за того, что у светодиодов практически нет инертности, то и яркость свечения светодиода визуально упадет в два раза.»

    Нека, не в два :)
    Почти не упадет. Из-за того что зрение человека работает нелинейно, к счастью, иначе все матричные панели были бы очень тусклыми.

    1. Ну может и не в два — не замерял.
      Но то, что таким образом можно реализовать в светодиодных часах «ночной режим» — факт.

    2. При импульсноп питании матриц и сегментов увеличивают ток питания онных.
      20мА диодик в при 10%ШИМе хавает 100мА и не потеет. и яркость как у статично запитаного.
      Правдо деградация приюлижается наверно быстрее, но оно того стоит.

      ЛЕДы + Мультиплексирование >>> увеличивай ток.

  3. а как быть если резисторы имеют разброс в 5-10% ? то есть придётся калибровать(запоминать U на входе АЦП) каждую кнопку? или как?

    1. Просто задается диапазон. Если значение попадает в этот диапазон — значит нажата кнопка Х.
      Ну или второй вариант — периодическая перекалибровка.

  4. Последнюю схему вообще не вкурил…
    У нас три ноги. Даже если зажигать диоды по одному — у нас 8 состояний. ВОСЕМЬ!
    Можно увидеть таблицу комбинаций код=светодиод?

    1. что-то тоже по последней схеме… «не допираю» как её на 6 ног разрисовать?
      или на 16 что-бы превзойти 64 led (для матрицы).

      1. А все точно также. «Внутри» — обычный чарлиплексинг, между каждыми парой ног два светодиода встречно-параллельно. Потом от каждой ноги светодиод анодом к эмиттеру верхнего транзистора и катодом эмиттеру нижнего.

  5. я вот думаю и думаю) как получить на матрице такую стрелку. Ведь у тебя на всех столбцах «1» т.к хотя бы один диод в каждой строке горит. и получается что в каждой строке «0» если горит хотя бы один диод в каждой строке. так? нет?

    1. Так, только не одновременно.
      они по очереди загараются. Только быстро.

      Щас удивишся: В телике по кинескопу одна точка бегает.

  6. очепятка
    вот так
    *на всех столбцах “1″ т.к хотя бы один диод в каждом столбце горит. и получается что в каждой строке “0″ если горит хотя бы один диод в каждой строке*

  7. У такой клавиатуры есть большой минус.
    Со временем (или кнопки БУ) на них появляется налет, коррозия и сопротивление кнопки увеличивается. В итоге, при нажатии на 1 кнопку, получаем результат нажатия другой кнопки (часто на телевизорах, нажимаем громкость +, а переключается канал и т.д.)

    1. я для таких случаев пишу программу, с возможностью включения в отличном от основного режиме. например, какая нибудь кнопка должна садить на 0 какой нибудь вход в течении 3 секунд, тогда включается режим записи значений кнопок. нажимаешь их в нужном порядке, а результаты пишешь в еепром, перезапускаешь и всё.
      ну и не надо париться с вычислениями делителей и значений ацп.

      1. Придется таким способом калибровать кнопки каждый раз при их использовании. Т.к. было уже сказано, что сопротивление окисшей кнопки крайне не стабильно.
        Бывали случаи, что у кнопки в не нажатом состоянии был ток утечки! (сопротивление ее составляло от 100К до 1М Ома). Два дня убил на поиск этой неисправности.

        1. но зато это лучше чем зарание выщитывать АЦПшки и писать их конкретные значения. а если окислились то нужно разобрать почистить и заног записать значения. проще чем перепрограммировать полностью
          не подумайте что я хвалю этот способ просто если осталась 1 нога и на неё надо повесить много кнопок, то это, наверное, единственный вариант. можно конечно кодировать, и по 1 проводу пускать код, но это уже требуются дополнительные компоненты.

    2. +100500!!
      В своё время был сильно поражён таким идиотским решением, встречая его в видиках и диджейских 2-х карманных CD-аппаратах.

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

      Не поможет. У окислившейся кнопки сопротивление может меняться на порядки в зависимости от силы и направления нажатия, а так же от фазы луны.

      1. Интересно, а у меня на магнитолле из-за этого тоже кнопки неправильно работают? :) Жму «тише» становится «громче», жму «настройка вверх» — она вообще выключается. Может пора их перепаять? Хотя не знаю — по тому же ли принципу — измерению напряжения — они работают?

        1. Можно попробовать накапать в кнопки жидкость WD-40. Это фигня такая, керосином воняет, у автомобилистов популярна. Поначалу точно помогает, а вот что будет через пол-годика и потом не знаю, нету пока личной статистики, а в сети сведения протеворечивы…

            1. Затечёт-затечёт! Эта фигня шибко текучая..
              А если менять на новые, то не помешает проверить и их, я например пару раз так попадался — только купленые с магазина, а уже с плохим контактом :-( Видать долго валялись где-то на складах в сырости…

  8. Граждане! Вот сижу тут… курю схемки… И возник (возможно идиотский, но всё же) вопрос:
    Нам удалось изначально на одну ногу без выпендрежа посадить 2 светодиода… 3 состояния (0, 1 , Z). То по идее получается, что если на 3 ногах мы имеем 27 состояний, то теоретически, должно быть возможным посадить там 26 светодиодов? Или я неправильно мыслю?

    1. «Теоретически мы миллионеры…» (из анекдота)
      Да, теоретически у нас 27 различимых состояний, но построить простой дешифратор «из говна и палок» уже не выйдет. Поэтому, как только сложность превысит пару транзисторов и горсть резисторов, становится гораздо проще использовать сдвиговый регистр.

      1. Не сосвсем.
        Резистивный тач ближе к переменному резистору, вернее схема его использования.
        т.е. измерительный ток по «кнопке» не протекает, и следовательно если она хоть както контачит( и входное сопротивление контроллера достаточно большое) таких проблем не будет

  9. У предпоследней схемы один косяк может вылезти при определенном сочетании характеристик диодов, транзисторов и номиналов резюков. Вот смотрите хотим мы включить диод D13. Для этого на пину P1 командируется “0”, а пину P3 “1”. При этом естественно включается диод D13, но смотрите катоды диодов D12, D14 и D15 висят на 0 (пин P1), а катоды диодов D23, D43, D53 на уровне +5 вольт (открыт транзистор Q3). В принципе ни что не мешает току через диоды D23, D43, D53 и соответствующие резисторы открыть базы транзисторов Q2, Q4 и Q5, что приведет к включению диодов D12, D14 и D15.

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

    1. Светодиоды «на улице» можно использовать любые, но есть опасность: при попадании на них не просто прямого, но даже и отражённого солнечного света достаточной интенсивности (я живу на юге) в них _может_ вырабатываться фототок (от фотоэффекта), который (ток) _может_ сводить с ума контроллер.
      Так что или обеспечивать им световой «интим», или продумывать схему так, чтобы фототок не мешал.
      Правильней второе.

  11. А тут кроме матрицы 8х8 все схемы позволяют включать по одному диоду?
    (А в матрице по колонкам)

    Ну, в смысле, если я хочу сделать табло 5*4 по, например, предпоследней схеме, используя 5 ног, то, мне надо будет моргать диодами?

    1. Предпоследняя схема позволяет получить табло 5*4 (причём светодиоды можно будет включать независимо друг от друга) только вот паять его придётся вам самому, потому как стандартных чарлиплексинговых светодиодных матриц не существует.

      Я кстати пока сюда не читал — называл эту схему матрицей без главной диагонали…
      Управление этой матрицей аналогично обычной матрице… на нужном выводе выставляете 1, остальными соответственно выбираете колонку, на остальных либо ноль либо Z. Потом другую колонку и т.д.

      1. Но, например, зажечь все диоды сразу у меня не получится ведь? В смысле надо будет моргать каждым по очереди? Это же должно повлиять на яркость сильно

        1. Дык и в обычных многоразрядных семисегментных индикаторах невозможно зажечь сразу все… вернее — возможно, но нельзя этого делать потому как при динамической индикации ток через светодиод поднимают в 4 раза, благодаря чему они светятся с яркостью примерно равной обычному включению. Что будет со светодиодом, если этот ток будет течь через него непрерывно — думаю догадываетесь…

  12. Думаю, в статью стоит добавить, что при использовании в проекте динамической индикации и кнопок, можно выбор колонки или строки совместить с выбором кнопок. Таким образом на восьминогом контроллере можно получить 20 независимых светодиодов и 5 кнопок (проверено на PIC12F628).

    Ещё вопрос (это тоже, думаю, стоит добавить в статью): Как подключить матрицы, которым требуется больше 5 вольт на свечение? Например огромные 12-вольтные индикаторы. А то как ни кручу — приходится 2 транзистора вешать для комутации с +12В. Итого 3+16 транзисторов для трех восьмёрок с общим катодом — многовато будет…

    В предпоследней схеме с Чарлиплексингом — пойдёт ли схема для 10мм светодиодов (по 20-30 мА на душу)? (Вроде как по суммарному втекающему току можно не вписаться… почему кстати в микросхемах ограничивается суммарный ток? Вроде как ключи внутри друг от друга не зависят…)

  13. Ещё вопрос — а можно ли совмещать в обычной матрице индикаторы с общим катодом и анодом?
    Соответственно активация той строки, на которой общий катод подача лог нуля, а строки с общим анодом — логическая единица. Ну и состояния колонок соответственно инвертировать…
    (Теоретически — никаких проблем я на первый взгляд при таком подключении кроме увеличения кода программы я не вижу, но такое на практике ещё не проверено)

  14. Здравствуйте, уважаемые!
    У меня банальный вопрос. Как все-таки бороться с дребезгом. Все говорят нужна
    задержка. Я уже до 2х секунд довел и включение очень нестабильное. Кнопка — 1концом
    на массу, другим на вывод.
    Может подскажете. Заранее спасибо.

    1. Попробуйте следующий алгоритм:
      переменные: keystatus, keytest,keytest1,keypressed,keyunpressed,temp: битовые маски, соответствующие кол-ву кнопок.
      Процедура опроса:
      {
      keytest=состояние пинов всех кнопок; //если в течении динамической индикации переменная keytest не сформировалась…
      temp=keytest&keystatus | keytest1&keystatus | keytest&keytest1; //аля мажоритарный элемент — новое состояние кнопок
      keypressed |= ~keystatus | temp; //какие кнопки были не нажаты, а теперь нажаты
      keyunpressed |= keystatus | ~temp; // какие кнопки были нажаты, а теперь отжаты
      keystatus = temp; //новый статус кнопок
      keytest1=keytest; //сохранение статуса
      keytest=0; // обнуление для удобства заполнения маски… можно «обединичить», если так удобно…
      }

      Проверено на динамической индикации (при матричном соединении кнопок и светодиодов) — дребезга нет!

      1. эквивалент помеси триггера шмитта и фильтра низких частот:
        если кнопка считается нажатой, то чтобы она зарегистрировалась как отжатая — два последовательных опроса должны содержать нулики и наоборот …

  15. Для приведенной схемы с матрицей светодиодов набросал табличку включений:
    https://docs.google.com/spreadsheet/ccc?key=0AgWRQTReJ5iudEwwSHI4V1V3Qy11SU1tRG9nd1NRZXc&hl=ru#gid=0
    не представляю, как можно это использовать в реальном устройстве — на каждую комбинацию постоянно светится или 4 или 6 светодиодов, причем не в самых удобных комбинациях.

    Может быть глубоким перебором перестановок светодиодов и удастся подобрать не совсем уж страшный шрифт под матрицу 5×4 для отображения цифр и алфавита, но я хотел сделать задачу значительно проще — плавную бегущую строку из 20 светодиодов на тиньке в 8 ног, но что-то пока не вижу такой возможности.

    При динамической индикации можно получить объединение любого набора строк, но сами эти строки уж очень неудобные. Имеет ли мультиплексирование светодиодов действительный практический смысл?

        1. весь пафос той схемы в том, что линии МК могут находиться в трех состояниях. Не только 0 и 1, но и еще третье состояние — высокоимпедансное (переключены на вход).

          Вот соответственно и способ управления — подаем 1 на линию, которая отвечает за нужный столбец, на те линии, которые нужно зажечь подаем 0, остальные линии — в Hi-Z

  16. [offtop] Извиняюсь за некропостерство [/offtop]
    Мне, тут, подумалось — если к светодиодной матрице применить демультиплексоры, то можно добиться супержлобоплексирования вида: 2N=2^(2N), где N — количество используемых выводов МК.
    А мультиплексоры можно использовать в клавиатуре, тогда формула будет: 2^(2N)=2N+2.

    1. А если прицепить сдвиговый регистр, то все можно рулить по двум ножкам. Конечно можно, я это и обговорил вначале статьи — здесь рассматриваем решения без мультиплексоров, шифраторов и регистров.

  17. А не проще транзы и их обвязку (3 резистора) заменить двумя двумя стабилитронами с напряжением стабилизации 1,8V, включёнными вместо коллектор-эмитеров. В верней части схемы анод слева катод справа. В нижней части схемы катод слева анод справа.

    1. Это скорее не из разряда, а немного видоизмененная последняя схема, которая здесь приведена. На двух ногах именно 6 светодиодов и получишь, 2*(2+1)=6:)

  18. По поводу клавиатуры на тактовых кнопках.
    Если жать на нее короткими обычными нажатиями то ацп не всегда успевает словить это нажатие. Приходится жать чуть чуть придерживая кнопку на мгновение.
    Ну или делать опрос ацп без предделителя, а значит ацпха будет отвлекать всю остальную работу микроконтроллера своими частыми прерываниями.
    Можно ли как то победить это схемотехнически?

    1. Ну и пусть отвлекает. У Тебя такой дикий затык по времени чтоль? Сделай обработчик предельно коротким и все. Можно в десяток тактов уложиться если захотеть. Там надо то сгрузить из ацпшного регистра в переменную и выйти.

Добавить комментарий

Ваш e-mail не будет опубликован.

Перед отправкой формы:
Human test by Not Captcha