Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/29: Рейтинг темы: голосов - 29, средняя оценка - 4.69
112 / 99 / 68
Регистрация: 21.04.2014
Сообщений: 1,403
1

Эмуляция Modbus

18.09.2018, 14:16. Показов 5972. Ответов 11

Author24 — интернет-сервис помощи студентам
Здравствуйте.
Есть необходимость создать эмуляцию устройства Modbus. Ну т.е. чтобы к нашему приложению можно было обратиться по этому протоколу и, на пример, запросить информацию по определённым регистрам, а мы могли это обработать и ответить.
Внезапно у меня совсем не выходит нагуглить ничего подобного. Есть множество гайдов о том, как подключиться к устройству, но не как его сэмулировать. Рад буду всему, и ссылке на полезные статьи и конкретным примерам.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.09.2018, 14:16
Ответы с готовыми решениями:

Modbus
Добрый день. Помогите пожалуйста, нужно написать программу для опроса устройства по протоколу...

CRC 16 Modbus
Собственно есть алгоритм, в нём старший и младший байт поменяны местами и при вычислении CRC для...

Файл по Modbus
Всем привет, кто-нибудь сталкивался с таким, как передача файлов по протоколу связи Modbus. Нужна...

Modbus через RS-485
Подскажите пожалуйста,как реализуеться обмен по протоколу Modbus через RS-485? Интересует 6-ая...

11
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
18.09.2018, 14:44 2
Цитата Сообщение от FaceHoof Посмотреть сообщение
Внезапно у меня совсем не выходит нагуглить ничего подобного. Есть множество гайдов о том, как подключиться к устройству, но не как его сэмулировать.
Первым делом, наверное, надо определиться что за устройство будете эмулировать — Modbus ведь протокол общего назначения.

Если определились, то начинайте читать документацию:
Спек протокола
Реализация для последовательного порта
Реализация для TCP/IP
Реализация клиентской и серверной частей

После чего составляете список функционала, который поддерживает эмулируемое вами устройство (или придумайте свое) и пишете реализацию.
3
112 / 99 / 68
Регистрация: 21.04.2014
Сообщений: 1,403
18.09.2018, 15:24  [ТС] 3
kolorotur, за мануалы спасибо!
Но вот какое устройство... Да понятия не имею)
Есть прибор вполне реальный, который общается со службой, которая раз в минуту берёт с него данные и сохраняет в файлик. Прибор находится в изолированной части сети и доступ к нему никто кроме службы не имеет. Нужно чтобы эта самая служба сама "стала прибором".
По сути надо передавать пять чисел float по сети Modbus (tcp/ip). И вот я даже не знаю как это назвать то по человечески и что мне нужно...
0
112 / 99 / 68
Регистрация: 21.04.2014
Сообщений: 1,403
19.09.2018, 10:07  [ТС] 4
Ещё актуально.
Я понимаю, что скорее всего прошу сам незнама чего. Но вот прочитал я про протокол и я понятия не имею, как мне работать с данными на таком низком уровне. Я вообще надеялся, что мне тут посоветуют какую-то библиотеку, на пример, а так... Я вообще не понимаю с чего начать. Вот пришёл нам какой-то запрос по сети Modbus (tcp/ip), как его "поймать", распознать, определить какую команду шлют?
В общем, нужен хоть какой-то пример, а то я просто не понимаю с чего мне начинать.
0
112 / 99 / 68
Регистрация: 21.04.2014
Сообщений: 1,403
19.09.2018, 12:40  [ТС] 5
И так, вот к чему я пришёл на данный момент: в службе я сделал простую слушалку на сокетах и пытаюсь к ней обратиться по протоколу Modbus. Для этого использую библиотеку nModbus4. Вот приложение, которое обращается к службе:
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
public static void Main ( string [] args )
        {
            NetworkIsOk = Connect ( );
            if ( NetworkIsOk )
            {
                ushort startAddress = 100;
                ushort numInputs = 5;
                bool[] inputs = master.ReadInputs ( startAddress, numInputs );          
            }
        }
 
        private static bool Connect ( )
        {
            if ( master != null )
                master.Dispose ( );
            if ( tcpClient != null )
                tcpClient.Close ( );
            if ( CheckInternet ( ) )
            {
                try
                {
                    tcpClient = new TcpClient ( );
                    IAsyncResult asyncResult = tcpClient.BeginConnect ( ipAddress, tcpPort, null, null );
                    asyncResult.AsyncWaitHandle.WaitOne ( 3000, true ); //wait for 3 sec
                    if ( !asyncResult.IsCompleted )
                    {
                        tcpClient.Close ( );
                        Console.WriteLine ( DateTime.Now.ToString ( ) + ":Cannot connect to server." );
                        return false;
                    }
                    // create Modbus TCP Master by the tcpclient
                    master = ModbusIpMaster.CreateIp ( tcpClient );
                    master.Transport.Retries = 0; //don't have to do retries
                    //master.Transport.ReadTimeout = 1500;
                    Console.WriteLine ( DateTime.Now.ToString ( ) + ":Connect to server." );
                    return true;
                }
                catch ( Exception ex )
                {
                    Console.WriteLine ( DateTime.Now.ToString ( ) + ":Connect process " + ex.StackTrace +
                   "==>" + ex.Message );
                    return false;
                }
            }
            return false;
        }
