Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Не получили письмо с кодом активации?

Официальный форум Simple-Scada.

Автор Тема: Как "располовинить" DWORD?  (Прочитано 5365 раз)

Izergill

  • Новичок
  • *
  • Сообщений: 25
    • Просмотр профиля
Как "располовинить" DWORD?
« : 14 Ноября 2016, 15:37:18 »
Добрый день!
Из контроллера приходят данные: два слова, упакованные в одну переменную типа DWORD. Как можно извлечь эти две переменные?
« Изменён: 18 Ноября 2016, 11:27:06 от Simple-Scada »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3146
    • Просмотр профиля
    • Simple-Scada
Re: Как "располовинить" DWORD
« Ответ #1 : 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.
« Изменён: 14 Ноября 2016, 16:16:47 от Simple-Scada »

Izergill

  • Новичок
  • *
  • Сообщений: 25
    • Просмотр профиля
Re: Как "располовинить" DWORD
« Ответ #2 : 14 Ноября 2016, 16:23:06 »
А возможно ли обратное преобразование: две переменные типа Word в одну типа LongWord?

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3146
    • Просмотр профиля
    • Simple-Scada
Re: Как "располовинить" DWORD
« Ответ #3 : 14 Ноября 2016, 16:31:06 »
Конечно, обратным способом:
Код
var
  aHiWord, aLowWord: Word;
begin
  aHiWord := 1883;  // для примера
  aLowWord := 52501;  // для примера
  varDWord.Value := LongWord(aHiWord shl 16) or aLowWord;
end.

Izergill

  • Новичок
  • *
  • Сообщений: 25
    • Просмотр профиля
Re: Как "располовинить" DWORD
« Ответ #4 : 14 Ноября 2016, 16:41:01 »
Насколько я понимаю переменные aHiWord и aLowWord являются локальными для процедуры. А возможно ли "разобрать" переменную, которую мы берем из OPC и "половинки" присвоить внутренним переменным? И по какому событию это можно сделать?

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3146
    • Просмотр профиля
    • Simple-Scada
Re: Как "располовинить" DWORD
« Ответ #5 : 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 скрипты без создания объекта.

Teodor

  • Старожил
  • ****
  • Сообщений: 256
    • Просмотр профиля
Re: Как "располовинить" DWORD
« Ответ #6 : 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.