1 / 1 / 0
Регистрация: 07.01.2013
Сообщений: 27

Приложение для управления устройством по modbus RTU

21.01.2016, 06:57. Показов 29774. Ответов 24

Студворк — интернет-сервис помощи студентам
Необходимо написать приложение для управления девайсом по modbus RTU. функция чтения 0х03, записи - 0х06 и 0х10. Не могу найти примеры как работать с modbus и в частности работы с этими функциями. Если есть у кого исходники или готовые проекты, ссылки где что почитать - поделитесь пожалуйста...
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.01.2016, 06:57
Ответы с готовыми решениями:

Приложение для управления девайсом по протоколу Modbus RTU
Здравствуйте! Необходимо написать приложение для управления источником постоянного тока по протоколу Modbus RTU. Канал обмена RS-485. ...

ModBus RTU master для компа
Может у кого есть любимая бесплатная программа эмулятора ModBus RTU master для компа. Вообщем есть устройство "раб" подключал к...

Конфигурация modbus rtu для s1200 (TIA14)
Добрый день, уважаемые форумчане. Остается только просить помощи. Уже голова пухнет, ломается и пытается ударить сама себя об стену. ...

24
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
21.01.2016, 08:56
Есть общая спецификация Modbus RTU, где оговорены, например, те команды, что ты привёл.
Есть спецификация Modbus для конкретного устройства - в каких регистрах что хранится.
Дальше вопрос - какой канал обмена? Скорее всего у тебя RS-232 или RS-485, что для тебя почти одно и тоже. В обоих случаях надо использовать объект SerialPort.

В итоге всё просто. Открываешь канал связи с нужными настройками. Формируешь массив байт, соответствующий нужной команде, передаёшь устройству и получаешь ответ.
0
1 / 1 / 0
Регистрация: 07.01.2013
Сообщений: 27
21.01.2016, 09:22  [ТС]
На компе стоит девайс RS-232 -> RS-485. Терминальной программой читаю с нужных регистров данные. Хотелось бы увидеть пример кода записи в нужный регистр_№ с помощью той же функции 0х10 числа signed int16

Опыт работы с SerialPort уже имеется.
0
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
21.01.2016, 09:35
Цитата Сообщение от EgorDS Посмотреть сообщение
Хотелось бы увидеть пример кода записи в нужный регистр_№ с помощью той же функции 0х10 числа signed int16
в чём вопрос?

Добавлено через 1 минуту
преобразование 16 битного числа в байты?
0
1 / 1 / 0
Регистрация: 07.01.2013
Сообщений: 27
21.01.2016, 14:02  [ТС]
Как вызвать функцию записи 0х10, С помощью терминальной проги я пробовал залить значения - ругается, так как записывать нужно именно этой функцией. Или вы предлагаете мне ее вручную , ручками писать ??
0
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
21.01.2016, 14:34
Общее описание Modbus
Причём здесь терминальная программа? Передача осуществляется в байтах. Как правило пакет Модбас состоит из следующих частей:
адрес устройства - 1 байт;
код функции - 1 байт, в твоём случае 0х10,
данные - много байт,
контрольная сумма - как правило, 1 байт.

Кажется стоит сказать, что вводя в терминальную программу запись "0х10" - по факту ты получаешь не 1, а, как минимум 4 байта - по байту на символ.

