8-900-374-94-44
[email protected]
Slide Image
Меню

Stm32 modbus tcp: РадиоКот :: Modbus и stm32

Содержание

протокол Modbus / Блог компании Advantech IIoT / Хабр


Протокол Modbus — самый распространенный промышленный протокол для M2M-взаимодействия. Является стандартом де-факто и поддерживается почти всеми производителями промышленного оборудования.

Благодаря универсальности и открытости, стандарт позволяет интегрировать оборудование разных производителей. Modbus используется для сбора показания с датчиков, управления реле и контроллерами, мониторинга, и т.д.

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

История Modbus


Modbus был представлен в 1979 году компанией Modicon (ныне Schneider Electric). Это был открытый стандарт, работающий по интерфейсу RS-232. Позже появилась реализации протокола для интерфейсов RS-485 и Modbus TCP. Протокол быстро набрал популярность, и многие производители стали внедрять его в своих устройствах.

Позже права на протокол были переданы некоммерческой организации Modbus Organization, которая до сегодняшнего дня владеет стандартом.

В описании стандарта Modbus используются терминология, унаследованная от языков релейной логики. Так, например, некоторые регистры называются катушками (англ. coil).

Физический уровень


  • RS-232/422/485 — последовательные интерфейсы, широко распространенные в промышленности. Интерфейсы RS-422/485 обеспечивают дальность сигнала до 1200 метров. Используются протоколы Modbus RTU/ASCII
  • Сети TCP/IP — физическим каналом передачи данных могут любые ethernet-интерфейсы. Используется протокол Modbus TCP

Логический уровень



Различия протоколов Modbus
Modbus ASCII

Данные кодируются символами из таблицы ASCII и передаются в шестнадцатеричном формате. Начало каждого пакета обозначается символом двоеточия, а конец — символами возврата каретки и переноса строки. Это позволяет использовать протокол на линиях с большими задержками и оборудовании с менее точными таймерами.
Modbus RTU

В протоколе Modbus RTU данные кодируются в двоичный формат, и разделителем пакетов служит временной интервал. Этот протокол критичен к задержкам и не может работать, например, на модемных линиях. При этом, накладные расходы на передачу данных меньше, чем в Modbus ASCII, так как длина сообщений меньше.
Modbus TCP

Структура пакетов схожа с Modbus RTU, данные также кодируются в двоичный формат, и упаковываются в обычный TCP-пакет, для передачи по IP-сетям. Проверка целостности, используемая в Modbus RTU, не применяется, так как TCP уже имеет собственный механизм контроля целостности.

Формат пакета



Форматы пакета разных реализаций Modbus

Все устройства Modbus взаимодействуют, следуя модели master-slave. Запросы может инициировать только master-устройство, slave-устройства могут только отвечать на запросы, и не могут самостоятельно начинать передачу данных. В зависимости от реализации протокола, заголовки пакета различаются. Вот основные составляющие пакета, которые важно знать:

ADU (Application Data Unit) — пакет Modbus целиком, со всеми заголовками, PDU, контрольной суммой, адресом и маркерами. Отличается, в зависимости от реализации протокола.

PDU (protocol data unit) — основная часть пакета, одинаковая для всех реализаций протокола. Содержит сам payload.

Адрес устройства — адрес получателя, то есть slave-устройства. В одном сегменте Modbus-сети могут находится до 247 устройств. Только slave-устройства имеют различающиеся адреса, master-устройство не имеет адреса. Адрес «0» используется для широковещательных запросов от master, при этом, slave-устройства не могут отвечать на эти широковещательные пакеты.

Контрольная сумма — алгоритмы проверки целостности пакетов. В Мodbus RTU и ASCII используется 2 байта контрольной суммы. В Modbus RTU применяется алгоритм CRC16, в Modbus ASCII — более простой и менее надежный LRC8. В Modbus TCP контрольная сумма не добавляется в ADU, так как целостность проверяется на уровне TCP.

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

Регистры и функции Modbus


В упрощенном виде, структура запросов Modbus состоит из кода функции (чтение/запись), и данных, которые нужно считать или записать. При этом, коды функции различаются для разных типов данных. Разберем, какие бывают регистры, и функции для работы с ними.
  • Discrete Inputs — дискретные входы устройства, доступны только для чтения. Диапазон адресов регистров: с 10001 по 19999. Имеют функцию «02» — чтение группы регистров
  • Coils — дискретные выходы устройства, или внутренние значения. Доступны для чтения и записи. Диапазон адресов регистров: с 20001 по 29999. Имеет функции: «01» — чтения группы регистров, «05» — запись одного регистра, «15» — запись группы регистров
  • Input Registers — 16-битные входы устройства. Доступны только для чтения. Диапазон адресов регистров: с 30001 по 39999. Имеют функцию: «04» — чтение группы регистров
  • Holding Registers — 16-битные выходы устройства, либо внутренние значения. Доступны для чтения и записи. Диапазон адресов регистров: с 40001 по 49999. Имеют

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

Примеры работы


Для примера работы с протоколом Modbus TCP воспользуемся максимально простой консольной утилитой modbus-cli, написанной на языке Ruby. Она позволяет легко читать и писать данные в регистры Modbus.

Попробуем прочесть состояние счетчиков переданных пакетов на промышленном коммутаторе Advantech EKI-5524SSI. Для начала необходимо определить адреса регистров, хранящие нужную информацию, для этого заглянем в документацию устройства. Описание регистров находятся в разделе «Modbus Mapping Table»:


Описание значений регистров в документации коммутаторов EKI

Видно, что значение переданных пакетов для одного порта хранится в четырех регистрах, и для первого порта это регистры с 38193 по 38197. Также дано описание формата хранения данных, из которого следует, что целое число переданных пакетов хранится шестнадцатеричном формате, и значение 11223344 пакетов будет записано как 0xAB4130, справа налево.

Составим запрос:

$ modbus read 192.168.0.17 38193 4
38193   0x0000
38194   0x0000
38195   0x0000
38196   0x3459

read — команда чтения. Программа сама понимает, какую конкретно команду чтения использовать в зависимости от адреса регистра, в нашем случае будет использована команда «04», для чтения 16-битных регистров.

192.168.0.17 — IP-адрес устройства.

38193 — начальный адрес регистра.

4 — смещение относительно начального адреса. Мы читаем четыре регистра для порта 1, как следует из даташита.

Получаем ответ, содержащий значения четырех регистров. Видим, что число пакетов невелико: 0x3459, то есть 13401, — коммутатор был включен недавно.

Недостатки протокола Modbus


Справедливости ради, стоит упомянуть и о недостатках протокола. Так как он разрабатывался более 40 лет назад, когда производительность процессоров была существенно ниже и протоколы разрабатывались без учета защиты данных, он имеет рад минусов:
  • Протокол не предусматривает аутентификацию и шифрование передаваемых данных. Поэтому, при использовании Modbus TCP необходимо использовать дополнительные VPN-тоннели.
  • Slave-устройство не может инициировать передачу данных, поэтому master должен постоянно опрашивать ведомые устройства
  • Slave-устройство не может обнаружить потерю связи с Master. Эта проблема напрямую следует из предыдущей.

Однако, несмотря на все недостатки, Modbus по-прежнему остается самым распространенным промышленным протоколом, и благодаря открытости, позволяет легко объединять устройства разных производителей. Нетребовательность к ресурсам позволяет интегрировать протокол в самые маломощные устройства.

Оборудование с поддержкой Modbus


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

ADAM-6000 и WISE-4000 — модули удаленного ввода-вывода

Модули серии ADAM-6000 и WISE-4000 позволяют удаленно управлять цифровыми и аналоговыми входами/выходами по протоколу Modbus TCP. Используются для управления периферийными устройствами и сбора данных в режиме slave. Могут работать в паре с программируемым логическим контроллером, или подключаться напрямую к SCADA-серверу.⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

EKI-1200 — Modbus-шлюзы для преобразования интерфейсов



Для преобразования протоколов Modbus RTU/ASCII в Modbus TCP, используются Modbus шлюзы. Устройства серии EKI-1200 имеют на борту до четырех последовательных интерфейсов RS-232/422/485, и два Ethernet-порта. Они позволяют объединить в одну сеть устройства с разными протоколами. Например, подключить slave устройство, поддерживающее только Modbus RTU, по интерфейсу RS-485 к сегменту сети Modbus TCP.

APAX-5000, ADAM-3600, WISE-5000 — контроллеры автоматизации


Контроллеры поддерживают функции Modbus RTU в качестве slave/master и клиента/сервера Modbus TCP.

Примеры применения


Система мониторинга теплиц


Решение Advantech для мониторинга интегрирует устройства TPC-1070H, ADAM-6024, ADAM-6050, ADAM-6060 и программное обеспечение WebAccess в машинном шкафу рядом с сельскохозяйственными угодьями. Соединяясь с различными чувствительными устройствами, модули ADAM-6000 могут в режиме реального времени получать данные об окружающей среде и контролировать переключение оборудования, чтобы гарантировать, что теплица находится в оптимальной среде для роста растений. Благодаря особой функции Advantech — графической логике условий (GCL), пользователи могут определять свои собственные правила логики управления и загружать эти правила в модули ввода / вывода Ethernet ADAM-6000, а затем модули автоматически выполняют логические правила, как автономные модули. контроллер. Еще одна особенность — Peer-to-Peer (P2P) использует наиболее открытую и гибкую сеть Ethernet, чтобы не только упростить процесс внедрения без контроллера, но и сэкономить затраты на аппаратное оборудование.

Все полученные данные затем передаются через Ethernet на компьютер с сенсорной панелью TPC-1070H. Благодаря системе охлаждения без вентилятора и передней панели, соответствующей стандарту IP65, TPC-1070H представляет собой прочную и компактную конструкцию, подходящую для изменяемой операционной среды, а его мощные вычислительные возможности способны обрабатывать большие объемы данных. Для управления устройствами Advantech WebAccess позволяет инженерам или менеджерам просматривать, контролировать и настраивать систему мониторинга через интрасеть или Интернет с помощью обычного веб-браузера с любого устройства, включая планшеты и смартфоны.

Мониторинг системы нагрева воды солнечной энергией


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

Модули Adam от Advantech предоставили заказчику решение, в котором использовались модули сбора данных, подключенные через RS485, и двухпроводная шина для передачи данных со всех датчиков. Эта системная архитектура имеет два основных преимущества: во-первых, она позволяет в любое время добавлять в систему большее количество датчиков модулей сбора данных, и, во-вторых, очень легко добавлять дополнительные метки в программное обеспечение для мониторинга и записи этих значений на ПК.

Подробное, простое описание протокола Modbus TCP с примерами команд

Modbus TCP

В этой статье вы узнаете о протоколе Modbus TCP, который является развитием протокола Modbus RTU. Англоязычная версия статьи доступна на ipc2u.com.

Оглавление:

Куда посылать команду Modbus TCP?

В сети Ethernet адресом устройства является его IP-адрес. Обычно устройства находятся в одной подсети, где IP адреса отличаются последними цифрами 192.168.1.20 при использовании самой распространённой маски подсети 255.255.255.0.

Интерфейсом является сеть Ethernet, протоколом передачи данных – TCP/IP.

Используемый TCP-порт: 502.

Наверх к оглавлению

Описание протокола Modbus TCP

Команда Modbus TCP состоит из части сообщения Modbus RTU и специального заголовка.

О Modbus RTU написано в этой статье.

Из сообщения Modbus RTU удаляется SlaveID адрес в начале и CRC контрольная сумма в конце, что образует PDU, Protocol Data Unit.

Ниже приведен пример запроса Modbus RTU для получения значения AO аналогового выхода (holding registers) из регистров от #40108 до 40110 с адресом устройства 17.

11 03 006B 0003 7687

11Адрес устройства SlaveID (17 = 11 hex)
03Функциональный код Function Code (читаем Analog Output Holding Registers)
006BАдрес первого регистра (40108-40001 = 107 =6B hex)
0003Количество требуемых регистров (чтение 3-х регистров с 40108 по 40110)
7687Контрольная сумма CRC

Отбрасываем адрес устройства SlaveID и контрольную сумму CRC и получаем PDU:

03 006B 0003

К началу получившегося сообщения PDU добавляется новый 7-байтовый заголовок, который называется MBAP Header (Modbus Application Header). Этот заголовок имеет следующие данные:

MBAP Header

Transaction Identifier (Идентификатор транзакции): 2 байта устанавливаются Master, чтобы однозначно идентифицировать каждый запрос. Может быть любыми. Эти байты повторятся устройством Slave в ответе, поскольку ответы устройства Slave не всегда могут быть получены в том же порядке, что и запросы.

