ATtiny13 против ПЛК, или как получить 14 I/O от контроллера с 8 ногами

Прежде чем приступить, хотел бы предупредить рьяного читателя.

  • То, что я описываю, делать нельзя по многим причинам, эти причины вам радостно укажут в комментариях, и я ни коим образом не призываю так делать. И ни в коем случае я не утверждаю, что описанным ниже устройством можно заменить реальный ПЛК. Всё описанное было сделано только для того, чтобы доказать себе, что это технически возможно, и не применяется на реальном оборудовании.
  • Если вам становится плохо только от упоминания слова «Ардуино», вам лучше не читать. Все действия с контроллером я выполнял в среде Arduino IDE, мне так проще. Но ничто не мешает сделать всё то же без использования оной.

  • Давно хотел написать статью о своих экспериментах с ATtiny13, но отпугивало прежде всего отношение к ардуинщикам на сайте. Тем более, что контроллерами я занимаюсь всего несколько лет (опять же благодаря Arduino, эх, где ж вы раньше были!). Комментарии к статье На столбе висят три глаза… показали, что тема всё же интересна достаточному числу пользователей. Кстати, предполагалось название статьи «ПЛК на ATtiny13», но в тех же комментариях мне лицом об стол вежливо объяснили, что описанное устройство не может называться «ПЛК». Ну нет, так нет.

    Что нам нужно от ПЛК?
    Началось с того, что я захотел сделать функциональный аналог ПЛК, которые применяются у меня на предприятии, с учётом того, как именно они применяются. Большая часть схем управления у нас релейные со всеми вытекающими недостатками. Так же местами применяются ПЛК разного типа, начиная с 90-х годов. В основном они выполняют логическую задачу схемы управления, отталкиваясь от состояния концевых выключателей и бесконтактных датчиков положения.

    Никаких сложных интерфейсов, никаких аналоговых сигналов. Включено-выключено. Всё. Даже нагрузкой для выходов ПЛК по большей части служат те же реле, от которых так стремились избавиться. (Самое весёлое, что практически везде применены релейные выходы ПЛК, которые коммутируют внешние реле, которые коммутируют электромагниты гидравлических распределителей… Иногда добавляется ещё одно звено из пускателя.) Значит, что же мне нужно от ПЛК:

  • Дискретные входы под уровень сигнала 24 вольта.
  • Дискретные выходы с напряжением 24 вольта.
  • Отработка внутреннего алгоритма согласно заданной схемы, которую можно изменить при необходимости (в основном в процессе отладки).
  • Быстродействие порядка 50 мсек, для замены релейных схем больше не нужно.
  • И всё. Никаких интерфейсов. Никаких прерываний. Никаких экранов. Ах, да, экраны… Не помешает отображение состояния входов и выходов, здесь надёжней светодиодов пока ничего не придумали. Ну и не забываем, что всё делается из спортивного интереса, соответственно бюджет ложится на плечи разработчика. Кстати, очень хороший стимул.

    Если не брать в расчёт уровень сигнала в 24 вольта, то с задачей легко справляется абсолютно любой микроконтроллер с количеством I/O (входов/выходов) не меньше требуемого.

    Разбираемся с уровнями
    Изначально я хотел применять на входах оптроны. Любой, кто более-менее разбирается в электронике, тем более промышленной, знает, что оптронов много не бывает. В комментариях вам подробно расскажут, почему нельзя без оптронов. Но я взвесил все За и Против, и решил отказаться. Так что некоторые могут дальше не читать, и сразу переходить писать комментарий.
    Итак, мы имеем входной сигнал 24 вольта, или 0 вольт при отсутствии сигнала. Это позволит использовать бесконтактный индуктивный датчик положения или обычный контактный концевой выключатель. Из 24 вольт нужно получить безопасное для контроллера напряжение логической единицы. Старый добрый делитель напряжения справляется с этим как нельзя лучше.

    Резисторы посчитаны с учётом, чтобы при любых отклонениях входного напряжения на плюс-минус 20% от номинального напряжение на входе микроконтроллера было больше напряжения переключения (обычно это половина напряжения питания контроллера), но не более напряжения питания контроллера, считаем его равным 5 в. Подходит для любого контроллера семейства AVR. Кроме того, предполагаемый ток через делитель около 7 мА, что снижает вероятность влияния наводок и при этом не сильно нагружает выход датчика и источник питания. Стабилитрон на напряжение 4,7 В служит для защиты от импульсных перенапряжений при тех же наводках. Существует ещё дребезг контактов, с ним мы можем бороться программно или не бороться совсем, это ведь всего лишь макет. Теперь бы ещё сделать индикацию состояния входа. И вот здесь можно применить лайфхак, убив сразу двух зайцев:

    Светодиод на схеме выполняет две функции- работает как стабилитрон, ограничивая напряжение на уровне 2,8…2,9 вольт (только для синих и белых светодиодов!), ну и светит к тому же. Должен предупредить, что в некоторых случаях напряжения на светодиоде не достаточно для переключения входа контроллера! При использовании нескольких входов контроллера мы таким образом упрощаем монтаж и экономим несколько стабилитронов. Плавно повышая напряжение на входе, можно заметить, что момент зажигания светодиода и момент переключения входа немного не совпадают. Но нас это не очень беспокоит, так как промежуточных уровней на входе быть не должно- только 0 В или 24 В. Естественно, к этому моменту у вас в контроллере должна быть хотя бы минимальная тестовая прошивка для одного входа и одного выхода.

    Теперь выходной сигнал с контроллера тоже нужно адаптировать под 24 В, причём с учётом, что общий провод, он же минус, является общим для всех выходных реле. Здесь нужно минимум 2 транзистора и 2 резистора:

    схема

    На самом деле нужен бы ещё один резистор, и защитный диод параллельно реле, но сейчас не об этом. Поначалу я использовал эту схему. Но в один прекрасный момент обратил внимание на оптроны, от которых я отказался вначале.
    Тот, кто нам мешает, тот нам поможет
    схема
    Смотрим параметры оптронов по даташитам: самый дешёвый и доступный PC817C по выходу позволяет коммутировать U вых: 35 В: I вых: 50 мА. Те реле, что подключены к ПЛК у нас (на предприятии), берут до 45 мА. Без запаса, но вполне подходит. Большинство малогабаритных реле на 24 В и вовсе тянут до 15…20 мА. В конце концов, можно купить оптрон подороже, если очень нужно, там и ток до 80 мА, и напряжение до 60 В. Нам для макета и 817 подойдут. Чтобы вы не учились на своих ошибках, предупреждаю, что для максимального тока по выходу через светодиод оптрона нужно пропустить больше 7 мА.

    Ну и снова вспомним об индикации. Чтобы отобразить состояние выхода, добавим светодиод последовательно с светодиодом оптрона, у нас там всё равно вхолостую падает больше 3 вольт. И пора бы нарисовать защитный диод, пока вы не сожгли оптрон. Кстати, так и не смог найти методику выбора защитного диода в зависимости от параметров реле. С одной стороны, он должен быть импульсным, с другой– высоковольтным. К тому же его можно поставить параллельно транзистору, как лучше? Практика показывает, что достаточно маломощного диода IN4148 в данном случае, но хотелось бы теоретического обоснования.

    схема

    Резистор 220 ом указан с расчётом опять же на синий или белый светодиод, если поставить красный, ток в цепи с 3,5 мА вырастет до 9 мА, это нужно учитывать.

    Немного о программировании
    Ну вот, столько букв, а я до сих пор не добрался ни до сути заглавия, ни до ATtiny13. Для программирования своего контроллера я использовал проект FLProg, визуальная среда программирования, максимально приближающая программирование контроллера к программированию ПЛК на языках LAD и FBD. Созданная в этой среде схема, она же проект, компилируется в скетч Ардуино, который уже из среды Ардуино я заливаю в ATtiny13 или другой контроллер семейства AVR. Например, такая простенькая схема

    компилируется в такой код:

    bool _k1 = 0;
    void setup()
    {
    pinMode(1, INPUT);
    pinMode(2, INPUT);
    pinMode(3, OUTPUT);
    }
    void loop()
    {
    _k1 = (((((!(digitalRead (1)))) &&((digitalRead (2))))) || ((((!(digitalRead (1)))) &&(_k1))));
    digitalWrite (3, _k1);
    }
    Попробуйте всё то же написать вручную- одну скобку где-то пропустил, и всё насмарку. Огромное спасибо творцу проекта FLProg Сергею Глушенко, его программа значительно повлияла на моё «творчество» за последние три года. Ардуинщикам всё должно быть понятно и так, а остальным не знаю как объяснять. Единственное, pin на схеме и в коде– это пины контроллера в среде Ардуино, их нумерация отличается от нумерации ножек. Как всё это залить в ATtiny13, подробнейшим образом расписано здесь: Обновленное руководство по программированию Attiny13 или Attiny13a с помощью Arduino IDE Да, ещё мелочь: FLProg всё ещё не поддерживает ATtiny13 (вроде в ближайшее время должна добавиться), так что прикидываемся, что работаем с другим контроллером, например ATmega168. Просто FLProg будет предлагать к использованию пины, которых нет у ATtiny13, но их можно не брать. А уж в Arduino IDE нужно ставить правильный тип контроллера, иначе ничего не выйдет.

    Ну и о самом главном
    Что мы имеем в итоге? У нас есть ATtiny13, у которой для пользования доступны 5 ног, которые мы можем назначить входами или выходами. Если очень захотеть, можно задействовать 6 ног, но это чревато, читаем здесь, например: Мало выводов? Используем RESET.

    Ну, получим 6, всё равно мало. Как получить больше?

    А вот так:

    схема

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

    Я уже упоминал, что мне достаточно быстродействия схемы порядка 50 мсек. Значит, достаточно раз в 50 мсек быстро опросить состояние входов, затем назначить их выходами, и подать на эти выходы нужный уровень. После чего назначаем выходы входами, и повторяем процесс.

    Во время опроса на входном делителе у нас 0 вольт или 2,8 В, это же напряжение подаётся на вход микроконтроллера, в любом случае этого недостаточно для протекания тока через цепочку выхода. Для того, чтоб через выходную цепь пошёл ток, необходимо напряжение минимум 1,1 В (падение на светодиоде оптрона) плюс 2,9 В, итого минимум 4 вольта. Соответственно тока в этот момент нет, транзистор закрыт.

    Далее вход стал выходом. Если выход в состоянии логического нуля, через выходную цепь опять же не протекает ток, транзистор закрыт. Если же выход в состоянии единицы, то напряжение на нём близко к питанию, то есть около 5 В, соответственно через выходную цепочку светодиод оптрона-резистор-светодиод протекает ток, что открывает транзистор оптрона и включает реле. Часть тока в это же время протекает через резисторы 3 кОма (который горизонтально на схеме) и 680 ом. Но падения на получившемся делителе недостаточно, чтоб зажечь светодиод входной цепи. Если же в это время на входе высокий уровень, светодиод входа горит, а к току входной цепи добавляется небольшой ток от пина контроллера.

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

    Схема проверена в работе, функционирует не только в теории. Сюда просятся ещё несколько деталей для надёжности, на схеме абсолютно необходимый минимум.

    Но мы получаем только 6+6=12 входов-выходов, где взять ещё 2?

    опять схема

    Ну, логику вы поняли? Здесь уже понадобится аналоговый вход, их у нас есть) причём целых 4 штуки, правда, один опять же на ножке сброса, оставим его на чёрный день. На пине микроконтроллера в режиме опроса состояния входа напряжение 0 вольт, если на обоих входах по схеме низкий уровень, и 2,8 вольта, если на обоих входах высокий уровень (мы это уже выше проходили). А вот если на одном из них 24, а на другом 0, или наоборот, мы получаем ещё 2 промежуточных значения– 0,93 В или 1,87 В. Остаётся только сравнить полученное значение на соответствие определённым пределам, и назначить состояние входов переменным в программе. В среде Arduino IDE всё это делается довольно медленно и ресурсоёмко, но даже при этом у меня осталось свободно почти половина памяти ATtiny, и удовлетворительная скорость. Вы же можете написать всё на Ассемблере, и будет ещё круче.

    Итак, как видите, 6 выходов и 10 входов(!) можно получить от ATtiny13 даже без микросхем регистров (такой опыт у меня тоже был). Конечно, практической пользы от этого мало, отлаживать такое устройство очень неудобно. Хотя отладить можно на контроллере с большим количеством ног, а уж готовую схему «залить» в ATtiny. Ну, и экономически целесообразней сделать всё то же на ATmega8, и без танцев с бубнами. Но удовольствие не то 🙂

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

    ПЛК на КДПВ не имеет отношения к данной публикации, просто я не стал приводить фото реальных ПЛК, используемых на моём предприятии, дабы невзначай не обидеть производителя. Зато количество I/O на нём соответствует поставленной задаче. Кстати, эти цифры (8/6) появились из конкретной задачи, на которой я хотел испытать свой неПЛК, чтобы не говорить о «сферических конях в вакууме».

    Что ж, если меня не заплюют после первой публикации, возможно, напишу о своём более практическом опыте «ПЛКстроения», с фотографиями и пасьянсом. Жду отзывов.

    P.S. Если вы смотрите на схемы в статье, и думаете: «Что же мне это напоминает?»

    вот

    Оставить комментарий