В службу приходит абракадабра (прикладываю скрин). Как это превратить в нормальную команду, чтобы я мог её распознать и правильно обработать? Может можно как-то разложить на байты?
P.S. Или хотя бы скажите, иду я в правильном направлении или фигнёй какой-то страдаю?
Изображения
 
0
112 / 99 / 68
Регистрация: 21.04.2014
Сообщений: 1,403
19.09.2018, 13:52  [ТС] 6
Попытался пообщаться со своей службой с помощью утилиты Modbus Master Tool. Но увы, даже подключиться не выходит, я явно отвечаю что-то не то=(

Добавлено через 57 минут
Попробовал сформировать уже ответ руками:
C#
1
2
byte[] bs = new byte [] { 0001, 0000, 0009, 11, 03, 06, (byte) Convert.ToInt16 ( "AE41", 16 ), (byte) Convert.ToInt16 ( "5652", 16 ), (byte) Convert.ToInt16 ( "4340", 16 ) };
handler.Send ( bs );
Но утилита зависает намертво, а моё собственное приложение с библиотекой NModbus4 сообщает, что а ответ приходит 0 байт, но такого быть не может.
0
112 / 99 / 68
Регистрация: 21.04.2014
Сообщений: 1,403
20.09.2018, 13:05  [ТС] 7
Ещё актуально. Пока так и не понял, почему в ответ 0 байт.

Добавлено через 2 часа 49 минут
Использовал другую утилиту Modbus TCP client, вот она ответ получает корректно.
0
1 / 1 / 0
Регистрация: 08.04.2015
Сообщений: 9
22.10.2018, 21:08 8
вот как то так в таком формате приходят тебе данные ответить нужно так же только вместо адреса регистра свои данные и количество регистров опускаешь. Если корректно в Modbus TCP client то порядок байт надо поменять в программе и твои заработают
C#
1
2
3
4
5
     msg[8] = _adr[1];               // адрес регистра
                    msg[9] = _adr[0];               // для чтения
                    byte[] _length = BitConverter.GetBytes(length);
                    msg[10] = _length[1];           // количество регистров
                    msg[11] = _length[0];           // для чтения
на
C#
1
2
3
4
5
                    msg[8] = _adr[0];               // адрес регистра
                    msg[9] = _adr[1];               // для чтения
                    byte[] _length = BitConverter.GetBytes(length);
                    msg[10] = _length[0];           // количество регистров
                    msg[11] = _length[1];           // для чтения
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
57
58
if (connected) // если подключение успешно опрашиваем прибор
 
                { 
 
                NetworkStream tcpStream = TCPMBus.GetStream();
               
               
 
 
                    byte[] _id = BitConverter.GetBytes((ushort)id);
                    msg[0] = _id[1];                // я так понял 
                    msg[1] = _id[0];                // это идентификатор сообщения слейв присылает его обртнатно в том же виде
                    msg[2] = 0;                     // на данный момент не используется по описанию протокола
                    msg[3] = 0;                     // на данный момент не используется по описанию протокола
                    msg[4] = 0;                     // длинна сообщения протокола модбас т.е то что следует после этого байта но почему то этот байт равен 0 всегда хотя посмотрим как будет с другим размером запроса
                    msg[5] = 6;                     // длинна сообщения протокола модбас т.е то что следует после этого байта
                    msg[6] = 1;                     // адрес слейв как в модбас рту
                    msg[7] = 3;                     // код функции 3 или 4
                    byte[] _adr = BitConverter.GetBytes((short)startAddress+i);
                    msg[8] = _adr[1];               // адрес регистра
                    msg[9] = _adr[0];               // для чтения
                    byte[] _length = BitConverter.GetBytes(length);
                    msg[10] = _length[1];           // количество регистров
                    msg[11] = _length[0];           // для чтения
 
 
 
 
                    tcpStream.Write(msg, 0, msg.Length);
                string msd = BitConverter.ToString(msg);
 
                byte[] bytes = new byte[TCPMBus.ReceiveBufferSize];
                int bytesRead = tcpStream.Read(bytes, 0, TCPMBus.ReceiveBufferSize);
 
               
                // Строка, содержащая ответ от сервера
                string returnData = BitConverter.ToString(bytes);
                // Расшифровывает данные
                Console.Clear();
                Console.SetCursorPosition(0, 1);
                Console.WriteLine("Запрос: " + (i+1));
                Console.WriteLine("TX: " + msd);
                Console.WriteLine("RX: "+ returnData);
                byte[] values = new byte[2];
               
 
                        values[1] = (byte)(bytes[9]);
                        values[0] = (byte)(bytes[10]);
                        Console.WriteLine("распознанные данные, регистр "+ (i+1)+ ": " + BitConverter.ToUInt16(values, 0));            
                    
                  
                Thread.Sleep(500);
                    if (i == col_1-1)
                    { TCPMBus.Close(); }
                    i++;
                }
 
            }