Protocol Identifier (Идентификатор протокола): 2 байта устанавливаются Master, всегда будут = 00 00, что соответствует протоколу Modbus.

Length (Длина): 2 байта устанавливаются Master, идентифицирующие число байтов в сообщении, которые следуют далее. Считается от Unit Identifier до конца сообщения.

Unit Identifier (Идентификатор блока или адрес устройства): 1 байт устанавливается Master. Повторяется устройством Slave для однозначной идентификации устройства Slave.

Итого получаем:

Modbus RTUSlave IDЗапросCRC
Modbus RTU1103 006B 00037687
Modbus TCP0001 0000 0006 1103 006B 0003
Modbus TCPMBAP HeaderPDU
Modbus TCPADU, Application Data Unit

Где:

0001Идентификатор транзакцииTransaction Identifier
0000Идентификатор протоколаProtocol Identifier
0006Длина (6 байтов идут следом)Message Length
11Адрес устройства (17 = 11 hex)Unit Identifier
03Функциональный код (читаем Analog Output Holding Registers)Function Code
006BАдрес первого регистра (40108-40001 = 107 =6B hex)Data Address of the first register
0003Количество требуемых регистров (чтение 3-х регистров с 40108 по 40110)The total number of registers

В ответе от Modbus TCP Slave устройства мы получим:

0001 0000 0009 11 03 06 022B 0064 007F

Где:

0001Идентификатор транзакцииTransaction Identifier
0000Идентификатор протоколаProtocol Identifier
0009Длина (9 байтов идут следом)Message Length
11Адрес устройства (17 = 11 hex)Unit Identifier
03Функциональный код (читаем Analog Output Holding Registers)Function Code
06Количество байт далее (6 байтов идут следом)Byte Count
02Значение старшего разряда регистра (02 hex)Register value Hi (AO0)
2BЗначение младшего разряда регистра (2B hex)Register value Lo (AO0)
00Значение старшего разряда регистра (00 hex)Register value Hi (AO1)
64Значение младшего разряда регистра (64 hex)Register value Lo (AO1)
00Значение старшего разряда регистра (00 hex)Register value Hi (AO2)
7FЗначение младшего разряда регистра (7F hex)Register value Lo (AO2)

Регистр аналогового выхода AO0 имеет значение 02 2B HEX или 555 в десятичной системе.

Регистр аналогового выхода АО1 имеет значение 00 64 HEX или 100 в десятичной системе.

Регистр аналогового выхода АО2 имеет значение 00 7F HEX или 127 в десятичной системе.

Наверх к оглавлению

Типы команд Modbus TCP

Приведем таблицу с кодами функций чтения и записи регистров Modbus TCP.

Код функцииЧто делает функцияТип значенияТип доступа
01 (0x01)Чтение DORead Coil StatusДискретноеЧтение
02 (0x02)Чтение DIRead Input StatusДискретноеЧтение
03 (0x03)Чтение AORead Holding Registers16 битноеЧтение
04 (0x04)Чтение AIRead Input Registers16 битноеЧтение
05 (0x05)Запись одного DOForce Single CoilДискретноеЗапись
06 (0x06)Запись одного AOPreset Single Register16 битноеЗапись
15 (0x0F)Запись нескольких DOForce Multiple CoilsДискретноеЗапись
16 (0x10)Запись нескольких AOPreset Multiple Registers16 битноеЗапись

Наверх к оглавлению

Как послать команду Modbus TCP на чтение дискретного вывода? Команда 0x01

Эта команда используется для чтения значений дискретных выходов DO.

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

Значения DO в ответе находятся в одном байте и соответствуют значению битов.

Значения битов определяются как 1 = ON и 0 = OFF.

Младший бит первого байта данных содержит значение DO адрес которого указывался в запросе. Остальные значения DO следуют по нарастающей к старшему значению байта. Т.е. справа налево.

Если запрашивалось меньше восьми значений DO, то оставшиеся биты в ответе будут заполнены нулями (в направлении от младшего к старшему байту). Поле Byte Count Количество байт далее указывает количество полных байтов данных в ответе.

БайтЗапросБайтОтвет
(Hex)Название поля(Hex)Название поля
01Идентификатор транзакции01Идентификатор транзакции
0202
00Идентификатор протокола00Идентификатор протокола
0000
00Длина сообщения00Длина сообщения
0604
01Адрес устройства01Адрес устройства
01Функциональный код01Функциональный код
00Адрес первого регистра Hi байт01Количество байт далее
00Адрес первого регистра Lo байт02Значение регистра DO 0-1
00Количество регистров Hi байт
02Количество регистров Lo байт

Состояния выходов DO0-1 показаны как значения байта 02 hex, или в двоичной системе 0000 0010.

Значение DO1 будет вторым справа, а значение DO0 будет первым справа (младший бит).

Шесть остальных битов заполнены нулями до полного байта, т.к. их не запрашивали.

КаналыDO 1DO 0
Биты00000010
Hex02

Модули с дискретным выводом: ioLogik E1211, ET-7060, ADAM-6060

Наверх к оглавлению

Как послать команду Modbus TCP на чтение дискретного ввода? Команда 0x02

Эта команда используется для чтения значений дискретных входов DI.

Запрос и ответ для DI похож на запрос для DO.

БайтЗапросБайтОтвет
(Hex)Название поля(Hex)Название поля
01Идентификатор транзакции01Идентификатор транзакции
0202
00Идентификатор протокола00Идентификатор протокола
0000
00Длина сообщения00Длина сообщения
0604
01Адрес устройства01Адрес устройства
02Функциональный код02Функциональный код
00Адрес первого регистра Hi байт01Количество байт далее
00Адрес первого регистра Lo байт03Значение регистра DI 0-1
00Количество регистров Hi байт
02Количество регистров Lo байт

Состояния выходов DI 0-1 показаны как значения байта 03 hex, или в двоичной системе 0000 0011.

Значение DI1 будет вторым справа, а значение DI0 будет первым справа (младший бит).

Шесть остальных битов заполнены нулями.

Модули с дискретным вводом: ioLogik E1210, ET-7053, ADAM-6050

Наверх к оглавлению

Как послать команду Modbus TCP на чтение аналогового вывода? Команда 0x03

Эта команда используется для чтения значений аналоговых выходов AO.

