DIY PLC для IoT, часть 3

в 1:34, , рубрики: diy или сделай сам, DYI, IoT, open source, plc, Интернет вещей

image
Продолжение,
Начало:
Часть 1
Часть 2
Ну что-ж, пока не заминусовали в усмерть, буду продолжать публикации на тему: сделай сам контроллер и PowerLine модем. Если все же такое произойдет, то дальнейшие публикации и все уже опубликованное можно будет найти на моем сайте. Кому интересно — добро пожаловать под кат, если просто размять пальцы клавиатурой в комментариях — большая просьба дальше не читать. Да и картинок в данной статье мало.

И так, для начала, мы собрали два модуля: модуль датчиков и модуль CAN-Gate. Попробуем из них построить систему. Вообще, модулей в системе ( допустим «Умный дом» ), может быть достаточно много, требуется их объединить в единую сеть. Уже упоминалось, что «на борту» платы процессорной модулей имеется физическая реализация поддержки CAN. Эта шина (протокол) крайне гибка и пригодна для многих применений. Её используют в тяжёлых и ответственных применениях: автомобили, суда, самолёты, тепловозы, ядерные реакторы, ускорители частиц, управление телескопами и лифтами, банковские терминалы, медицинские приборы… На основе CAN, Rockwell Automation, Inc (Allen-Bradley) разработали свой протокол и шину — DeviceNet.

После анализа и сравнения различных шин/протоколов был выбран именно CAN. Вернее, как стартовое решение были выбраны CAN и PowerLine (домашней «выпечки»).
Причины и критерии выбора перечислять не буду, если интересно, можете это сделать самостоятельно. Но пожалуй один из критериев все же приведу: специализированные микросхемы обеспечивающие поддержку CAN-шины соизмеримы по стоимости с аналогичными для RS-485.
И так, начнем с CAN:

Протокол

CAN (англ. Controller Area Network — сеть контроллеров) — стандарт промышленной сети, ориентированный прежде всего на объединение в единую сеть различных исполнительных устройств и датчиков. Режим передачи — последовательный, широковещательный, пакетный.

CAN разработан компанией Robert Bosch GmbH в середине 1980-х и в настоящее время широко распространён в промышленной автоматизации, технологиях «умного дома», автомобильной промышленности и многих других областях.

CAN является синхронной шиной с типом доступа Collision Resolving (CR, разрешение коллизии), который, в отличие от Collision Detect (CD, обнаружение коллизии) сетей (Ethernet), приоритетно обеспечивает доступ на передачу сообщения, что особо ценно для промышленных сетей управления (fieldbus). Передача ведётся кадрами. В шину будет передан пакет с наибольшим приоритетом. Приоритет кадра определяется состояниям бит идентификатора кадра ( доминирующие, рецессивные )

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

В то же время консорциум CANopen рекомендует следующие скорости передачи:
10 кбит/с; 20 кбит/с; 50 кбит/с; 100 кбит/с; 125 кбит/с; 250 кбит/с; 500 кбит/с; 1 Мбит/с. Рекомендуемое количество точек выборки = 3. Ну что же, будем придерживаться данных рекомендаций.

Соотношение между скоростью передачи и максимальной длиной кабеля приведено в таблице:
image

Стандарт CAN предлагает два варианта форматов кадра: базовый формат кадра и расширенный формат кадра. Основное отличие — длина идентификатора. В первом случае — 11 бит, во втором — 29. Первый вариант — уж сильно «куцо», посему его рассматривать не будем, остановимся на варианте 2.

Расширенный формат кадра данных
image

Физическая реализация

