Modbus TCP маленький обмен байтами в конце строки

#.net #modbus-tcp

#.net #modbus-tcp

Вопрос:

Я использую FluentModbus, также пробовал EasyModbus для связи с процессором Delta SE, я могу нормально общаться, пока я читаю / записываю отдельные регистры, проблема в том, что мне нужно преобразовать в Little Endian ByteSwap для доступа к удвоениям ПЛК и поплавкам, протестировал это с ModbussPoll, который я приобрел некоторое время назад для Excel.

Есть идеи, как я могу это решить?

Спасибо

Комментарии:

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

2. Для EasyModbus взгляните на ConvertRegistersToFloat ; для FluentModbus похоже, что над этим ведется некоторая текущая работа . К сожалению, поскольку это не предусмотрено стандартом Modbus, вам может потребоваться реализовать собственное решение, если вышеуказанное не поможет (простой источник modbus должен указать вам правильное направление).

Ответ №1:

спасибо за вашу помощь.

Это работает

 var ReadunitIdentifier = (byte)0xFF;
        var ReadstartingAddress = (ushort)40;
        var Readcount = (ushort)4;

       
        if (modbusTcpClient.IsConnected)
        {
            try
            {
                var byteData = modbusTcpClient.ReadHoldingRegisters<byte>(ReadunitIdentifier, ReadstartingAddress, Readcount);
                byte highByte0 = byteData[0];
                byte lowByte0 = byteData[1];
                byte highByte1 = byteData[2];
                byte lowByte1 = byteData[3];
                byte[] doubleBytes =
                {
                    lowByte0, highByte0,lowByte1,highByte1
                };
                SharedVariables.LoadcellScaled = BitConverter.ToInt32(doubleBytes, 0);
            }
  

Ответ №2:

Начиная с версии v2.1.0 , вы должны иметь возможность предоставлять расположение байтов сервера (в формате little-endian или big-endian):

 var client = new ModbusTcpClient(...);
client.Connect(..., ModbusEndianness.BigEndian);

var value = client.ReadHoldingRegisters<float>(...);
  

С ModbusEndianness.BigEndian вы указываете клиенту ожидать сервер с большим порядком байтов, который заставит клиента изменить порядок байтов в зависимости от архитектуры операционной системы клиента (в основном с малым порядком байтов).

Комментарии:

1. Спасибо, у меня он установлен в LittleEndian, но все равно нужно было выполнить байтовый обмен.

2. Извините, я был недостаточно ясен. Пожалуйста, попробуйте ModbusEndianness.BigEndian сообщить клиенту в конце строки, что сервер использует расположение байтов в конце строки в своих сообщениях Modbus. Это должно устранить необходимость менять байты вручную.

Ответ №3:

БУДЬТЕ ОСТОРОЖНЫ — большая часть того, что я прочитал выше, запутана и сбивает с толку.

Modbus обычно использует ‘большой / маленький порядковый номер’ для обозначения порядка, в котором он передает 16-разрядные блоки с большим 32-разрядным (или в принципе большим) значением.

ПОЧТИ ПРИ ЛЮБОМ ИСПОЛЬЗОВАНИИ Modbus байты НЕ меняются местами внутри каждого 16-битного значения.

Итак, если у вас есть шестнадцатеричное значение 0x33221100, порядок окончания зависит от того, в каком порядке вы отправляете два значения регистра 0x3322 и 0x1100

Некоторые пакеты Modbus s / w будут поддерживать «обмен байтами», поэтому вы можете отправить 16-разрядное значение 0x3322 как 16-разрядное значение 0x2233. Это МОЖЕТ иметь некоторое значение, если вы поместите два полученных регистра в память x86 в смежных местах, а затем сообщите программе интерпретировать его как 32-разрядное целое число.

Но нам удалось поработать с периферийными устройствами Modbus в течение 15 лет, прежде чем мы столкнулись с этим дурацким способом ведения дел.

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

Комментарии:

1. Стандарт Modbus определяет представление в формате big-Endian для регистров (16-битные значения), поэтому это не должно быть проблемой (библиотеки разберутся с этим за вас). Однако стандарт не распространяется на большие значения, поэтому, если вам нужно объединить несколько 16-разрядных регистров (например, в 32-разрядное целое число или с плавающей точкой), то порядковый номер, безусловно, важен. Поскольку большинство пользователей будут опрашивать устройство, разработанное кем-то другим, вам нужно декодировать все, что вам дано, и это то, с чем я регулярно сталкиваюсь (например, просто обработал 32-битное значение с плавающей точкой, закодированное как CDAB).

2. Не путает ли это порядковый номер байта с порядковым номером слова? Порядковый номер байта повлияет на то, как вы читаете один 16-битный регистр, но порядковый номер слова повлияет на то, как вы считываете 32-битное значение (которое, если я правильно понимаю, составляет всего два 16-битных регистра)