БайтЗапросБайтОтвет
(Hex)Название поля(Hex)Название поля
01Идентификатор транзакции01Идентификатор транзакции
0202
00Идентификатор протокола00Идентификатор протокола
0000
00Длина сообщения00Длина сообщения
0607
01Адрес устройства01Адрес устройства
03Функциональный код03Функциональный код
00Адрес первого регистра Hi байт04Количество байт далее
00Адрес первого регистра Lo байт02Значение регистра Hi (AO0)
00Количество регистров Hi байт2BЗначение регистра Lo (AO0)
02Количество регистров Lo байт00Значение регистра Hi (AO1)
64Значение регистра Lo (AO1)

Состояния выхода AO0 показаны как значения байта 02 2B hex, или в десятичной системе 555.

Состояния выхода AO1 показаны как значения байта 00 64 hex, или в десятичной системе 100.

Модули с дискретным вводом: ioLogik E1210, ET-7053, ADAM-6050

Наверх к оглавлению

Как послать команду Modbus TCP на чтение аналогового ввода? Команда 0x04

Эта команда используется для чтения значений аналоговых входов AI.

БайтЗапросБайтОтвет
(Hex)Название поля(Hex)Название поля
01Идентификатор транзакции01Идентификатор транзакции
0202
00Идентификатор протокола00Идентификатор протокола
0000
00Длина сообщения00Длина сообщения
0607
01Адрес устройства01Адрес устройства
04Функциональный код04Функциональный код
00Адрес первого регистра Hi байт04Количество байт далее
00Адрес первого регистра Lo байт00Значение регистра Hi (AI0)
00Количество регистров Hi байт0AЗначение регистра Lo (AI0)
02Количество регистров Lo байт00Значение регистра Hi (AI1)
64Значение регистра Lo (AI1)

Состояния выхода AI0 показаны как значения байта 00 0A hex, или в десятичной системе 10.

Состояния выхода AI1 показаны как значения байта 00 64 hex, или в десятичной системе 100.

Модули с аналоговым вводом: ioLogik E1240, ET-7017-10, ADAM-6217

Наверх к оглавлению

Как послать команду Modbus TCP на запись дискретного вывода? Команда 0x05

Эта команда используется для записи одного значения дискретного выхода DO.

Значение FF 00 hex устанавливает выход в состояние включен ON.

Значение 00 00 hex устанавливает выход в состояние выключен OFF.

Все остальные значения недопустимы и не будут влиять на состояние выхода.

Нормальный ответ на такой запрос — это эхо (повтор запроса в ответе), возвращается после того, как состояние DO было изменено.

БайтЗапросБайтОтвет
(Hex)Название поля(Hex)Название поля
01Идентификатор транзакции01Идентификатор транзакции
0202
00Идентификатор протокола00Идентификатор протокола
0000
00Длина сообщения00Длина сообщения
0606
01Адрес устройства01Адрес устройства
05Функциональный код05Функциональный код
00Адрес регистра Hi байт00Адрес регистра Hi байт
01Адрес регистра Lo байт01Адрес регистра Lo байт
FFЗначение Hi байтFFЗначение Hi байт
00Значение Lo байт00Значение Lo байт

Состояние выхода DO1 поменялось с выключен OFF на включен ON.

Модули с дискретным выводом: ioLogik E1211, ET-7060, ADAM-6060

Наверх к оглавлению

Как послать команду Modbus TCP на запись аналогового вывода? Команда 0x06

Эта команда используется для записи одного значения аналогового выхода AO.

БайтЗапросБайтОтвет
(Hex)Название поля(Hex)Название поля
01Идентификатор транзакции01Идентификатор транзакции
0202
00Идентификатор протокола00Идентификатор протокола
0000
00Длина сообщения00Длина сообщения
0606
01Адрес устройства01Адрес устройства
06Функциональный код06Функциональный код
00Адрес регистра Hi байт00Адрес регистра Hi байт
01Адрес регистра Lo байт01Адрес регистра Lo байт
55Значение Hi байт55Значение Hi байт
FFЗначение Lo байтFFЗначение Lo байт

Состояние выхода AO0 поменялось на 55 FF hex, или в десятичной системе 22015.

Модули с аналоговым выводом: ioLogik E1241, ET-7028, ADAM-6224

Наверх к оглавлению

Как послать команду Modbus TCP на запись нескольких дискретных выводов? Команда 0x0F

Эта команда используется для записи нескольких значений дискретного выхода DO.

БайтЗапросБайтОтвет
(Hex)Название поля(Hex)Название поля
01Идентификатор транзакции01Идентификатор транзакции
0202
00Идентификатор протокола00Идентификатор протокола
0000
00Длина сообщения00Длина сообщения
0806
01Адрес устройства01Адрес устройства
0FФункциональный код0FФункциональный код
00Адрес первого регистра Hi байт00Адрес первого регистра Hi байт
00Адрес первого регистра Lo байт00Адрес первого регистра Lo байт
00Количество регистров Hi байт00Кол-во записанных рег. Hi байт
02Количество регистров Lo байт02Кол-во записанных рег. Lo байт
01Количество байт далее
02Значение байт

Состояние выхода DO1 поменялось с выключен OFF на включен ON.

Состояние выхода DO0 осталось выключен OFF.

Модули с дискретным выводом: ioLogik E1211, ET-7060, ADAM-6060

Наверх к оглавлению

Как послать команду Modbus TCP на запись нескольких аналоговых выводов? Команда 0x10

Эта команда используется для записи нескольких значений аналогового выхода AO.

БайтЗапросБайтОтвет
(Hex)Название поля(Hex)Название поля
01Идентификатор транзакции01Идентификатор транзакции
0202
00Идентификатор протокола00Идентификатор протокола
0000
00Длина сообщения00Длина сообщения
0B06
01Адрес устройства01Адрес устройства
10Функциональный код10Функциональный код
00Адрес первого регистра Hi байт00Адрес первого регистра Hi байт
00Адрес первого регистра Lo байт00Адрес первого регистра Lo байт
00Количество регистров Hi байт00Кол-во записанных рег. Hi байт
02Количество регистров Lo байт02Кол-во записанных рег. Lo байт
04Количество байт далее
00Значение Hi AO0 байт
0AЗначение Lo AO0 байт
01Значение Hi AO1 байт
02Значение Lo AO1 байт

Состояние выхода AO0 поменялось на 00 0A hex, или в десятичной системе 10.

