Simple-Scada forum

Simple-Scada 2 => Ваши вопросы => Тема начата: Izergill от 14 Ноября 2016, 15:37:18

Название: Как "располовинить" DWORD?
Отправлено: Izergill от 14 Ноября 2016, 15:37:18
Добрый день!
Из контроллера приходят данные: два слова, упакованные в одну переменную типа DWORD. Как можно извлечь эти две переменные?
Название: Re: Как "располовинить" DWORD
Отправлено: Simple-Scada от 14 Ноября 2016, 16:11:27
Здравствуйте.

Это можно сделать следующим скриптом:
Код
var
  aHiWord, aLowWord: Word;
begin
  aHiWord := Word(varDWord.AsInt shr 16);
  aLowWord := Word(varDWord.AsInt);
end.

, где varDWord - переменная с контроллера, типа DWord, которую нужно разложить на слова. aHiWord - старшее слово. aLowWord - младшее слово. При этом не забывайте, что для корректной работы у DWord переменной должна быть выбрана шкала в Simple-Scada с диапазоном 0..4294967295. Типу данных DWord в Simple-Scada 2 соответствует тип LongWord.
Название: Re: Как "располовинить" DWORD
Отправлено: Izergill от 14 Ноября 2016, 16:23:06
А возможно ли обратное преобразование: две переменные типа Word в одну типа LongWord?
Название: Re: Как "располовинить" DWORD
Отправлено: Simple-Scada от 14 Ноября 2016, 16:31:06
Конечно, обратным способом:
Код
var
  aHiWord, aLowWord: Word;
begin
  aHiWord := 1883;  // для примера
  aLowWord := 52501;  // для примера
  varDWord.Value := LongWord(aHiWord shl 16) or aLowWord;
end.
Название: Re: Как "располовинить" DWORD
Отправлено: Izergill от 14 Ноября 2016, 16:41:01
Насколько я понимаю переменные aHiWord и aLowWord являются локальными для процедуры. А возможно ли "разобрать" переменную, которую мы берем из OPC и "половинки" присвоить внутренним переменным? И по какому событию это можно сделать?
Название: Re: Как "располовинить" DWORD
Отправлено: Simple-Scada от 14 Ноября 2016, 16:54:37
Переменные с OPC-сервера мало чем отличаются от локальных переменных, поэтому здесь принцип такой же.

Из переменной OPC-сервера varDWord (тип LongWord) в две внутренние переменные varHiWord и varLowWord (типа Word):
Код
begin
  varHiWord.Value := Word(varDWord.AsInt shr 16);
  varLowWord.Value := Word(varDWord.AsInt);
end.

Цитировать
И по какому событию это можно сделать?
Лучше всего по изменению переменной varDWord, т.е. по событию OnDataChange. Сейчас для этого придется создать объект (например Поле), связать его с переменной varDWord, перейти к OnDataChange-скрипту этого объекта и вставить в него код, которые представлен выше. В будущем можно будет создавать OnDataChange скрипты без создания объекта.
Название: Re: Как "располовинить" DWORD
Отправлено: Teodor от 11 Января 2017, 19:41:38
Конечно, обратным способом:
Код
var
  aHiWord, aLowWord: Word;
begin
  aHiWord := 1883;  // для примера
  aLowWord := 52501;  // для примера
  varDWord.Value := LongWord(aHiWord shl 16) or aLowWord;
end.
У меня сегодня подобная конструкция не срабтала ввиду провтыка LongWord()... пришлось срагулить:
Код
var
  aHiWord, aLowWord: Word;
begin
  aHiWord := 1883;  // для примера
  aLowWord := 52501;  // для примера
  varDWord.Value := aHiWord*65536 + aLowWord;
end.