Управляем шторой через ПЛИС за $1.44 (или даже за $0.43)
В комментариях к предыдущей статье один уважаемый пидор воскликнул: «Как можно управлять какой‑то шторой аж на целом ПЛИС?!»Почему‑то всякий раз, когда речь заходит о ПЛИС, в воображении тех, кто что‑либо слышал о них, рисуется нечто уровня Stratix‑10 стоимостью с половину квартиры (это не шутка, именно эта микросхема стоит почти $20k за единицу). Однако ПЛИСы гораздо доступней, чем кажется. Именно поэтому сегодня мы поиграем со шторой Джойреактора при помощи ПЛИС стоимостью в полтора‑два доллара. Замечательным плюсом будет тот факт, что данные ПЛИСы можно будет программировать графически, рисуя мышкой схему!
Но сперва нам нужно вспомнить, как управлять обмотками двигателя при помощи базовых элементов цифровой логики. Двигатель имеет четыре входа, усиленных драйвером ULN2003A и чтобы он крутился, по этим входам должна пробегать пара логических единиц.
Это можно сделать при помощи цепочки из четырёх D‑триггеров (в два из которых мы загрузим лог.1, в другие два — лог.0):
При каждом «щелчке» по линии тактирования, D‑триггер запоминает значение, которое находилось у него на входе D и начинает его выдавать на выход Q. Иными словами, в цепочке из D‑триггеров каждый триггер передаст своё значение следующему.
Но наш двигатель должен вращаться в обе стороны. Можно ли соединить линии так, чтобы при «щелчке» (восходящем фронте, изменении с лог.0 на лог.1) по линии тактирования триггеры передали бы значения в обратную сторону? Ну, как бы, да:
А можем ли мы сделать так, чтобы у нас был выбор в какую сторону вращать биты внутри цепочки? Да, можем. Но для этого нам нужно такое устройство как мультиплексор:
Мультиплексоры работают так:
- на их информационные входы подают различные данные;
- на их управляющие входы подают двоичный код, выбирающие номер канала;
- а на выходе мультиплексоры выдают данные только с выбранного канала;
Мультиплексоры бывают различной разрядности, но нам сейчас будет нужны будут самые маленькие мультиплексоры:
Здесь изображён одни‑единственный блок, который будет повторён несколько раз. Если нарисовать все блоки, будет просто «макаронная фабрика» из связей, поэтому пока так
Логика обработки переключателя и концевиков прежняя:
- в промежуточном положении штора уже вышла из нижнего концевика (он выдаёт лог.0), но пока ещё не вышла из верхнего концевика (он выдаёт лог.1)
- если переключатель нажат в положение «вверх» и верхний концевик всё ещё выдаёт лог.1, то нужно крутить двигатель вверх;
- если переключатель нажат в положение «вниз» и нижний концевик всё ещё выдаёт лог.0, то нужно крутить двигатель вниз;
Теперь нужно:
- найти где‑нибудь источник тактового сигнала;
- собрать схему, выключающую его, если сигнал RUN в лог.0;
- подать тактирование на цепочку D‑триггеров (она в электронике называется «регистр»);
- подать сигнал направления вращения DIR (direction) на мультиплексоры при D‑триггерах;
- подать сигналы D‑триггеров на выход микросхемы и далее на драйвер двигателя ULN2003A;
Теперь возьмём SGL46826G — ПЛИС в корпусе TSSOP‑20 от компании Renesas — и создадим в визуальной среде разработки GreenPAK Designer простой проект:
- назначаем микросхеме вход на контакт №1 и два выхода на контакты №18 и №19;
- добавляем схеме источник внутреннего тактирования OSC2;
- добавляем один логический элемент LUT0;
- выбираем в его свойствах стандартный логический элемент AND (лог.И), наш LUT0 превращается из безликого прямоугольника в самый настоящий AND;
- соединяем всё связями как показано на рисунке;
Прошиваем нашу микросхему при помощи GreepPAK Serial Debugger, подключаем кнопку ко входу, а также щупы осциллографа к выходам и видим как всё запустилось:
Первый канал осциллографа — источник тактирования, отключаемый входом №1;
Второй канал осциллографа — вход №1, проброшенный сквозь ПЛИС на выход №19
Дорисуем чёртову сову!
Четыре входа, четыре выхода и всё то, о чём мы говорили до этого:
Работает!
Но есть проблема: хотя у SLG46826G приятный для пайки корпус и достаточно обширная аналого‑цифровая начинка, это не самая дешёвая из ПЛИСов Renesas.
На Mouser Electronics за штуку она стоит $2.13. Так как я брал сразу 25 штук, мне они достались по цене $1.44.
Но это всё ещё кратно дороже, чем ПЛИС SLG46110V, которая стоит $0.64 за 1 штуку или $0.43 (!) за 25 штук.
В предыдущей статье один уважаемый пидор возмутился использованием 1,2ГГц‑ового процессора Raspberry Pi для управления шторой и посоветовал использовать ATtinny.Так вот, SLG46110V дешевле самого дешёвого ATtinny, у котрого есть пины для 4 входов и 4 выходов: У SLG46110V помимо питания и земли есть восемь выводов, что как раз необходимо и достаточно для управления шторой. Но напрямую перенести логику из SLG46826G не получится — логических элементов маловато. Однако сейчас мы сделаем ряд таких улучшений нашего проекта, что в SLG46110V даже останутся лишние элементы!
Сначала поместим всю логику обработки переключателя и концевиков в один 4‑входовый LUT.
Суть вот в чём. Мультиплексоры, о которых мы говорили ранее, могут быть не только элементами, маршрутизирующими сигнал. Они могут стать универсальным логическим элементом, если поменять управляющие и информационные входы местами!
Есть у вас, допустим 4 входных цифровых сигнала, в соответствии с которыми выход элемента должен принимать то или иное значение. Сколько всего комбинаций этих сигналов может быть? Ну, если чуть‑чуть подумать, то 24, то есть 16 вариантов.
Что если мы возьмём 16‑канальный мультиплексор (у которого 4 линии управления),
все 4 цифровых сигнала заведём на 4 линии управления,
а на каждом канале жёстко выставим либо лог.0, либо лог.1, в зависимости от того какое значение нам нужно при каждой конкретной комбинации?
Такое устройство реализует всю необходимую нам логику!
Мультиплексор, реализующий выдачу сигнала RUN по состоянию концевиков и переключателя
Кажется расточительством использовать для такой предпосчтанной логики целый мультиплексор. Но прелесть в том, что если мы хорошо научились делать эти мультиплексоры, делаем их много и дёшево, то мы можем уже не заморачиваться на тему, как же нам соединить И, ИЛИ, НЕ и где достать ИСКЛ.ИЛИ‑НЕ.
Далее. Линия A, входящая в драйвер двигателя всегда инвертирована относительно линии C. Точно также инвертирована и B относительно D.
То есть нам достаточно наличия корректных сигналов по линиям A и B, а оставшиеся сигналы мы получим при помощи пары лог.НЕ.
Линии A и B смещены друг относительно друга на ¼ периода. При вращении в одну сторону, фронт по линии B запаздывает относительно A, при вращении в другую — опережает. Как из запаздывания на −¼ периода сделать опережение на +¼ периода? Прибавкой ½ периода, или… инверсией! То есть нам достаточно обеспечить смещение A относительно B на ¼ периода, а уж в какую сторону — это мы отрегулируем элементом лог.НЕ и чем‑нибудь вроде мультиплексора (на самом деле, элементом ИСКЛ.ИЛИ‑НЕ, если расписать его таблицу истинности).
Представим, что у нас есть некий базовый тактовый сигнал с заполнением 50%. Как сделать из него сигнал, смещённый на ¼ периода?
Ну, если у нас был бы дополнительный высокоскоростной тактовый сигнал, и сигнал выдающий короткий импульс в начале каждого периода базового сигнала, то мы могли бы по этому импульсу запускать два счётчика.
Один отсчитывал бы ¼ периода, другой ¾. А выходы с этих счётчиков можно объединить через элемент NXOR (ИСКЛ.ИЛИ‑НЕ). Он равен единице только тогда, когда его входы не равны между собой.
Это кажется невероятным, но у SLG46110V есть два встроенных счётчика, а также внутренний источник тактового сигнала с двумя выходами, в один из которых можно пустить тактовый сигнал в неизменном виде, а в другой — поделив его, например на 64.
Кстати, у этого источника есть вход‑выключатель, так что сигнал RUN от 4‑входового LUT‑а можно завести прямо туда, сэкономив лог.И.
Реальной SLG46110V у меня нет, но GreenPAK Designer имеет достаточно неплохие инструменты для симуляции.
Собираем схему:
Задаём входные сигналы, типа:
- переключатель нажимают вверх, штора поднимается;
- через некоторое время срабатывает верхний концевик;
- переключатель отпускают;
- затем переключатель нажимают вниз, штора опускается;
- почти сразу верхний концевик отпускается;
- через некоторое время штора наезжает на нижний концевик
Проводим симуляцию.
Вот так очерёдность сигналов на двигатель при вращении вверх и вниз:
------