Состояние выхода AO1 поменялось на 01 02 hex, или в десятичной системе 258.

Модули с аналоговым выводом: ioLogik E1241, ET-7028, ADAM-6224

Наверх к оглавлению

Ошибки запроса Modbus TCP

Если после получения запроса устройство не может обработать его, то будет отослан ответ с кодом ошибки.

Ответ будет содержать измененный Функциональный код, его старший бит будет равен 1.

Пример:

БылоСтало
Функциональный код в запросеФункциональный код ошибки в ответе
01 (01 hex) 0000 0001129 (81 hex) 1000 0001
02 (02 hex) 0000 0010130 (82 hex) 1000 0010
03 (03 hex) 0000 0011131 (83 hex) 1000 0011
04 (04 hex) 0000 0100132 (84 hex) 1000 0100
05 (05 hex) 0000 0101133 (85 hex) 1000 0101
06 (06 hex) 0000 0110134 (86 hex) 1000 0110
15 (0F hex) 0000 1111143 (8F hex) 1000 1111
16 (10 hex) 0001 0000144 (90 hex) 1001 0000

Пример запроса и ответ с ошибкой:

БайтЗапросБайтОтвет
(Hex)Название поля(Hex)Название поля
01Идентификатор транзакции01Идентификатор транзакции
0202
00Идентификатор протокола00Идентификатор протокола
0000
00Длина сообщения00Длина сообщения
0603
0AАдрес устройства0AАдрес устройства
01Функциональный код81Функциональный код с измененным битом
04Адрес первого регистра Hi байт02Код ошибки
A1Адрес первого регистра Lo байт
00Количество регистров Hi байт
01Количество регистров Lo байт

Расшифровка кодов ошибок

01Принятый код функции не может быть обработан.
02Адрес данных, указанный в запросе, недоступен.
03Значение, содержащееся в поле данных запроса, является недопустимой величиной.
04Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие.
05Ведомое устройство приняло запрос и обрабатывает его, но это требует много времени. Этот ответ предохраняет ведущее устройство от генерации ошибки тайм-аута.
06Ведомое устройство занято обработкой команды. Ведущее устройство должно повторить сообщение позже, когда ведомое освободится.
07Ведомое устройство не может выполнить программную функцию, заданную в запросе. Этот код возвращается для не успешного программного запроса, использующего функции с номерами 13 или 14. Ведущее устройство должно запросить диагностическую информацию или информацию об ошибках от ведомого.
08Ведомое устройство при чтении расширенной памяти обнаружило ошибку паритета. Ведущее устройство может повторить запрос, но обычно в таких случаях требуется ремонт.
10
(0A hex)
Шлюз неправильно настроен или перегружен запросами.
11
(0B hex)
Slave устройства нет в сети или от него нет ответа.

Наверх к оглавлению

Программы для работы с протоколом Modbus TCP

Ниже представлены программы, которые помогут легко взаимодействовать с устройствами Modbus TCP.

Modbus Master Tool с поддержкой Modbus RTU, ASCII, TCP. Скачать

Modbus Master Tool

Modbus TCP client с поддержкой Modbus TCP. Скачать

Modbus TCP client

Наверх к оглавлению

Оборудование с поддержкой протокола Modbus TCP

Наверх к оглавлению


За более подробной информацией обращайтесь к специалистам IPC2U по телефону: +7 (495) 232 0207 или по e-mail: [email protected]

IoT шлюз Ethernet-RS485 на базе STM32 / Хабр

Привет, Хабр!

Данный пост посвящён DIY разработке Ethernet-RS485 шлюза. Цель данного шлюза – обеспечение централизованного управления нодами Mysensors со стороны контроллера умного дома.

Недавно меня таки достали провода, дюпоны, навесная пайка и т.п. и было принято давно оттягиваемое решение — сделать свои платы с нуля, т.е. всё по серьёзному. 🙂
Сказано — сделано!

Первым делом была разработана и нарисована принципиальная схема шлюза, в которой я постарался учесть все свои хотелки и пожелания. Далее произведена компоновка и подгонка платы под требуемые размеры (50×50мм). И последний этап, это заказ плат на производстве. Я заказывал на фабрике JLCPCB, 5 плат — 2$ + доставка.

Данный шлюз построен на базе МК STM32F103CB(8)T6. В качестве Ethernet чипа выступает достаточно известная микросхема от WIZnet — W5500. Транспортом данного шлюза в сети Mysensors является проводной интерфейс RS485. В качестве драйвера RS485 был выбран чип — MAX13488EESA+T, в том числе и в связи с наличием у него режима автоматического выбора направления приёма/передачи.

Итак пройдёмся поподробнее по основным частям шлюза.

Сердцем шлюза является МК STM32F103CBT6 в корпусе 48LQFN. МК построен на ядре Cortex-M3, имеет 128Кб встроенной флэш памяти и 20Кб ОЗУ. Штатная частота МК — 72МГц, но если не использовать встроенный USB порт, то частоту можно разогнать и до 128МГц, он на ней вполне стабильно работает. МК питается от 3.3В. Для полноценной работы нужны два кварца, на 8МГц и 32.768КГц. Для программирования и отладки имеется интерфейс SWD. МК можно заменить и на STM32F103C8T6, он на данный момент по памяти вполне проходит.

Ethernet чип W5500. Внутри имеет ядро Cortex M0, для связи с внешним миром присутствует порт SPI (скорость до 80 МГц). При скорости 100Mbps Full Link имеет потребление в 132мА. Есть поддержка Wake on LAN, для обозначения своего режима умеет управлять 4 светодиодами 4 (SPD / DUP / ACT / Link). В наличии 32 кбайт буферной памяти RAM для обеспечения процесса передачи TCP/IP пакетов, аппаратно обеспечивает до 8 независимых TCP/UDP сокетов (канальных соединений). Аппаратно поддерживает следующие коммутационные протоколы обработки проводного TCP/IP стека: TCP, UDP, MAC, ICMP, IPv4, ARP, IGMP, PPPoE. Диапазон рабочих температур -40…85°C. Напряжение питания — 3.3В.

И наконец драйвер RS485 — MAX13488EESA+T. Микросхема в корпусе SOIC-8 150mil. Скорость передачи данных до 16 Mb/s. Рабочее напряжение — 5В, потребляемый ток — 4.5 мA. Позволяет подключать до 128 узлов на одну линию RS485. Из главных особенностей это возможность включения режима автоматического определения направления приёма/передачи, т.е. данный драйвер может подключаться напрямую к порту UART и всё! Никаких лишних телодвижений совершать не надо.

