#.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-битных регистра)