Как мне получить доступ к этим регистрам (Enron Modbus)?

#c# #modbus

#c# #modbus

Вопрос:

При использовании компьютера OMNI Flow я столкнулся с проблемой, с которой не могу разобраться. Я пытаюсь получить доступ 32 bits IEEE floating points number с помощью NModbus .

Что я делаю, чтобы получить один номер :

  1. Считайте 2 регистра ReadHoldingRegisters(byte slaveAddress, ushort StartAddress, ushort numberOfPoints) с помощью numberOfPoints = 2 с.
  2. Преобразуйте 2 ушорта, которые я прочитал, в 1 поплавок, вот так :
 private static float ToFloat(ushort[] data)  {  var bArray = new byte[4];  BitConverter.GetBytes(data[0]).CopyTo(bArray, 2);  BitConverter.GetBytes(data[1]).CopyTo(bArray, 0);  return BitConverter.ToSingle(bArray, 0);  }  
  1. Используйте этот поплавок в моем коде.

Я пробовал этот метод, и, похоже, он работает для большинства данных, которые я читаю, но сейчас у меня возникают проблемы с чтением точек (я получаю неожиданные значения, но не могу сделать вывод о причине), и я хотел бы быть уверенным, что это не связано с адресацией; точки расположены так :


адреса данных, которые я хочу прочитать


Где один адрес эквивалентен 32 битам информации, тогда как обычно используются 2 разных регистра. У моего устройства есть параметр, Modicon modbus compatible который заставил меня изучить, какой протокол он использует по умолчанию, и оказалось, что это Enron Modbus.


введите описание изображения здесь


Согласно этой части документации (в частности, в нижней части)

Начальный адрес переменной по-прежнему применяется

Это означает, что если я переключусь на обычный Modicon Modbus, я получу доступ к 2 регистрам, используя только одну точку ? Например, если бы я хотел прочитать первые две плавающие точки, мне нужно было бы прочитать 2 регистра, начиная с адреса 8080, а затем еще 2 регистра, но начиная с адреса 8081. Когда обычно я начинал с адреса 8082 для своего второго пункта.

Как мне получить доступ к этим регистрам ? Кроме того, есть ли смещение в адресации, даже если в документации указано иное ? Если бы при использовании NModbus я должен был прочитать 2 регистра с помощью ReadMultipleRegisters метода, вернул бы он правильное значение ?

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

1. Вы пишете: «У меня проблемы с чтением очков». Что именно происходит? Вы вообще не получаете никаких данных? Неожиданные значения?

2. @StevenRands Я получаю неожиданные значения, и я не уверен, исходит ли это из того, что я объяснил в посте, или из других источников. Поэтому я хотел бы услышать мнение опытного пользователя, который скажет мне, является ли это вероятным источником ошибки.

3. Какой адрес регистра хранения Modbus вы пытаетесь прочитать?

4. Отладка Modbus может быть настоящей болью. Я бы предложил сократить ваш код, чтобы вы просто читали одну пару значений регистров, и сравнить четыре байта (2 регистра х 2 байта/регистр), которые вы получите, с числовым значением, которое вы ожидаете увидеть. Затем опубликуйте эти значения в своем вопросе.

5. Без проблем. Две основные вещи, о которых следует знать: (1) У вас правильный начальный адрес-ошибки с точностью до 1 довольно часто встречаются в Modbus; (2) Порядок байтов, возвращаемых через Modbus, может не всегда быть таким, как вы ожидаете, возможно, вам потребуется переключить порты.

Ответ №1:

После нескольких тестов я заметил, что могу считывать правильное значение из регистра с помощью ReadHoldingRegisters(byte slaveAddress, ushort address, ushort numberOfPoints) с numberOfPoints = 2 , в то время как при попытке с я получаю ошибку numberOfPoints = 1 , потому что мое устройство отправляет обратно 8 байтов данных вместо 4. Это согласуется с документацией, в которой говорится, что

Вы не можете прочитать или записать частичную переменную

И так как каждая плавающая точка имеет форму 32-битного регистра, я не могу прочитать меньше 2-х шагов.

Более того, я обнаружил, что для меня считывание значения из определенного регистра (будь то плавающее или логическое значение) Мне пришлось использовать адрес, который был уменьшен на 1. Так, например, если бы я хотел прочитать значение в регистре 8080, в моем коде я должен фактически прочитать регистр 8079.

У меня было ощущение, что в адресации было смещение, но я этого не ожидал.