Принципиальная схема шлюза разбита на три части:


Принципиальная схема

Схема RS485 части шлюза.


Схема МК и его периферии.


Схема части Ethernet.


Т.к. шлюз в сети Mysensors является единой точкой отказа, то к нему предъявляются повышенные требования по надёжности и безопасности. И в первую очередь он должен быть гальванически развязан от самой линии RS485. Для гальванической развязки линии данных была установлена микросхема — цифровой изолятор от TEXAS INSTRUMENTS — ISO7321CDR. Для развязки по питанию был использован изолированный DC/DC преобразователь от Traco Power – TME0505S. Защита драйвера RS485 от высоковольтных импульсов при необходимости реализовывается отдельной платой. Единственно, в виду своей компактности был оставлен защитный диод (подавитель ЭСР) VD1.

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


Рендеринг шлюза

Верхний слой.


Нижний слой.


3D — вид сверху.


3D — вид снизу.


Теперь поподробнее о схеме. Для функционирования шлюза, от МК нам необходим один порт USART и один порт SPI. МК STM32F103CBT6 имеет 3 порта USART с максимальной скоростью до 4.5Mbits/s. И два SPI порта. В результате компромисса (компоновка деталей на плате), для взаимодействия с драйвером RS485 был выбран порт USART1 (ноги PB6, PB7 с ремапом). А для взаимодействия с W5500 — порт SPI1 (ноги PA4-7).

Подключение Ethernet контроллера W5500 выполнено в соответствии с рекомендациями производителя. Единственное, что может вызвать некоторые сложности, это высокоточные резисторы, которых может не оказаться в наличии в местном радиоларьке. Но на сайте lcsc.com и ему подобных с данными резисторами всё в порядке. Для Ethernet разъёма был выбран широко распространённый бюджетный модуль — HR911105A, имеющий на борту трансформатор и два светодиода.

Самое сложное в данной плате, это запаять две 48-ножечные lqfp микросхемы. Если с этим справились, то дальнейшая сборка не представляет никаких сложностей. Настроек плата не требует и сразу после сборки готова к работе.

Хоть это и шлюз, но чтобы не пропадать добру на плате были разведены практически все пины МК, разведён ресет, и два светодиода (один из них RGB). Сделаны две площадки под микросхемы, одна под I2C EEPROM и вторая для цифрового термометра/измерителя влажности HDC1080. Термометр конечно будет измерять общую температуру по больнице, так как он установлен рядом с двумя чипами, но мало ли, вдруг кому понадобиться.

В качестве разъёма для RS485 был выбран, трёх пиновый зелёный разъём DB2EV-5.08-3P, с шагом 5.08мм. Он конечно великоват, но удобен в использовании. Остальные разъёмы за исключение microUSB выбраны — 1.25мм JST, они достаточно компактны и хорошо фиксируются.


Фото собранного шлюза

Вид сверху


Вид снизу


Для питания платы необходимы 5В, которые можно подать через разъём microUSB, либо через разъём Power. 5В питание необходимо драйверу RS485, микросхеме гальванической развязки и DC/DC преобразователю. Т.к. МК STM32 и Ethernet чип требуют питания 3.3В, на плате предусмотрен LDO регулятор — на базе микросхемы LDL1117S33R. На линиях питания 5 и 3.3В установлены танталовые и керамические конденсаторы. Большинство используемых смд компонентов — 0603.

Т.к. у всех всегда ситуации и подходы бывают разные, то некоторые вещи оставлены на откуп
пользователю. Если нам не нужна гальваническая развязка от линии RS485, то мы можем не устанавливать изолирующий DC/DC преобразователь — D1, микросхему опторазвязки — D3. В таком случае надо напаять «соплей» в предназначенные для этого места на плате.


Смотреть

По необходимости устанавливаем резисторы R31, R32 и R2, защитный диод VD3.

При первом включении на столе, шлюз нормально видел ноду, прошивки в неё залетали за 30 секунд, всё было хорошо. И да, планируемая мной скорость сети RS485 — 0.5-1Mbit. В доме будет 1Mbit, на улице 0.5Mbit. Так вот когда я поставил шлюз на его рабочее место в серверную, а ноду подключил к устройству на улице, я вполне ожидаемо столкнулся с тем, что они друг друга не увидели. С помощью осциллографа я мог наблюдать весьма удручающую картину линии RS485, но пара подтягивающих резисторов R31 и R32 быстро решила данную проблему. На фото шлюза, данные резисторы подпаяны проводками. Дело в том, что изначально я не планировал ставить их на шлюз, т.к. они нужны только на концах линии RS485, а шлюз у меня планировался в середине. Но когда подключена только одна нода, они всё же нужны и поэтому они были добавлены во второй ревизии. Терминирующий резистор на 120Ом устанавливается прямо в разъём RS485, так его проще переносить от устройства к устройству при наращивании линии.

Как это ни удивительно, но плата первой ревизии показала полную работоспособность и стабильную работу. За несколько месяцев не произошло ни одного зависания. Но с другой стороны ещё не было и гроз, а данный шлюз у меня смотрит как-раз на улицу.

Но — поживём увидим! 🙂

Таким образом была выполнена основная задача — создать компактный, высокоскоростной и надёжный Ethernet-RS485 шлюз. Чтобы не расплываться мыслями по древу, статья сосредоточена только на железной части, а программная часть сознательно вынесена за скобки.

Репозиторий с проектом шлюза

С радостью отвечу на конструктивные вопросы.

Для интересующихся постройкой УД на базе Mysensor существует русскоязычная группа в телеграмм — https://t.me/mysensors_rus и русскоязычный сайт — mysensors.ru.

PS Моя первая разработанная плата — универсальная нода Mysensors для сети RS485. Она про наполнению и разработке гораздо сложнее и интереснее данного шлюза. Если данная тема будет интересна, то моя следующая статья будет о ней.

P.P.S. Цель данной статьи показать, что нет ничего сложного в разработке и создании своих собственных плат и готовых устройств. Главное ставить цель и идти к ней!

P.P.P.S. Хочу заметить, что для меня это хобби и всего лишь вторая собственноручно разработанная плата, поэтому просьба сильно не пинать. 🙂

