Просмотр полной версии : МВ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 преобразования/извлечения данных? Был бы благодарен за урок.
С уважением, Антон.
а вы значения с отрицательно на биты раскидывали? нет там случайно по документации передачи ошибок старшими битами?
Anton_V_A
18.09.2025, 12:24
а вы значения с отрицательно на биты раскидывали? нет там случайно по документации передачи ошибок старшими битами?
Нет. В обычном рабочем состоянии читаю целочисленные значения, делю их на заданное число разрядов после запятой и получаю точное реальное значение температуры.
Sergey361
18.09.2025, 12:47
Так а какое значение у параметра "точек после запятой". Судя по всему 3, тогда значения INT выходят за диапазон
Так а какое значение у параметра "точек после запятой". Судя по всему 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
ну у Дельфи наверняка как у других float идет от младшего байта к старшему вероятно. И если надо переставить байты, регистры местами то что-то вроде Array.Copy или может просто реверс и уже потом подсовывать.
Т.е. мне достаточно снизить точность, убавив количество разрядов после запятой с 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;
У 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 закрыли ассемблерные вставки. Поэтому удобно таким подходом воспользоваться.
Перестановка байт 1234 -> 4321 штатными средствами
1234 -> 3412 для Овена. Байты свапит модбас-клиент //если это модбас-клиент, а не не пойми что
Сколько помню, для некоторых компиляторов режима x64 закрыли ассемблерные вставки..
Да что же в этом мире происходит то?))
.... есть тип данных - запись (record) с вариантами .....Или можно через промежуточную переменную.
Без всего
function Swap(x: Single): Single;
begin
PDWord(@Result)^ := PDWord(@x)^ shr 16 + PDWord(@x)^ shl 16;
end;
Powered by vBulletin® Version 4.2.3 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot