Чарлиплексинг
Предлагаю вашему вниманию полезное рабочее решение, как при помощи трех пинов контроллера независимо управлять шестью светодиодами. Его придумал сотрудник компании Maxim Чарли Аллен. В этой статье мы научимся принципам работы так называемого «чарлиплексинга».
Для начала поборемся с неподписёрством – друзья, помогите каналу и просто клацните кнопку подписаться и лайк. Поехали дальше.
Это должно быть мега интересно тем, кто юзает мелкие контроллеры типа Attiny и другие.
Но так же например мне лично такого метода не хватало при конструировании щитков управления различными устройствами, где на передней панели щитка нужно было размещать несколько светодиодов индикации включения исполнительных механизмов, а так же пару кнопок со светодиодной индикацией. Одной кнопкой например включается автоматический режим, а другой ручной режим, или одной пуск, а второй стоп и их нужно подсвечивать при смене режима. И по таким как бы мелочам уходит порядочное количество пинов. Допустим есть три исполнительных механизма и две кнопки с подсветкой. Это получается 5 светодиодов и 5 выходов контроллера только на индикацию. Для Arduino Nano или Uno, например, это много в более менее серьезном проекте там, где еще необходимо управлять несколькими реле и несколькими датчиками плюс устройство на шине SPI.
В нескольких проектах мне пришлось всё-таки применить расширители входов-выходов с управлением по I2C. Но что, если можно было обойтись без расширителя, с меньшим количеством пинов и даже с меньшим количеством ограничительных резисторов. Чарли Аллен показал в свое время миру, как можно использовать третье состояние пина контроллера для управления бо́льшим количеством светодиодов чем все привыкли.
Использование третьего состояния вывода контроллера
Пин в режиме дискретного выхода:Логическая “1” -> На выход идет напряжение питанияЛогический “0” -> На выход подключен общий провод(минус питания)Пин в режиме входа -> Высокоомное состояние
То есть у нас в руках есть следующие состояния пина контроллера: единица – это переключение на плюс питания; ноль – это переключение на минус питания или на общий провод; и третье – это высокоомное состояние, когда пин сконфигурирован как дискретный вход. Эти три значения можно обыграть для коммутации шести светодиодов.
Схема следующая.
В неё входит контроллер Arduino Nano, три резистора на 150 Ом и 6 светодиодов. Интересно, что к ним не нужно даже вести общий провод. Светодиоды включены попарно параллельно с обратной полярностью друг к другу. Здесь, чтобы включать одновременно только один из шести светодиодов, необходимо различное состояние на трех выводах контроллера Arduino. Каждому светодиоду будет соответствовать своя комбинация отличных друг от друга состояний трёх пинов. Представим, что нужно зажечь светодиод LED1. Для этого на вывод D5 требуется подать сигнал высокого уровня, а на вывод D6 – сигнал низкого уровня. Если при этом не должен зажигаться ни один другой светодиод схемы, то вывод D7 нужно перевести в режим входа. Тем самым мы предотвратим протекание тока через любой из светодиодов, непосредственно подключенных к нему.
D5,D6,D71, 0,-1 - LED10, 1,-1 - LED2-1, 0, 1 - LED4-1, 1, 0 - LED30,-1, 1 - LED61,-1, 0 - LED5
Комбинация сигналов для отдельных светодиодов такая. В табличку сведены состояния выходов контроллера для зажигания каждого светодиода. И здесь становится понятно, что одновременно мы статически не сможем зажигать несколько светодиодов, для этой задачи необходимо динамически переключать состояния выходов с такой скоростью, чтобы человеческому глазу эти переключения не были заметны. Хорошо, что контроллеры с этим прекрасно справляются, если их не слишком нагружать другими задачами.
Соединим все компоненты на монтажке. Я беру обычные светодиоды, а потом заменю их ультраяркими. Надеюсь висячие провода не сильно будут закрывать светодиоды.
Первая пробная программа
void setup(){pinMode(6, OUTPUT); // 1digitalWrite(6, 1);digitalWrite(7, 0);pinMode(7, OUTPUT); // 0}pinMode(5, INPUT); // -1 } void loop() {
Открываем Arduino IDE и набрасываем программу. Для начала просто для свечения первого светодиода, чтобы убедиться в функционировании идеи. Пятый пин конфигурируется как выход и выставляется в единицу. Шестой тоже как выход и выставляется в ноль. Седьмой вывод конфигурируем как дискретный вход. На нём будет высокоомное состояние. Клацаю загрузить скетч в контроллер. И первый светодиод горит за милую душу. Хорошо, один может светить. Теперь попробуем, например, третий зажечь. Небольшие изменения в программе: единицу ставлю на 6-й пин; ноль – на седьмой пин, а минус один на пятый. Загружаю скетч в контроллер и о чудо! Хорошо, таким образом можно светить один конкретный светодиод из шести. Но мы ведь здесь собрались, чтобы научиться светить много одновременно.
Программа динамического переключения светодиодов
const int pins[] = {5, 6, 7};const int pinLEDstates[6][3] = {{1, 0, -1}, // LED 1{-1, 1, 0}, // LED 3{0, 1, -1}, // LED 2 {-1, 0, 1}, // LED 4};{1, -1, 0}, // LED 5 {0, -1, 1} // LED 6 int ledState[6];ledState[1] = 0;void setup() { } void loop() { ledState[0] = 1; ledState[2] = 1;refresh();ledState[3] = 0; ledState[4] = 1; ledState[5] = 1; }if (ledState[led])void refresh() { for (int led = 0; led < 6; led ++) { clearPins(); {}setPins(led); } else { clearPins(); } delay(1); }if (pinLEDstates[led][pin] == -1)void setPins(int led) { for (int pin = 0; pin < 3; pin ++) { { pinMode(pins[pin], INPUT);digitalWrite(pins[pin], pinLEDstates[led][pin]);} else { pinMode(pins[pin], OUTPUT); } } } void clearPins() {}for (int pin = 0; pin < 3; pin ++) { pinMode(pins[pin], INPUT);}
Для этого усложняем прогу до неузнаваемости. Сначала идет объявление номеров пинов в массиве pins[]. Следующий двумерный массив содержит комбинации состояний выходов для каждого светодиода. Массив ledState[] будет содержать необходимые состояния ледов (0 – выключен, 1 – включен). Функция setup остается пустой. В функции loop выставляем необходимые состояния светодиодов, а функция refresh() динамично попереключает светодиоды так как мы делали в первом скетче, только намного быстрее. Она в цикле шесть раз сначала переводит все три выхода в режим входа при помощи функции clearPins. При этом все светодиоды гаснут на короткое время. Дальше проверяется необходимое состояние для очередного светодиода, и, если его надо засветить, программа идет в функцию setPins, которая выставит состояния трех пинов для этого леда. Если светодиод не должен светиться, обработчик бросается в функцию clearPins. Дальше в любом случае ждем одну миллисекунду и идем снова по циклу перебирать светодиоды. Проще говоря прога циклически периодически засвечивает или тушит следующий по очереди светодиод на одну миллисекунду, а в промежутках между обработкой следующего по порядку светодиода, их все тушит на несколько микросекунд. Кстати, менять состояния светодиодов можете при помощи массива ledState. Загружаем программу и видим, как светятся все светодиоды и довольно ярко. Теперь потушим второй и четвертый светодиоды. Загрузим скетч. Все работает, ставим галочку в своей трудовой книжке.
С этим же скетчем подключаем ультраяркие светодиоды вместо обычных и убеждаемся, что они тоже прекрасно светятся как надо.
Выводы
Теперь какие же выводы можно сделать по этой схеме включения светодиодов. Это хороший вариант дешевого решения вопроса нехватки входов-выходов контролера. Кстати есть схемы и на большее количество светодиодов и пинов соответственно. Интерес так же может представлять возможность подключать какие-то исполнительные механизмы в эту схему, используя вместо наших индицирующих светодиодов оптопары. Представьте, что вы таким образом сможете управлять шестью оптопарами. Это будет не простое управление нагрузкой, ведь здесь управление импульсное, но в некоторых случаях возможно будет выгодно заморочиться. Недостатки схемы вижу следующие: низкая надежность, в том смысле, что, если один светодиод выходит из строя, остальные поведут себя непредсказуемо. Невозможность применения аппаратной ШИМ на пинах контроллера. Хотя теоретически можно управлять яркостью светодиодов обыграв длительности свечения и погасания программно. Из недостатков так же отмечаем сложность программы, которая так же может накладывать ограничения и на основную программу. Мы например не сможем прерывать цикл программы другими задержками типа delay, ибо светодиоды начнут подмигивать. Хотя эта проблема решается при оперировании светодиодами в прерываниях по таймеру. Напишите в комментах какие плюсы и минусы я ещё не упомянул. Так что, несмотря на программные сложности, по этой схеме просматриваются многие полезные применения. Я в ней вижу больше плюсов и для себя точно беру её на заметку. Спасибо за внимание! Подпишитесь на наш канал и группу в фейсе – там много интересного. До скорых встреч.
Датчик уровня дискретный горизонтальный
Дискретный датчик, срабатывающий при достижении жидкостью определенного уровня и выше его. В сработа..
113.03грн.
DS3231 часы для Raspberry Pi (RTC)
ЧАСЫ РЕАЛЬНОГО ВРЕМЕНИ DS3231 ДЛЯ RASPBERRY PI, ORANGE PIЧасы DS3231 производятся в различных форм-ф..
125.34грн.
Двойная шестерня для зубчатого ремня на 20 зубьев под ось 8 мм
Сдвоенная шестерня для передачи крутящего момента с одного вала на другой.Применяется для разделения..
75.37грн.
Контроллер ESP32-WROOM-32 (8MB)
ESP32-WROOM-32 - это мощный универсальный модуль Wi-Fi + BT + BLE MCU, предназначенный для широкого ..
243.36грн.
Адаптер для радио модуля NRF24L01
Модуль, облегчающий подключение радио приемо-передатчика NRF24L01 к любительским контроллерамНа..
25.66грн.