P.P.P.P.S 20.02.2020 — обновил плату (третья ревизия). Добавил гальванические зазоры, кондёры по 0.1uF (где их не было). Возможность установки подтягивающего резистора на ногу RO MAX13488 (его номинал над подбирать по месту) и объединения земли GND_isolate с RS485_ground.

Программная эмуляция сети Modbus RTU / Хабр


Если в качестве инструмента у Вас имеется лишь молоток, каждая проблема начинает напоминать гвоздь.

Абрахам Маслоу


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

Популярность данного протокола обусловлена его открытостью и простотой. Сфера применимости достаточно широка: от профессиональных промышленных систем автоматизации до любительских DIY-проектов распределенных управляющих систем, «умных» домов и так далее. Данный протокол был выбран и мной, когда моя команда занималась создание ПО тренажера электропоезда. Протокол Modbus RTU на физическом интерфейсе RS485 используется на данном тренажере для обеспечения ввода в управляющий компьютер данных с органов управления, смонтированных на пульте машиниста (не стоит думать что Modbus используется на настоящем подвижном составе!).

Не стоит говорить с какими трудностями сопряжена наладка ПО, взаимодействующего с сетью контроллеров, управляющих оборудованием. Особенно когда часть устройств уже существует в железе, а другая часть находится в процессе разработки и изготовления. При этом ПО верхнего уровня требуется писать с учетом его взаимодействия с эти железом. И желательно писать его так, чтобы создавать рабочий вариант системы сразу, без использования «костылей» которые всегда трудно вычищать из кода.

«Надо писать ПО, когда готовы рабочие прототипы всего железа» — скажете вы и будете правы, но… ха-ха-ха, в реальном мире такое случается редко. И вот тут нам на помощь приходят программные эмуляторы.


Подробно рассказывать о протоколе не буду. Те, кого интересуют подробности могут воспользоваться поиском — протокол открыт, в сети доступна его официальная спецификация и масса информации. Скажу лишь, что в Modbus RTU описывает двоичный формат передаваемых данных и в качестве среды передачи использует дифференциальную витую пару стандарта RS485. Может использоваться и RS232, если в сети один передатчик и один приемник, или RS422 для однонаправленной передачи данных.

Нас будет интересовать именно RS485, который является полудуплексным интерфейсом, что допускает лишь одно передающее данные устройство в каждый момент времени. Арбитраж шины в Modbus осуществляется за счет выдержки обязательного интервала тишины длиной 3,5 символа при данной скорости передачи. Каждое сообщение должно начинаться и завершаться интервалом тишины. В сети существует одно ведущее устройство (master) и несколько ведомых устройств (slave) (до 31 в одном сегменте сети, без применения репитеров). Каждое ведомое устройство имеет уникальный идентификатор ID (от 1 до 31). Передача данных ведомым осуществляется лишь в том случае, если мастер послал запрос на получение данных с этого устройства.

Типичный запрос мастера выглядит так

ID Код функции Адрес данных Количество данных (2 байта) Данные CRC16

CRC16 используется для контроля целостности передаваемых данных. Modus использует Big Endian нотацию представления данных: для значений размером 2 байта старший байт внутри сообщения идет первым). В протоколе используется четыре типа данных:
  1. Coils — дискретные выходы (1 бит) доступные для чтения/записи
  2. Discrete inputs — дискретные входы (1 бит) доступные для чтения
  3. Holding registers — регистры вывода (2 байта) доступные для чтения/записи
  4. Input registers — регистры ввода (2 байта) доступные для чтения

В ответ на запрос ведомое устройство отдает данные в следующем формате
ID Код функции Количество данных в байтах Данные CRC16

Сообщение, принятое от мастера попадает в приемный буфер всех устройств. Однако, если первый байт приемного буфера не совпадает с ID устройства, оно игнорирует принятые данные, очищая приемный буфер. Если сообщение предназначено данному устройству, то оно формирует ответ и, выдержав интервал тишины посылает его мастеру.

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

Разрабатывая ПО верхнего уровня (master реализуемый на базе ПК, например) для подобной сети, хорошо бы иметь набор программных средств, позволяющих реализовать такую концепцию


Смысл этой схемы в следующем. Допустим, у нас есть часть устройств, входящих в будущую сеть. Или пока нет ни одного такого устройства. Но есть горячее желание написать ПО для верхнего уровня управления, отладить его, с тем чтобы когда сеть будет таки реализована аппаратно нам не пришлось ничего переписывать. Для этого придется использовать физическую среду передачи, для чего используем девайс, подобный этому

Один из адаптеров используется для подключения ПО разрабатываемого мастера. Другой — для подключения эмулятора будущей сети слейвов. К отводу с белым коннектором подключаем ту часть сети, которая уже реализована аппаратно. Таким образом мы получаем возможность спокойно работать со штатным протоколом связи, постепенно вводя в работу реальную аппаратуру. К тому же, отдав объект заказчику мы не лишаемся возможность модифицировать его ПО в комфортной обстановке лаборатории без доступа к объекту. QSlave на схеме как раз таки часть сети, эмулируемая программно. Естественно, придется написать соответствующий софт, что и было сделано автором.


QSlave — открытый кроссплатформенный эмулятор сети Modbus RTU. Получить его можно по лицензии GPL v2.0 на Github по вышеприведенной ссылке.

Приложение разработано на C++ с использованием фреймворка Qt. Qt, вообще говоря, имеет библиотеки для работы с Modbus, но специфика задачи — имитация сети слейвов а не одного слейва, привела к тому, что встроенные библиотеки Qt для Modbus тут не использовались. Для обработки данных, принимаемых с виртуального последовательного порта была создана самописная библиотека modbus. Код этой библиотеки реализован в виде отдельного проекта, совершенно не зависит от интерфейса пользователя и может быть использован для сознания программных имитаций с более продвинутым функционалом. Из-за того, что эмуляция Modbus отвязана от UI, конфигурирование сети происходит с применением конфигурационных файлов. Был выбран формат XML (мы часто его используем в своих проектах). Пример конфигурации доступен в коде проекта. Комплект конфигов состоит из главного файла с расширением *.net, который выглядит так

example.net

<?xml version="1.0" encoding="UTF-8" ?>
<Config>
	<Slave>
		<!-- Описание слейва, отображаемое в списке устройств -->
		<Description>Traffic light</Description>
		<!-- Идентификатор слейва -->
		<id>1</id>
		<!-- Имя XML-файла конфигурации (без расширения *.xml) -->
		<config>traffic-light</config>
	</Slave>
