Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
FaceHoof
88 / 81 / 59
Регистрация: 21.04.2014
Сообщений: 1,128
Завершенные тесты: 3
1

Эмуляция Modbus

18.09.2018, 14:16. Просмотров 1243. Ответов 11

Здравствуйте.
Есть необходимость создать эмуляцию устройства Modbus. Ну т.е. чтобы к нашему приложению можно было обратиться по этому протоколу и, на пример, запросить информацию по определённым регистрам, а мы могли это обработать и ответить.
Внезапно у меня совсем не выходит нагуглить ничего подобного. Есть множество гайдов о том, как подключиться к устройству, но не как его сэмулировать. Рад буду всему, и ссылке на полезные статьи и конкретным примерам.
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.09.2018, 14:16
Ответы с готовыми решениями:

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

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

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

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

11
kolorotur
Эксперт .NET
13213 / 10281 / 2670
Регистрация: 17.09.2011
Сообщений: 17,452
Завершенные тесты: 1
18.09.2018, 14:44 2
Цитата Сообщение от FaceHoof Посмотреть сообщение
Внезапно у меня совсем не выходит нагуглить ничего подобного. Есть множество гайдов о том, как подключиться к устройству, но не как его сэмулировать.
Первым делом, наверное, надо определиться что за устройство будете эмулировать — Modbus ведь протокол общего назначения.

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

После чего составляете список функционала, который поддерживает эмулируемое вами устройство (или придумайте свое) и пишете реализацию.
3
FaceHoof
88 / 81 / 59
Регистрация: 21.04.2014
Сообщений: 1,128
Завершенные тесты: 3
18.09.2018, 15:24  [ТС] 3
kolorotur, за мануалы спасибо!
Но вот какое устройство... Да понятия не имею)
Есть прибор вполне реальный, который общается со службой, которая раз в минуту берёт с него данные и сохраняет в файлик. Прибор находится в изолированной части сети и доступ к нему никто кроме службы не имеет. Нужно чтобы эта самая служба сама "стала прибором".
По сути надо передавать пять чисел float по сети Modbus (tcp/ip). И вот я даже не знаю как это назвать то по человечески и что мне нужно...
0
FaceHoof
88 / 81 / 59
Регистрация: 21.04.2014
Сообщений: 1,128
Завершенные тесты: 3
19.09.2018, 10:07  [ТС] 4
Ещё актуально.
Я понимаю, что скорее всего прошу сам незнама чего. Но вот прочитал я про протокол и я понятия не имею, как мне работать с данными на таком низком уровне. Я вообще надеялся, что мне тут посоветуют какую-то библиотеку, на пример, а так... Я вообще не понимаю с чего начать. Вот пришёл нам какой-то запрос по сети Modbus (tcp/ip), как его "поймать", распознать, определить какую команду шлют?
В общем, нужен хоть какой-то пример, а то я просто не понимаю с чего мне начинать.
0
FaceHoof
88 / 81 / 59
Регистрация: 21.04.2014
Сообщений: 1,128
Завершенные тесты: 3
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
Изображения
 
FaceHoof
88 / 81 / 59
Регистрация: 21.04.2014
Сообщений: 1,128
Завершенные тесты: 3
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
FaceHoof
88 / 81 / 59
Регистрация: 21.04.2014
Сообщений: 1,128
Завершенные тесты: 3
20.09.2018, 13:05  [ТС] 7
Ещё актуально. Пока так и не понял, почему в ответ 0 байт.

Добавлено через 2 часа 49 минут
Использовал другую утилиту Modbus TCP client, вот она ответ получает корректно.
0
Kostennikov
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
BaredJJ
17 / 16 / 7
Регистрация: 16.05.2017
Сообщений: 382
Завершенные тесты: 3
22.10.2018, 21:24 9
Вобще ModBus устройства бывают разные и спрашивать у них можно как минимум четыре команды. Так что нужно для начала знать какого типа устройство и какие на ней контакты. И в зависимости от этого принимать данные. А вообще зачем эмулировать устройство?
0
FaceHoof
88 / 81 / 59
Регистрация: 21.04.2014
Сообщений: 1,128
Завершенные тесты: 3
23.10.2018, 09:29  [ТС] 10
Цитата Сообщение от BaredJJ Посмотреть сообщение
А вообще зачем эмулировать устройство?
Очень долго объяснять, но если опустить подробности: устройство закрыто от остальной сети, к нему доступ имеет только один компьютер, который для сети уже видим. Но общаться с устройством надо, поэтому надо его же сэмулировать на компьютере.

Но в общем задачу я решил с помощью библиотеки EasyModbus: Библиотеки для эмуляции modbus
0
Kostennikov
1 / 1 / 0
Регистрация: 08.04.2015
Сообщений: 9
23.10.2018, 15:09 11
Зачем эмулировать??? шлюз без понтов пишется за пол часа с перекурами по 15 минут.
0
FaceHoof
88 / 81 / 59
Регистрация: 21.04.2014
Сообщений: 1,128
Завершенные тесты: 3
23.10.2018, 15:46  [ТС] 12
Цитата Сообщение от Kostennikov Посмотреть сообщение
Зачем эмулировать??? шлюз без понтов пишется за пол часа с перекурами по 15 минут.
Чтобы полностью ответить на этот вопрос мне придётся написать целую стену текста. Как бы сократить...
Короче, это самое устройство, которое не видно для остальной сети, может быть заменено другим почти таким же устройством, но не умеющим работать по Mudbus и с ним будет общаться только этот один компьютер.
Всю эту схему придумывал не я, задачу поставил тоже не я, а куда более умные люди. Так надо, короче)
0
23.10.2018, 15:46
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.10.2018, 15:46

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

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

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

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

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


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.