Среда передачи — гальванически развязанная неэкранированная витая диф.пара, часто её объединяют в одном кабеле с шиной питания. Стандартами оговорена также возможность применения оптики, но я не знаком с реальными примерами его использования.
Для обеспечения работы шины требуется как минимум два провода: CAN_L и CAN_H ( High и Low ). CAN неприхотлив, можно использовать даже «телефонную лапшу», и всё равно как то, но будет работать. Однако конечно, для достижения высоких скоростей и надежного обмена данными лучше использовать более качественные кабели — например, Ethernet cat5/5e, который и использую в своих проектах (по нему же можно и питание поставлять). Ещё хорош кабель USB — там два толстых провода питания и экранированная витая пара. Вообще подойдет любая витая пара с волновым сопротивлением 100-120 Ом.
Не желательны длинные отводы. Если вы соединяете несколько устройств — то лучше сделать максимально короткий отвод (до 10см), а еще лучше — сделать у устройства два порта CAN, соединить их вместе, и включать устройство в разрыв цепи, либо как в реализации наших контроллеров помещать два скрученных провода в одно отверстие клеммника.
Конечно, нужно терминировать концы линии резистором в 100-120 Ом, в нашем случае для этого предусмотрены «джамперы». Чип интерфейса CAN на плате процессора в состоянии физически поддерживать до 100 устройств на шине.

Витая пара cat 5/5e

Каких то «жестких» требований по использованию провода cat 5e для шины CAN нет, будем использовать следующие провода/маркировку:
image

Это обыкновенная медная витая пара. По одному проводу сечением 0.2 мм2 можно подать до 1.5А. Падение напряжение в отношении к расстоянию считается исходя из того, что среднее сопротивление медного провода данного сечения составит примерно 18-20 Ом на 100 м. Минимальное напряжение для питания модулей должно быть не менее 7‑8V. Самое простое — измерить напряжение на крайнем подключенном модуле, если недостаточно, то придется установить дополнительный источник питания.

Протокол логический

Как уже упоминалось, мастер непрерывно, с заданным временным интервалом, шлет запросы известным (имеющим уникальный номер в сети) модулям. Рассылкой запросов занимается отдельный программный поток. Ответы от модулей приходят асинхронно. Пакеты принимает другой поток, отвечающий за прием пакетов. Исходим из того, что примерно 50% общего времени канала должно остаться для ответа модуля, т. е. Процент «заполнения» запросами тоже — 50%. При скорости CAN 250 кбит/сек это составит примерно 1 кГц. Эту частоту делим на количество модулей в сети — получаем частоту опроса каждого модуля.
Логический протокол CAN никак не специфицирован, т. е. Формат идентификатора может быть любым.
Почитал, что предлагает консорциум CANopen… Возник вопрос, а зачем столь сложный протокол, когда мне всего то требуется пара функций? Решено протокол использовать свой. Что должно быть:

  • команда установить значения
  • команда дать значения
  • номер модуля на шине CAN

Так как битовое представления команд — идентично для всех модулей, то в начало идентификатора поместим номер модуля. В случае синхронного ответа модулей или какой то из модулей решил отправить сообщение самостоятельно, без команды опроса (напр. аварийная ситуация требующая немедленной отправки сообщения), высший приоритет будет иметь кадр с большим номером на шине CAN. Если какой-то модуль не ответил в течении максимального времени ответа — то с этим модулем явно какие то проблемы.

Протокол представляет из себя:
image

Будем «работать» полубайтами (4 бита). Первые 3 бита — не используются (длина идентификатора — 29 бит).
Далее:

  • 9 бит адрес на CAN (какому конкретно модулю пакет адресован)
  • 12 бит — код функции часть №1 (1-установить значения; 2-читать значения)
  • 8 бит — код функции часть №2, или расширение основной функции

Если в коде функции часть №2 8-й бит установлен, то пришел ответ от модуля. Данное решение предназначено потоку-приемнику пакетов. Т.к. поток приема пакетов «слушает» все подряд, то необходима фильтрация только ответов.
Если в коде функции часть №1 установлен старший бит, то пришел пакет идентифицирующий ошибку в модуле или сообщение об аварии.
В каждый модуль «зашивается» идентификатор устройства (тип) и уникальный серийный номер.
Модули всегда отвечают на пакеты им адресованные. Это одновременно является подтверждением получения пакета.
Адрес=0 — широковещательная рассылка.