</Config>

и XML-файлов конфигурации для каждого из слейвов

traffic-light.xml

<?xml version="1.0" encoding="UTF-8" ?>
<Config>
	<!-- Дискретные выходы -->
	<Coil>
		<address>16</address>
		<description>Red signal</description>
		<value>0</value>
	</Coil>
	<Coil>
		<address>17</address>
		<description>Yellow signal</description>
		<value>0</value>
	</Coil>
	<Coil>
		<address>18</address>
		<description>Green signal</description>
		<value>0</value>
	</Coil>
	
	<!-- Дискретные входы -->
	<DiscreteInput>
		<address>0</address>
		<description>Ready</description>
		<value>1</value>
	</DiscreteInput>
	
	<!-- Регистры вывода -->
	<HoldingRegister>
		<address>5</address>
		<description>Signal activity time</description>
		<value>15</value>
	</HoldingRegister>
	
	<!-- Регистры ввода -->
	<InputRegister>
		<address>2</address>
		<description>Signals count</description>
		<value>3</value>
	</InputRegister>
</Config>

Последний файл содержит описание всех данных, доступных в устройстве. Для того, чтобы загрузить конфигурацию необходимо открыть файл *.net из меню программы QSlave (File → Open config). Все файлы конфигурации должны лежать в одном каталоге. Конфигурация примера описывает сеть из одного ведомого устройства, некий виртуальный дорожный светофор, дискретные выходы которого описывают сигналы, дискретный вход обозначает некий бит готовности устройства к работе (Ready), регистр ввода сообщает число сигналов светофора, а регистр вывода задает время, в течение которого горит каждый из сигналов.

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

При всей своей простоте, данный софт помогает нам работать над ПО тренажера (который уже сдан в эксплуатацию) не выходя из лаборатории.

Но никто не говорит, что нельзя создать более продвинутый эмулятор, имитирующий работу устройств виртуальной сети. Для его создания можно использовать код библиотеки modbus, доступный в комплекте поставки QSlave.


Для создания ведомых устройств, отладки их прошивок нужна имитация мастера. Существует ряд открытых эмуляторов, таких как например QModbus. Мы использовали его в своей работе, до тех пор, пока не решили увеличить скорость передачи данных до 250 кБит/с. QModbus этого не позволяет. Его удалось пересобрать из исходников под Linux, но наши электронщики сидят на Windows, а где сборка не пошла по ряду причин. Выяснилось, что это приложение написано на Qt 4, использует сторонную библиотеку libmodbus. Хотелось иметь кроссплатформенное решение на Qt5, тем более что Qt5 уже работает с Modbus «из коробки». Поэтому был написан свой аналог, использующий стек библиотек Qt Modbus — QMaster. Он тоже доступен на Github на тех же условиях.


В заключении скажу, что работаю (на работе) в основном над закрытыми проектами. Однако, описанные инструменты разработаны лично мной в инициативном порядке в свободное время. К тому же они, в Windows-версии, статически линкованы с GPL-кодом Qt, поэтому я обязан передать их сообществу на тех же условиях, что и получил Qt. К тому же, эти инструменты могут быть полезны для читателя.

Благодарю за внимание!

AlexPuts / Modbus-TCP-for-stm32-blue-pill: В этом проекте есть несколько исправлений для оригинального Modbus TCP ENC28J60, чтобы он работал с синей таблеткой stm32 (stm32duino)

перейти к содержанию Зарегистрироваться
  • Почему именно GitHub? Особенности →
    • Обзор кода
    • Управление проектами
    • Интеграции
    • Действия
    • Пакеты
    • Безопасность
    • Управление командой
    • Хостинг
    • мобильный
    • Истории клиентов →
    • Безопасность →
  • команда
  • предприятие
  • Проводить исследования
    • Изучите GitHub →
    Учитесь и вносите свой вклад
    • Темы
    • Коллекции
    • В тренде
    • Учебная лаборатория
    • Руководства с открытым исходным кодом
    Общайтесь с другими
.

malik1988 / Modbus-STM32: приложение протокола Modbus для STM32

перейти к содержанию Зарегистрироваться
  • Почему именно GitHub? Особенности →
    • Обзор кода
    • Управление проектами
    • Интеграции
    • Действия
    • Пакеты
    • Безопасность
    • Управление командой
    • Хостинг
    • мобильный
    • Истории клиентов →
    • Безопасность →
  • команда
  • предприятие
  • Проводить исследования
    • Изучите GitHub →
    Учитесь и вносите свой вклад
    • Темы
    • Коллекции
    • В тренде
    • Учебная лаборатория
    • Руководства с открытым исходным кодом
    Общайтесь с другими
      .

      kiltum / modbus: очень простой Modbus для STM32 HAL FreeRTOS

      перейти к содержанию Зарегистрироваться
      • Почему именно GitHub? Особенности →
        • Обзор кода
        • Управление проектами
        • Интеграции
        • Действия
        • Пакеты
        • Безопасность
        • Управление командой
        • Хостинг
        • мобильный
        • Истории клиентов →
        • Безопасность →
      • команда
      • предприятие
      • Проводить исследования
        • Изучите GitHub →
        Учитесь и вносите свой вклад
        • Темы
        • Коллекции
        • В тренде
        • Учебная лаборатория
        • Руководства с открытым исходным кодом
        Общайтесь с другими
        • События
        • Форум сообщества
        • GitHub Education
      .

      eziya / STM32_HAL_FREEMODBUS_TCP: TCP порт FreeMODBUS для библиотеки STM32 HAL

      перейти к содержанию Зарегистрироваться
      • Почему именно GitHub? Особенности →
        • Обзор кода
        • Управление проектами
        • Интеграции
        • Действия
        • Пакеты
        • Безопасность
        • Управление командой
        • Хостинг
        • мобильный
        • Истории клиентов →
        • Безопасность →
      • команда
      • предприятие
      • Проводить исследования
        • Изучите GitHub →
        Учитесь и вносите свой вклад
        • Темы
        • Коллекции
        • В тренде
        • Учебная лаборатория
        • Руководства с открытым исходным кодом
        Общайтесь с другими
        • События
        • Форум сообщества
      .

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

      Ваш адрес email не будет опубликован. Обязательные поля помечены *