Как прочитать 16-битный регистр, если я получаю в нем значение с плавающей запятой, используя NModbus4

Я использую NModbus4 для чтения 16-битного регистра, в котором уже есть значение с плавающей запятой. Я получаю это значение с плавающей запятой непосредственно из соответствующего программного обеспечения с регистрами, настроенными для этих значений с плавающей запятой. Эта конфигурация регистра помогает мне получить записанное значение в моей консольной программе, используя NModbus4.

Вопрос довольно прост. Nmodbus возвращает ushort[] для регистров хранения, и я хочу получить значение с плавающей запятой при чтении из ответа.

Да, я пытался прочитать два 16-битных регистра и объединить их для формирования значения с плавающей запятой (32-битного), и НЕТ, я не получаю желаемых результатов.

Например, 2.3e-007 приводит к 0, а число больше ushort приводит к типу данных 32767. Может быть, мне нужно что-то изменить в библиотеке (NModbus4). Просто какой-то намек сделает свое дело. Пожалуйста, кто-нибудь может мне помочь?

Вот мой фрагмент кода:

TcpClient masterTcpClient = new TcpClient(address.ToString(), portNo);
ModbusIpMaster master = ModbusIpMaster.CreateIp(masterTcpClient);//Created master

ushort[] inputs = null;
inputs = master.ReadHoldingRegisters(slaveId, startAddress, numInputs);//Read Registers

GetRegistersByNModbus(inputs, startAddress);//Convert registers to float
private static void GetRegistersByNModbus(ushort[] inputs, ushort startAddress)
    {
        List<float> floatList = new List<float>();
        for (int i = 0; i < inputs.Length;)
        {
            float temp = ModbusUtility.GetSingle(inputs[i++], inputs[i++]);
            floatList.Add(temp);
        }
        float[] floatArray = floatList.ToArray();
        int startReg = int.Parse(startAddress.ToString());
        for (int i = 0, j = startReg; i < floatArray.Length; i++, startAddress += 2)
        {
            Console.WriteLine("Register {0}={1}", startAddress, floatArray[i]);
        }
    }

person Samrat Matte    schedule 23.11.2018    source источник
comment
Не зная более подробностей, трудно догадаться, что происходит не так. Когда вам нужно прочитать float, что-то/кто-то пишет это раньше. Есть ли документация, как она написана? Вы пробовали обменивать loword и hiword? Каков ваш исходный код для объединения двух слов в поплавок?   -  person KBO    schedule 23.11.2018
comment
@KBO Я использую метод ReadHoldingRegisters() для чтения регистров хранения с 0101 по 0131. После предоставления startAddress, идентификатора подчиненного устройства и noofregisters для чтения он считывает регистры с 0101 по 0131 и предоставляет свое значение в ushort, как и ожидалось. Но не желанный. От 0101 до 0131 каждый регистр содержит значение с плавающей запятой, поэтому ushort дает 0, когда требуется 2.3e-007, и 32767, когда число выходит за пределы диапазона ushort. Регистры с 0101 по 0131 получают свои значения (запись) из программного обеспечения автоматизации. Нам просто нужно получить доступ к этим значениям   -  person Samrat Matte    schedule 23.11.2018
comment
Являются ли поплавки одинарной точностью IEEE-754? Предполагая, что вам нужно будет прочитать 2 ushorts, сохранить их в 4 байтах, соблюдая правильный порядок, а затем использовать что-то вроде BitConverter.ToSingle() для перевода их в число с плавающей запятой. Я предполагаю, что вы уже делаете подобное; Можете ли вы добавить какой-нибудь реальный нерабочий код, который вы используете, к своему вопросу?   -  person sellotape    schedule 23.11.2018
comment
Комментарий @sellotape должен быть ответом. Возможно, вам придется попробовать все возможные комбинации размещения двух значений ushort в 4-байтовом массиве (перестановка слов и событие, меняющее местами байты в каждом слове), поскольку не существует универсального соглашения о том, как кодировать float в Modbus.   -  person Klaus Gütter    schedule 23.11.2018
comment
@sellotape ВСЕ мой код работает. И в этом проблема. Потому что каждый регистр 16-битный, но ему назначены 32-битные значения с плавающей запятой, записанные программным обеспечением автоматизации. При чтении каждого регистра за раз я получаю эти значения с плавающей запятой как ushort. Следовательно, вышеупомянутая проблема преобразования. Я уже реализовал то, что вы сказали о BitConvertor.ToSingle(), но он будет объединять два последовательных регистра, чего я не хочу. Я просто хочу значение одного регистра в float. Может ли перенастройка регистров в канале из программного обеспечения автоматизации на 32-разрядные с 16-разрядных получить меня куда-нибудь?   -  person Samrat Matte    schedule 23.11.2018
comment
@SamratMatte - звучит так, будто у вас половина точности поплавки, а не одинарные. Ознакомьтесь с этим ответом.   -  person sellotape    schedule 23.11.2018