1
19 / 18 / 7
Регистрация: 16.05.2017
Сообщений: 447
22.10.2018, 21:24 9
Вобще ModBus устройства бывают разные и спрашивать у них можно как минимум четыре команды. Так что нужно для начала знать какого типа устройство и какие на ней контакты. И в зависимости от этого принимать данные. А вообще зачем эмулировать устройство?
0
112 / 99 / 68
Регистрация: 21.04.2014
Сообщений: 1,403
23.10.2018, 09:29  [ТС] 10
Цитата Сообщение от BaredJJ Посмотреть сообщение
А вообще зачем эмулировать устройство?
Очень долго объяснять, но если опустить подробности: устройство закрыто от остальной сети, к нему доступ имеет только один компьютер, который для сети уже видим. Но общаться с устройством надо, поэтому надо его же сэмулировать на компьютере.

Но в общем задачу я решил с помощью библиотеки EasyModbus: Библиотеки для эмуляции modbus
0
1 / 1 / 0
Регистрация: 08.04.2015
Сообщений: 9
23.10.2018, 15:09 11
Зачем эмулировать??? шлюз без понтов пишется за пол часа с перекурами по 15 минут.
0
112 / 99 / 68
Регистрация: 21.04.2014
Сообщений: 1,403
23.10.2018, 15:46  [ТС] 12
Цитата Сообщение от Kostennikov Посмотреть сообщение
Зачем эмулировать??? шлюз без понтов пишется за пол часа с перекурами по 15 минут.
Чтобы полностью ответить на этот вопрос мне придётся написать целую стену текста. Как бы сократить...
Короче, это самое устройство, которое не видно для остальной сети, может быть заменено другим почти таким же устройством, но не умеющим работать по Mudbus и с ним будет общаться только этот один компьютер.
Всю эту схему придумывал не я, задачу поставил тоже не я, а куда более умные люди. Так надо, короче)
0
23.10.2018, 15:46
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.10.2018, 15:46
Помогаю со студенческими работами здесь

Как работать с modbus tcp?
кто знает как работать с modbus tcp подскажите плиз и подкинте пару примеров заранее блогадарен

Проблемы с подключенияем по Modbus TCP
Один и тот же код в разных программах. Одна библиотека подключена. Тем не менее в одной программе...

Использование классов в modbus TCP
Вообщем, необходимо было написать для одного человека модбас, что в принципе я и сделал. Поставили...

Передать дробное число по modbus
Здравствуйте. Создал два простых приложения (сервер и клиент) с помощью библиотеки EasyModbus,...

Формирование байтов для ответа по Modbus
Здравствуйте. Мне нужно сформировать ответ на запрос по протоколу modbus (TCP/IP). Нашёл весьма...

Лучший вариант для работы с Modbus
Здравствуйте. Внезапно у меня появилась задача: организовать передачу данных от приложения с...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru