PDA

Просмотр полной версии : 4 байта в число с плавающей запятой



Пьер
25.08.2017, 16:38
Codesys 3.5
Подключил счетчик энергии, в нем полная активная энергия представлена в Int64 - 4 байта информации (т.е. 4 WORD числа, если смотреть в регистрах), как преобразовать в REAL (число с плавающей запятой)?

lara197a
25.08.2017, 16:59
Вы запросите у них точный формат.
Обычно так:
A5: DWORD;
A5: REAL;
pt: POINTER TO REAL;

pt :=ADR(A5); (*Копируем в префикс*)
A6:=pt^; (*Превращение в реал(флоат)*)

Пьер
25.08.2017, 17:01
Вы запросите у них точный формат.
Обычно так:
A5: DWORD;
A5: REAL;
pt: POINTER TO REAL;

pt :=ADR(A5); (*Копируем в префикс*)
A6:=pt^; (*Превращение в реал(флоат)*)

64 разрядное целое число и вот его в реал

lara197a
25.08.2017, 17:05
а что конкретно смущает?
у меня так с расходомера уже 7 лет пересчитывает из 2х ворд, в одном из которых мантиса, в другом экспонента.
сложение в дворд я опустил, а результат такой.

Пьер
25.08.2017, 17:10
а что конкретно смущает?
у меня так с расходомера уже 7 лет пересчитывает из 2х ворд, в одном из которых мантиса, в другом экспонента.
сложение в дворд я опустил, а результат такой.

а как конкретно это в коде будет выглядеть?

Пьер
25.08.2017, 17:11
я с адресациями не очень

Пьер
25.08.2017, 17:14
FUNCTION two_word_TO_real : REAL
VAR_INPUT
IN_Data: POINTER TO ARRAY[0..1] OF DWORD; (*Указатель на массив регистров для Float*)
END_VAR
VAR
p1: POINTER TO BYTE;
p2: POINTER TO BYTE;
END_VAR
------------------------------------------------------------
p1:=ADR(two_word_to_real);
p2:=ADR(IN_Data^[1]);

p1^:=p2^;
p1:=p1+1;
p2:=p2+1;
p1^:=p2^;
p1:=p1+1;
p2:=ADR(IN_Data^[0]);
p1^:=p2^;
p1:=p1+1;
p2:=p2+1;
p1^:=p2^;
---------------------------
этот код, работает для 2х байтов, но как преобразовать в 4 не пойму.:confused:

lara197a
25.08.2017, 17:31
не нужно так усложнять.
в прг. складываю регистры, вам это не нужно.
что нужно я написал в первом сообщении.
программа такая.

ferret_maybe
25.08.2017, 21:20
Что-то не совсем в сообщении задание понимаю.
Int64 это же 8 байт, 4 слова, два двойных слова. А предлагают обычное преобразование в 4 -х байт в Real?
Нужно 8 байт в Real?

ferret_maybe
26.08.2017, 08:02
Может быть такой вариант только он не для Codesys делался. Функция WORD_TO_REAL не знаю есть ли в Codesys. Codesys оперирует указателями, у меня не было возможности их использовать поэтому решение получилось такое:
FUNCTION FourWords2Real
VAR_INPUT
WORD1: WORD;
WORD2: WORD;
WORD3: WORD;
WORD4: WORD;
END_VAR

VAR
Temp1: REAL;
Temp2: REAL;
Temp3: REAL;
Temp4: REAL;
END_VAR
Temp1:=WORD_TO_REAL(WORD1);
Temp2:=WORD_TO_REAL(WORD2);
Temp3:=WORD_TO_REAL(WORD3);
Temp4:=WORD_TO_REAL(WORD4);
Temp2:=Temp2*(2.0**16); (*сдвиг на 16 бит влево умножая на 2 в степени 16*)
Temp3:=Temp3*(2.0**32);
Temp4:=Temp4*(2.0**48);
Temp4:=TEMP1 + TEMP2 + TEMP3 + TEMP4; (*сложение разрядов в общее значение*)
FourWords2Real:= Temp4;
END_FUNCTION

lara197a
26.08.2017, 09:55
тема называлась так:
4 байта в число с плавающей запятой
4 байта это DWORD или 32 бита.

ferret_maybe
26.08.2017, 12:27
тема называлась так:
4 байта в число с плавающей запятой
4 байта это DWORD или 32 бита.
Так я понимаю, что Int64 - это 64 бита, 8 байт, 4 слова (Word), 2 двойных слова (DWORD). А не как писал автор темы Int64 - 4 байта, 4 слова. Но я вас понял)...Не совсем понимаю, что ему нужно.

Пьер
28.08.2017, 08:54
Что-то не совсем в сообщении задание понимаю.
Int64 это же 8 байт, 4 слова, два двойных слова. А предлагают обычное преобразование в 4 -х байт в Real?
Нужно 8 байт в Real?
Совершенно верно, я не описал задачу толково.
Попробую.
Вопрос, почему у КДС нет стандартной функции такой?

Пьер
28.08.2017, 09:07
По байтно смотрю значения:
А0 = 0 (WORD)
А1 = 66 (WORD)
А2 = 6293 (WORD)
А3 = 0 (WORD)
так идут значения.
В итоге преобразования получается фигня по lara197a рекомендации.
Я, не знаю, но что-то я делаю точно не так. Помню в институте, на delphi мы как-то переводили, но сейчас что-то не доходит до меня.

Пьер
28.08.2017, 09:54
https://en.wikipedia.org/wiki/Double-precision_floating-point_format когда то я отсюда брал инфу как с LReal работать

ага, но у меня с указателями не получается сработаться. А там без указателей как я понимаю никуда.

lara197a
28.08.2017, 12:38
у меня пример для 32 бита, исходя из названия темы.
В примере, в ручную собирается двойное слово из знака, мантисы и экспоненты.
Я вам писал, уточните у производителя, как у них размещены эти элементы и
по аналогии соберите.

Пьер
28.08.2017, 12:52
у меня пример для 32 бита, исходя из названия темы.
В примере, в ручную собирается двойное слово из знака, мантисы и экспоненты.
Я вам писал, уточните у производителя, как у них размещены эти элементы и
по аналогии соберите.

В том то и дело у производителя уточняю, он мне все как в руководстве.... По руководству поставил регистры, считываю получается х...

Пьер
28.08.2017, 12:59
Считывать регистры с 3204 размер 4 слова.
А0 = 0 (WORD)
А1 = 66 (WORD)
А2 = 6293 (WORD)
А3 = 0 (WORD)

по середине значения,
порядок нулевой, мантисса большая.
А1 увеличивается на 1, когда А2 достигает 65535.

lara197a
28.08.2017, 14:59
там где-то знак должен быть.
А если только А1 и А2 взять?

Пьер
28.08.2017, 15:06
там где-то знак должен быть.
А если только А1 и А2 взять?

Там счетчик, там нужно считывать активную энергию, сколько кВт/ч накрутило, в принципе это самое главное значение, которое не считывается толком.
Это значение 4 СЛОВА, ток и активная мощность 2 СЛОВА, их получилось преобразовать по вышеуказанному коду. Но вот это никак не получается. Если брать только два средних слова, то тоже получается какая то билеберда, пробовал и так и сяк.
Знак, по идее всегда +.

Пьер
28.08.2017, 15:09
32865
Вот слова, их видно побитно все, так что знаков нет не снизу не сверху )))

lara197a
28.08.2017, 15:14
Знак- лишняя единица.
ее нужно отделять.
может байты местами менять нужно.
у меня примерно такая же ситуация была с расходомером К300.
Методом кручения байт и с помощью описания типа данных в википедии.

Пьер
28.08.2017, 15:25
Знак- лишняя единица.
ее нужно отделять.
может байты местами менять нужно.
у меня примерно такая же ситуация была с расходомером К300.
Методом кручения байт и с помощью описания типа данных в википедии.

Я вас понял о чем вы говорите, сейчас Валенка попробуем код.

Пьер
28.08.2017, 15:45
Про порядок - не забываем.
Предположительно. DH := A4 * 65536 + A3; DL := A2 * 65536 + A1;
Если никакие перестановки не прокатят - плюньте в того, кто сказал что там int64

Если б авторы (девайса) привели пример содержимое слов & значение - было бы проще.
Получается в скором времени А1 и А4 появятся значения?

Пьер
28.08.2017, 16:03
Так они и сейчас там есть. Они всегда там есть )) Видите суслика ?

какого суслика)?
Получается шнайдер сантехникс (счетчик)

Пьер
28.08.2017, 16:26
Который там.

PS
Какая размерность у тех 4-х регистров ?

Все 4е - WORD( по 16 бит каждое)

Пьер
28.08.2017, 16:30
http://www.owen.ru/forum/showthread.php?t=10285&p=58530&viewfull=1#post58530 согласно ссылкам в этом посте, это точно не формат IEEE754

Честно, я что-то уже запутался!

Пьер
28.08.2017, 16:32
)) ватты, попугаи, поллитры .... ?

ааа, Вт*ч, получается. но крутит достаточно быстро. Где-то по 1000 кВт в сутки

Пьер
28.08.2017, 16:50
)) ватты, попугаи, поллитры .... ?

M := DH.31;
if M then
DH := (not DH) + sel(DL = 0,0,1);
DL := (not DL) + 1;
end_if

DH := A4 * 65536 + A3; DL := A2 * 65536 + A1;
int64_to_real := (DH * 65536.0 + DL) * sel(M,1,-1);

Получается вот так добавляю и все?

Пьер
29.08.2017, 09:46
Если там int64 - да. Только DH/DL образуйте - вначале.
И можно еще на 1000 разделить. Так ведь привычней будет ?

PS
Что разобраццо с порядком - можно на определенное время включить определенную нагрузку. И просмотреть рез-ты до и после.

Вот так вот изменил и вроде заработало. Но не знаю что будет показывать, когда появятся значения в А1 и А4.

FUNCTION int64_to_real : REAL
VAR_INPUT
A1,A2:WORD;
A3,A4:WORD;
END_VAR
VAR
DL,DH : DWORD;
M : BOOL;
END_VAR

----------------------------

M := DH.31;
DH := A4 * 65536 + A3; DL := A1 * 65536 +A2;

IF M THEN
DH := (NOT DH) + SEL(DL = 0,0,1);
DL := (NOT DL) + 1;
END_IF

int64_to_real:= (DH * 65536.0 + DL) * SEL(M,1,-1);
int64_to_real:=int64_to_real /1000;



Т.к. У меня последовательность (адресация в программе):
А1(3204)=0;
А2(3205)=88;
А3(3206)=17500;
А4(3207)=0;
Так видны значения в CoDeSys. Как там дальше будет, посмотрим.
Валенок, благодарю очень сильно за полезную помощь.
И всем остальным ребятам огромное спасибо.

amd111
08.09.2017, 02:21
Здравствуйте, сам сейчас столкнулся с проблемой чтения мощности из PM3250. Дело в том, что у них сдвинута нумерация регистров на 2. Т.е. ожидаемые данные регистра 3204 будут находится в регистре 3206. И так практически во всей таблице, кроме начальных. Причем несовпадение может быть как в одну, так и в другую сторону. Я, обычно, для наглядности, в конфигурации ПЛК читаю 3 регистра: один, который указан в таблице, и смежные, потом выбираю нужный. Подскажите пожалуйста как мне преобразовать Int64 в REAL. Программа написана на CFC. Спасибо

amd111
08.09.2017, 13:17
Вопрос решился проще, в техподдержка Scheider дали ответ : "В PM3250 имеется регистры энергии представлены как в формате int64, так и в Float32 (начиная с рег 45166)." стр. 60 руководства пользователя.

Пьер
18.03.2019, 11:26
Здравствуйте. Как 32bit input module переделать в число с плавающей запятой, т.е. в REAL? Выше перечисленными методами не получается.

Пьер
18.03.2019, 11:32
Здравствуйте. Как 32bit input module переделать в число с плавающей запятой, т.е. в REAL? Выше перечисленными методами не получается.

Евгений Кислов
18.03.2019, 11:32
Здравствуйте. Как 32bit input module переделать в число с плавающей запятой, т.е. в REAL? Выше перечисленными методами не получается.

Речь о ПЛК1хх? (судя по 32bit input module)
Можно его просто на Real input module заменить.

Пьер
18.03.2019, 11:38
Речь о ПЛК1хх? (судя по 32bit input module)
Можно его просто на Real input module заменить.
ПЛК 1хх - верно.
На Real input module менял, но что то не то выходит, что на дисплее прибора.

Пьер
18.03.2019, 11:39
как DWORD разбить на два WORD?

Евгений Кислов
18.03.2019, 11:41
В настройках Universal Modbus Device измените параметр Byte Sequence.
Нюанс - повлияет на все слэйвы в данном мастере.

ferret_maybe
18.03.2019, 11:44
Через точку должно работать dword.word0 и dword.word1 что-то в этом плане.

Пьер
18.03.2019, 11:45
В настройках Universal Modbus Device измените параметр Byte Sequence.
Нюанс - повлияет на все слэйвы в данном мастере.

ёклмнопрст. Я этого не знал. Спасибо, Евгений!

Пьер
18.03.2019, 12:01
Через точку должно работать dword.word0 и dword.word1 что-то в этом плане.

Что то не выходит.

ferret_maybe
18.03.2019, 19:37
Что то не выходит.

Опс, сорри. Думал, что у Codesys 2.3 есть такая функция.

VAR
IN_DWORD : DWORD;
LOW_WORD: WORD;
HI_WORD: WORD;
END_VAR

LOW_WORD := DWORD_TO_WORD(IN_DWORD);
HI_WORD := DWORD_TO_WORD(SHR(IN_DWORD, 16));