Вход

Просмотр полной версии : МВ210-101 не соответствие float и целочисленных значений



Anton_V_A
18.09.2025, 12:15
Всех приветствую.

Возникла проблема с датчиками Pt100. Подключены 3 шт. к первым 3-м каналам. Я считываю целочисленные данные своей программой по протоколу SNMP. В какой-то момент вместо нормальных температур 20-60°С значения становятся отрицательными. Какие-то каналы могут выдавать реальные показания, другие - отрицательные. Иногда отрицательные становятся реальными. Могут все 3 канала давать сбой. При этом через конфигуратор с удивлением обнаружил, что значения float показывают реальные температуры. Я думал, что целочисленные значения - это округленное до целого значение float * 10^(точек после запятой).

85807

Это глюк модуля? Может прошивка старая и в новой всё исправлено?

85808

При считывании значений float не могу расшифровать данные. Может у кого-нибудь есть пример в Delphi преобразования/извлечения данных? Был бы благодарен за урок.

С уважением, Антон.

melky
18.09.2025, 12:21
а вы значения с отрицательно на биты раскидывали? нет там случайно по документации передачи ошибок старшими битами?

Anton_V_A
18.09.2025, 12:24
а вы значения с отрицательно на биты раскидывали? нет там случайно по документации передачи ошибок старшими битами?

Нет. В обычном рабочем состоянии читаю целочисленные значения, делю их на заданное число разрядов после запятой и получаю точное реальное значение температуры.

Sergey361
18.09.2025, 12:47
Так а какое значение у параметра "точек после запятой". Судя по всему 3, тогда значения INT выходят за диапазон

petera
18.09.2025, 13:00
Так а какое значение у параметра "точек после запятой". Судя по всему 3, тогда значения INT выходят за диапазон

+100500 !!!
максимальное значение 32,767, выше будет показывать как сейчас

Anton_V_A
18.09.2025, 13:13
Так а какое значение у параметра "точек после запятой". Судя по всему 3, тогда значения INT выходят за диапазон

Т.е. мне достаточно снизить точность, убавив количество разрядов после запятой с 3 на 2 и всё заработает?

kondor3000
18.09.2025, 13:15
Т.е. мне достаточно снизить точность, убавив количество разрядов после запятой с 3 на 2 и всё заработает?

Да, даже 1 достаточно, так как вторая и третья после запятой, обычно прыгают.

Александр Пинэко-Скворцов
18.09.2025, 13:23
Всех приветствую.

Возникла проблема с датчиками Pt100. Подключены 3 шт. к первым 3-м каналам. Я считываю целочисленные данные своей программой по протоколу SNMP. В какой-то момент вместо нормальных температур 20-60°С значения становятся отрицательными. Какие-то каналы могут выдавать реальные показания, другие - отрицательные. Иногда отрицательные становятся реальными. Могут все 3 канала давать сбой. При этом через конфигуратор с удивлением обнаружил, что значения float показывают реальные температуры. Я думал, что целочисленные значения - это округленное до целого значение float * 10^(точек после запятой).

85807

Это глюк модуля? Может прошивка старая и в новой всё исправлено?

85808

При считывании значений float не могу расшифровать данные. Может у кого-нибудь есть пример в Delphi преобразования/извлечения данных? Был бы благодарен за урок.

С уважением, Антон.



Добрый день.

Действительно, значение типа INT получается из значения типа FLOAT домножением на 10^(положение точки).
Соответственно, если результат этой операции выходит за диапазон INT (-32768..+32767), произойдёт переполнение. Поэтому Вы наблюдаете отрицательные значения.

В этом случае 2 варианта:
1. Использовать в своём коде только FLOAT;
2. Уменьшить значение параметра Положение точки для соответствующего канала;


Для Delphi примера кода нет. Возможно, Вам пригодится конвертер: https://www.h-schmidt.net/FloatConverter/IEEE754.html

melky
18.09.2025, 14:45
ну у Дельфи наверняка как у других float идет от младшего байта к старшему вероятно. И если надо переставить байты, регистры местами то что-то вроде Array.Copy или может просто реверс и уже потом подсовывать.

Валенок
18.09.2025, 16:34
Т.е. мне достаточно снизить точность, убавив количество разрядов после запятой с 3 на 2 и всё заработает?
Накой? Читайте float в single и всё будет норм. Слова переставить см. ниже
А для отображалок есть format('%0.2f',[..])


..При считывании значений float не могу расшифровать данные. Может у кого-нибудь есть пример в Delphi преобразования/извлечения данных?

function Swap(x: Single): Single;
asm
mov eax,x
rol eax,16
mov Result,eax
end;

FPavel
18.09.2025, 18:48
У Delphi, как и у TurboPascal и, наверное, у Pascal из стандарта, есть тип данных - запись (record) с вариантами - который позволяет на одном участке памяти объявить несколько переменных.
Т.е. можно объявить single и dword и два word и четыре byte на одном участке памяти. Записать в переменную single и переставить байты или слова.

TDWordConvert = packed record
case word of
0: (dw: dword);
1: (w0, w1: word);
2: (b0, b1, b2, b3: byte);
3: (f32: single);
end;

Перестановка байт 1234 -> 4321 штатными средствами

t.dw := ModbusReadRegisters();
t.dw := Swap(t.dw);
t.w0 := Swap(t.w0);
t.w1 := Swap(t.w1);
write(t.f32);

Или можно через промежуточную переменную.

Сколько помню, для некоторых компиляторов режима x64 закрыли ассемблерные вставки. Поэтому удобно таким подходом воспользоваться.

Валенок
18.09.2025, 19:22
Перестановка байт 1234 -> 4321 штатными средствами

1234 -> 3412 для Овена. Байты свапит модбас-клиент //если это модбас-клиент, а не не пойми что




Сколько помню, для некоторых компиляторов режима x64 закрыли ассемблерные вставки..
Да что же в этом мире происходит то?))



.... есть тип данных - запись (record) с вариантами .....Или можно через промежуточную переменную.
Без всего


function Swap(x: Single): Single;
begin
PDWord(@Result)^ := PDWord(@x)^ shr 16 + PDWord(@x)^ shl 16;
end;