Примеры (лог программы candump Linux):

can0 400200 [8] 00 00 00 00 00 00 00 00 — Запрос данных устройству с номером 4
can0 400280 [8] 07 00 00 00 00 00 00 00 — Ответ устройства номер 4

can0 400100 [8] 07 00 00 00 00 00 00 00 — Передача данных устройству с номером 4
can0 400180 [8] 07 00 00 00 00 00 00 00 — Ответ устройства номер 4 (текущее состояние)

can0 100200 [1] 00 — Запрос данных устройству с номером 1 (один байт)
can0 100280 [8] 00 00 00 00 00 00 00 00 — Ответ устройства номер 1

can0 100100 [1] FF — Передача данных устройству с номером 1 (один байт)
can0 100180 [8] FF 00 00 00 00 00 00 00 — Ответ устройства номер 1 (текущее состояние)

can0 100F00 [1] 00 — Передача данных устройству с номером 1
can0 108F80 [8] 00 00 00 00 00 00 00 00 — Ответ устройства номер 1 (ошибка, неверная команда)

Команды широковещательной рассылки (номер CAN=0;):
(Формат — «код функции часть №1»: «код функции часть №2»)
2:x — запрос данных
2:0 — дать серийный номер; устройство вернет в первых 4-х байтах Sn
в следующих 4-х байтах код (идентфикатор) устройства
2:1 — дать номер CAN; в первых 4-х байтах Sn, кому адресовано

1:x — установка значений
1:1 — не откликаться на широковещательный запрос серийного номера.
в первых 4-х байтах Sn, кому адресовано
1:2 — присвоить номер CAN.
в первых 4-х байтах Sn, кому адресовано
5-й байт номер CAN

Команды широковещательной рассылки служат для определения какие и сколько модулей подключены к шине CAN, или конфигурация системы.

Поле данных — устройство возвращает 8 байт. В зависимости от типа устройства и кода функции эти значения могут трактоваться как массивы/значение:
int/uint8_t[8]
int/uint16_t[4]
int/uint32_t[2]
int/uint64_t

Поле данных — устройство возвращает 8 байт. В зависимости от типа устройства и кода функции эти значения могут трактоваться как массивы/значение:
int/uint8_t[8]
int/uint16_t[4]
int/uint32_t[2]
int/uint64_t

Пример для «C»:

uint8_t		buf_8[8]; // Тут записаны данные полученные из CAN, этот же буфер используется для передачи данных.
uint16_t	*buf_16;
uint32_t	*buf_32;
uint64_t	*buf_64;

buf_16 = &buf_8;
buf_32 = &buf_8;
buf_64 = &buf_8;

Далее используем нужный массив/значение в зависимости от типа устройства/модуля. Контроль за границами массива — на разработчике ПО.

Конфигурированиемодулей

Для начала, необходимо выполнить «конфигурацию» модулей. Делается при помощи USB-UART переходника. Запустить программу типа terraterm, putty, …, подключиться к СОМ-порту. Скорость — 115200, один стоповый, без паритета.
Нажать «Enter», будет выведена подсказка, специфичная для каждого типа модулей.
Далее печатаем: cfg«Enter», устанавливаем номер модуля на CAN и скорость CAN. Номер в принципе может быть установлен/изменен через широковещательные команды, скорость — обязательна, и должна быть одинаковой на всех модулях сети.
Выход из режима конфигурации: q«Enter».

Пример экрана конфигурации для модуля входа 0-20мА:
image

Модуль CAN-Gate так же требует конфигурации. При нормальной работе (не режим конфигурации) отправка-получение информации подобна работе утилитам Linux candump, cansend (в одном флаконе).
Данный логический протокол, как унифицированный для системы в целом, использован в PowerLine, радиомодулях упомянутых ранее, но об этом в следующих «сериях»…

Автор: leocat33

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js