как читать удерживаемые значения Modbus TCP (03) - обмен 32-битным плавающим словом (CD AB) с функциональным блоком узла красного цвета?
У меня проблема с Modbus...
Чтение из Modbus TCP (FC3, размер данных 32 бита с плавающей запятой, адрес 272 десятичного числа)...
Когда Node RED считывает значения ( FC 3, чтение регистров хранения, количество 2 ) возвращает такие значения, как [0,16833]... Здесь я использую msg.payload=msg.payload[1] в функции, чтобы получить значение 16833 из множество...
Это значение моего датчика температуры.
Чтобы убедиться, что адрес Modbus правильный, я использую внешнее приложение для считывания значений с датчиков (опрос Modbus Rilheva) ...
Правильное значение считывается из модуля ПЛК, когда установлено значение:
Чтение удерживаемых значений (03) - замена 32-битного слова с плавающей запятой (CD AB) - см. экран...
Итак, кто-нибудь знает, как преобразовать его в реальное значение - вот оно 24,25...
Смотрите здесь: discourse.nodered.org/t/modbus-tcp-read-32-bit-registers/1710/2 вам нужно будет манипулировать необработанными данными, чтобы учесть ваш порядок слов.
И здесь вы видите, как вы можете получить свой float: schneider-electric.com/en/faqs/FA204140, я не знаю, было ли это реализовано в узле red.
Сначала вы можете сохранить два целых числа в буфер (поменяв местами слова, как вы упомянули в ОП). После этого прочитайте буфер как число с плавающей запятой.
Вот как будет выглядеть функциональный узел (первая строка добавлена для тестирования).
msg.payload = [0, 16833];
let pay = msg.payload;
const buf = Buffer.allocUnsafe(4);
buf.writeInt16BE(pay[0],2);
buf.writeInt16BE(pay[1],0);
msg.payload = buf.readFloatBE(0);
return msg;
При тестировании с вашими образцами данных [0,16833] вы получите msg.payload = 24,125.
это работает, он показывает правильное значение (1-проводной датчик температуры 18b20).. Я изменил первую строку с помощью msg.payload = [0, msg.payload [1]]; ..... но если я использую другой регистр, где находится входное значение аналогового напряжения (0-5 В), я не могу получить правильное значение (тип регистра тот же). Я получаю ошибку диапазона....RangeError [ERR_OUT_OF_RANGE]: значение «значение» выходит за пределы допустимого диапазона. Должно быть >= -32768 и <= 32767. Получено 52880 здесь должно быть выведено 40...
Регистры хранения ModBUS могут хранить любые произвольные двоичные данные в нескольких 16-битных регистрах. Если вы хотите разобраться в этих данных, вам нужно знать, как какое правило использовалось для представления этих данных фрагментами по 16 бит. Из ваших результатов видно, что аналоговое напряжение не сохранялось в виде числа с плавающей запятой (с двумя замененными словами). Упомянутому вами датчику даже не нужно использовать все 16 бит, поскольку его точность составляет 12 бит. Возможно, вам потребуется даже выполнить какую-то дополнительную операцию (после чтения регистра), чтобы представить данные осмысленным образом.
Правильное решение — использовать writeUInt16BE, как показано ниже:
msg.payload = [0, 16833];
let pay = msg.payload;
const buf = Buffer.allocUnsafe(4);
buf.writeUInt16BE(pay[0],2);
buf.writeUInt16BE(pay[1],0);
msg.payload = buf.readFloatBE(0);
return msg;enter code here
Посмотрите документ nodejs для чтения из буферов.