Добавлено через 2 минуты
И ещё, из своего опыта могу сказать, что спецификация Modbus не обязательный документ, более-менее стандартным будет только перечень команд и максимальная длинна одного пакета.
0
1 / 1 / 0
Регистрация: 07.01.2013
Сообщений: 27
28.01.2016, 07:56  [ТС]
Погуглил, посмотрел и почитал. Нашел видеоурок создания проекта в Visual Studio С# ModBus TCP.
Теперь что имеем: Скачал библиотеку, подключил ее через менеджер проекта (вот только не знаю , универсальная ли она, будет поддерживать ModBus RTU). Включаем в проект Serial Port, Указываем его рабочие параметры. На форму кидаем кн. захвата S.Port. если все ОК - едем дальше. А дальше - для меня темный лес до тех пор пока не найду примеры:
- как работать с библиотекой Modbus, передать ей параметры Serial Port, читать и писать в нужные регистры (т.е. оправить и принять байты...
0
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
28.01.2016, 08:57
EgorDS, не ты ли писал:
Цитата Сообщение от EgorDS Посмотреть сообщение
Опыт работы с SerialPort уже имеется.
Не вижу смысла в отдельной библиотеке для Modbus. Всё что тебе надо знать - описание протокола для твоей конкретной железки, понимать что такое массив и тип данных byte. Как отправлять и получать данные, а также настраивать SerialPort подробно расписано в MSDN
0
1 / 1 / 0
Регистрация: 07.01.2013
Сообщений: 27
28.01.2016, 09:29  [ТС]
1. Правильно ли я понял ? Если используешь библиотеку Modbus, то и порт RS настраиваешь и подключаешь через эту библиотеку ?
2. Если работать только через Serial Port, так же придется CRC вычислять отдельно ?
0
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
28.01.2016, 09:57
Цитата Сообщение от EgorDS Посмотреть сообщение
Правильно ли я понял ? Если используешь библиотеку Modbus, то и порт RS настраиваешь и подключаешь через эту библиотеку ?
я не знаю, как оно работает через библиотеку. Я работаю напрямую с портом. Формирую нужные данные, отправляю их в порт, получаю из порта данные и разбираю их.

Цитата Сообщение от EgorDS Посмотреть сообщение
Если работать только через Serial Port, так же придется CRC вычислять отдельно ?
Естественно.

Добавлено через 14 минут
Вот мой класс формирования пакета Modbus.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 public class TModBus
    {
        List<byte> buff;
        public const ushort myPolinom = 0xA001;
 
        public TModBus()
        {
            buff = new List<byte>();
        }
 
        public byte[] getFirmCommand(byte com, byte[] data, byte adr)
        {
            ushort crcMdb;
            buff.Clear();
            buff.Add(adr);
            buff.Add(0x42);
            buff.Add(com);
            if (data != null)
                for (int i = 0; i < data.Length; i++)
                    buff.Add(data[i]);
            crcMdb = getCrc(buff.ToArray());
            buff.Add((byte)(crcMdb & 0xFF));
            buff.Add((byte)((crcMdb >> 8) & 0xFF));
            return buff.ToArray();
        }
 
        ushort getCrc(byte[] mdbBuf)
        {
            ushort crc;
            byte tmpB;
            crc = 0xFFFF;
            for (int i = 0; i < mdbBuf.Length; i++)
            {
                tmpB = mdbBuf[i];
                for (int j = 0; j < 8; j++)
                {
                    crc = (ushort)(crc ^ (tmpB & 1));
                    if ((crc & 1) != 0)
                        crc = (ushort)((crc >> 1) ^ myPolinom);
                    else
                        crc = (ushort)(crc >> 1);
                    tmpB = (byte)(tmpB >> 1);
                }
            }
            return crc;
        }
    }
Метод getFirmCommand получает на вход адрес устройства, подкоманду (да, вот такой у нас протокол модбас) и нужные данные команды 0x42. Формируется массив байт, рассчитывается контрольная сумма. Полученный массив возвращается в вызывающий класс, который в последствии передаёт пакет данных в заранее настроенный и открытый порт.

Добавлено через 2 минуты
метод уже старенький, при желании его можно оптимизировать, но это значит выпускать новую версию программы, записывать в систему контроля версий, сдавать в архив. Оно того не стоит.
0
1 / 1 / 0
Регистрация: 07.01.2013
Сообщений: 27
28.01.2016, 10:10  [ТС]
Вот тогда не понял такой момент: Передача данных Modbus начинается синхронизацией четырьмя стартовыми импульсами. Где эти импульсы формируются ? (программно в RS 232, или RS заливает байты в преобразователь 232-485, а тот формирует строб импульсы и потом шлет наши байты.. )
0
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
28.01.2016, 10:12
Цитата Сообщение от EgorDS Посмотреть сообщение
Передача данных Modbus начинается синхронизацией четырьмя стартовыми импульсами
Это ты откуда взял?
0
1 / 1 / 0
Регистрация: 07.01.2013
Сообщений: 27
28.01.2016, 11:18  [ТС]
Уже не могу найти. Видимо вычитал когда искал инфу реализации masrer modbus для мк atmel. В перспективе хотел уйти от программы на PC и собрать свой контроллер который и будет управлять устройствами по RS-485. Хотел еще тогда узнать отслеживается ли "тишина" на линии перед передаче данных мастером ?
0
484 / 397 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
28.01.2016, 11:52
EgorDS, Сначала реализуй что-то одно, потом приступай к другому, иначе будет каша в голове (как сейчас, например) и не получится вообще ничего.
"Передача данных Modbus начинается синхронизацией четырьмя стартовыми импульсами" - видимо подразумевалась установка высокого (или низкого) уровня на ноге микросхемы, через которую реализуется последовательный интерфейс. Догадки, конечно, но эта фраза чётко относится к аппаратной части и к софту (особенно на C#) никакого отношения не имеет.
0
1 / 1 / 0
Регистрация: 07.01.2013
Сообщений: 27
01.02.2016, 09:35  [ТС]
В общем почти во всем разобрался. Наперед такой вопрос. После запроса от мастера как правило выдерживается временная пауза (ожидание на ответ). Да и перед запросом наверное тоже надо отбить 3,5 фрейма (на тишину) и проверить что бы линия свободна была. первое что приходит в голову использовать Класс Timer (баловался уже с ним). Но быть может есть другие более эффективные методы, или я слишком усложняю ?
0
Эксперт .NET
 Аватар для Rius
13084 / 7644 / 1670
Регистрация: 25.05.2015
Сообщений: 23,285
Записей в блоге: 14
01.02.2016, 10:21
EgorDS, у SerialPort есть событие приёма данных. Передали и сразу ждёте ответ.
0
 Аватар для Jman
89 / 77 / 38
Регистрация: 11.10.2015
Сообщений: 860
27.02.2018, 16:52
Всем привет! Ребята, поделитесь пожалуйста примером функции 04, для чтения input registers и для записи функцией 06. Или может линк у кого есть интересный.
0
Эксперт .NET
 Аватар для Rius
13084 / 7644 / 1670
Регистрация: 25.05.2015
Сообщений: 23,285
Записей в блоге: 14
27.02.2018, 17:09
Мог бы показать код, но он - верхушка айсберга, и вам нисколько не поможет.
Читайте описание протокола.
https://ipc2u.ru/articles/pros... _analog_in
0
 Аватар для Jman
89 / 77 / 38
Регистрация: 11.10.2015
Сообщений: 860
28.02.2018, 13:17
Цитата Сообщение от Rius Посмотреть сообщение
Мог бы показать код, но он - верхушка айсберга, и вам нисколько не поможет.
Все, с 4й разобрался, спасибо за линк. А вот что-то с 6 не получается. Есть 16 функция, как ее переделать в 6?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
 // sp это у меня SerialPort sp = new SerialPort
 
 private void BuildMessage(byte address, byte type, ushort start, ushort registers, ref byte[] message)
 {
            // Массив для CRC bytes:
            byte[] CRC = new byte[2];
 
            message[0] = address;
            message[1] = type;
            message[2] = (byte)(start >> 8);
            message[3] = (byte)start;
            message[4] = (byte)(registers >> 8);
            message[5] = (byte)registers;
            
            // Функция подсчета CRC
            GetCRC(message, ref CRC);
            message[message.Length - 2] = CRC[0];
            message[message.Length - 1] = CRC[1];
 }
 
 public bool SendFc16(byte address, ushort start, ushort registers, short[] values)
        {
                // Проверяю открыт ли порт
                if (sp.IsOpen)
                {
                    //Очишаю буфер
                    sp.DiscardOutBuffer();
                    sp.DiscardInBuffer();
                    //Сообщение 1 адрес + 1 функция + 2 старт + 2 регистр + 1 счетчик + 2 * значение регистров + 2 CRC
                    byte[] message = new byte[9 + 2 * registers];
                    //ответ 16 функции фиксированный и занимает 8 байт
                    byte[] response = new byte[8];
 
                    // Счетчик байт в сообщении:
                    message[6] = (byte)(registers * 2);
                    // Пишем:
                    for (int i = 0; i < registers; i++)
                    {
                        message[7 + 2 * i] = (byte)(values[i] >> 8);
                        message[8 + 2 * i] = (byte)(values[i]);
                    }
                    //Наше сообщение:
                    BuildMessage(address, (byte)16, start, registers, ref message);
                }
                
                if (ну тут организация проверки записи)
                {
                    // Запись успешна;
                    return true;
                }
                else
                {
                    // Ошибка CRC;
                    return false;
                }
        }
По идее тут
C#
1
 BuildMessage(address, (byte)16, start, registers, ref message);
Заменить на так наверное:
C#
1
 BuildMessage(address, (byte)6, start, registers, ref message);
И вот тут что-то надо поменять, в формировании посылки в сообщении, только что еще не понял
C#
1
2
3
4
5
6
7
8
 // Счетчик байт в сообщении:
                    message[6] = (byte)(registers * 2);
                    // Пишем:
                    for (int i = 0; i < registers; i++)
                    {
                        message[7 + 2 * i] = (byte)(values[i] >> 8);
                        message[8 + 2 * i] = (byte)(values[i]);
                    }
Подскажите как тут сделать запись в один регистр.
0
0 / 0 / 0
Регистрация: 12.11.2018
Сообщений: 2
12.11.2018, 16:52
Для адекватных людей, реализующих реальные задачи, а не абстрактные, и осиливших этот тред унылых зануд дарю ссылку:

https://sourceforge.net/projects/easymodbustcp/

Не мучайте себе всякой фигней предложенной вверху.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
12.11.2018, 16:52
Помогаю со студенческими работами здесь

Протокол Modbus RTU/ASCII для режима Slave
Здравствуйте! Стоит задача реализовать протокол Modbus ASCII/RTU для режима Slave на Си. Программа modbus_tester будет опрашивать...

Java библиотеки для Serial Master Modbus rtu
Всем привет. У кого есть опыт использования Java библиотек для общения с устройствами через конвертор интерфейсов USB-RS485 протокол Modbus...

Эмулятор для Modbus RTU (slave и master) под Linux
Необходим эмулятор для отладки modbus rtu (slave и master). Работа предполагается только через последовательный порт

Modbus RTU - разобрать сформированный запрос к Slave
Добрый день Не могу разобраться с работой modbus rtu что значит запрос 024600e260? 02 - номер модуля 46 - функция и нет нигде...

Работа с Modbus RTU
Есть некий модуль ввода/вывода, со своим адресом, дискретный и аналоговый сигнал поддерживает. RS-485 интерфейс, протокол MODBUS. По...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

Новые блоги и статьи
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а привычная функция main(). . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru