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

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

Автор Тема: Обращение к отдельному биту переменной из скрипта  (Прочитано 5914 раз)

Timur007

  • Новичок
  • *
  • Сообщений: 15
    • Просмотр профиля
Здравствуйте. Подскажите пожалуйста как правильно в скрипте обратится к биту переменной по номеру. Дело в том что в переменной типа uint у меня передается массив битов, которые привязаны к кнопкам. При привязке переменной к кнопке имеется поле где можно у казать какой бит переменной использовать, а вот для анимационной картинки (вращающийся вентилятор) такого поля нет, подозреваю что в скрипте как то можно обратится к биту. Для анимации вентилятора использую вот такой скрипт.

Код
begin
  case Image6.ValueAsInt of
    1: Image6.AnimSpeed :=16;
    0: Image6.AnimSpeed :=0;
  end;
end.
« Изменён: 06 Июня 2016, 19:11:50 от Simple-Scada »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3003
    • Просмотр профиля
    • Simple-Scada
Здравствуйте!

Такие функции есть в скриптах. Это функция GetBit (для чтения бита), функция SetBit (для изменения бита) и функция InverseBit (меняет значение бита на противоположное). Подробнее об этих скриптах можно прочесть здесь. Чтобы использовать биты для анимации, нужно писать так:

Код
  { если нулевой бит равен TRUE (1), то запускаем анимацию, иначе останавливаем её }
  if GetBit(Image6.ValueAsInt, 0) then
    Image6.AnimSpeed := 16
  else
    Image6.AnimSpeed :=0;

Если у Вас в проекте несколько изображений должны работать с такими скриптами, то рекомендуем сделать один универсальный скрипт и использовать его везде. Он будет выглядеть так:

Код
  { если этот скрипт вызван объектом Изображение }
  if Sender is TM_Image then
    with Sender as TM_Image do
      { если нулевой бит равен TRUE (1), то запускаем анимацию, иначе останавливаем её }
      if GetBit(ValueAsInt, 0) then
        AnimSpeed := 16
      else
        AnimSpeed :=0;

Timur007

  • Новичок
  • *
  • Сообщений: 15
    • Просмотр профиля
Спасибо большое! Предложенный вами вариант отлично работает. Только один вопрос. Если я делаю универсальный скрипт в котором меняются только порядковые номера битов то в итоге я получаю скрипт с последним значением бита с которым я работал и этот  скрипт применяется ко всем изображениям, хотя компилировал я скрипт при разных значениях битов. Что я делаю не так? Как правильно создать универсальный скрипт ?

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3003
    • Просмотр профиля
    • Simple-Scada
Т.к. Вам необходимо сделать зависимость от разных битов, то придется как-то номера этих битов указывать. И здесь хорошо подойдет свойство Тег, которое есть у всех объектов. Тег - это целочисленное значение, которое пользователь может использовать по своему усмотрению. В Вашем случае можно сделать так...  выставьте каждому изображению значение тега равным биту с которым нужно работать. Например, если Image1 должно реагировать на бит номер 3, то выставьте у Image1 свойство тег равным 3. И так для каждого изображения. Затем просто изменить скрипт вот так:

Код
if Sender is TM_Image then 
    with Sender as TM_Image do
      { если бит (значение зависит от тега) равен TRUE (1), то запускаем анимацию, иначе останавливаем её }
      if GetBit(ValueAsInt, Tag) then
        AnimSpeed := 16
      else
        AnimSpeed :=0;

Цитировать
с которым я работал и этот  скрипт применяется ко всем изображениям, хотя компилировал я скрипт при разных значениях битов.
В этом и есть преимущество универсальных скриптов. Это один скрипт, который подходит для множества объектов и нет смысла компилировать его с разными значениями, т.к. при компиляции он просто пересоздается.
« Изменён: 06 Июня 2016, 23:39:46 от Simple-Scada »

Timur007

  • Новичок
  • *
  • Сообщений: 15
    • Просмотр профиля
Еще раз спасибо! Теперь все работает как надо. А я понять ни как не мог для чего нужно поле ТЕГ и что значит использовать по своему усмотрению))

Andrey1883

  • Пользователь
  • **
  • Сообщений: 73
    • Просмотр профиля
А я то думал, как же к битам обратиться, ведь OPC отдает только SmallInt...
писал для этого в шаблон импорта битовые теги, из-за чего тегов выросла гора...но зато в редакторе тегов все наглядно получилось...
Думал вопрос задать, но меня опередили.....
все из-за невнимательно прочитанной инструкции))
« Изменён: 07 Июня 2016, 11:56:13 от Andrey1883 »

stratixx

  • Новичок
  • *
  • Сообщений: 11
    • Просмотр профиля
ок, а как можно в тренд добавить отдельный бит из переменной? его конечно можно передавать как отдельную переменную, чтоб не было проблем, но всё же интересно можно ли так реализовать?
в создании переменной нельзя распаковать переменную на биты отдельные.. в скриптах на сколько я просмотрел - тоже нельзя тренду назначить  значение бита. это нужно в первую очередь для отображения в общем графике работы булевые значения включения/выключения оборудования и появления событий.

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3003
    • Просмотр профиля
    • Simple-Scada
stratixx, сейчас такой возможности нет и для трендов придется добавлять отдельную (boolean) переменную.

stratixx

  • Новичок
  • *
  • Сообщений: 11
    • Просмотр профиля
stratixx, сейчас такой возможности нет и для трендов придется добавлять отдельную (boolean) переменную.
Ну, по сути работает Getbit , значение которого в скрипте OnDataChange присваивается значению внутренней переменной, которая затем добавляется в Trace. Не удобно, конечно, но работает.
Единственное, что перменная из которой извлекается бит должна быть присвоена к инструменту какомуто. Но даже если в этом нет необходимости и все 32 переменные из double word передавать сугубо для скады - можно думаю создать невидимый инструмент, который по OnDataChange будет скриптом раздавать биты на отдельные внутренние переменные.
Вопрос: скрипт OnInit например, можно ли использовать для этого?
Т.е. будет ли всё время значение всех переменных из GetBIT назначенных внутренним переменным обрабатываться, если один раз назначено при инициализации клиента? или нужно скрипт держать постоянно выполняющимся?

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3003
    • Просмотр профиля
    • Simple-Scada
stratixx, нет, OnInit не подойдет для этого. Сейчас нормальным решением будет только использование отдельных Boolean переменных. Мы постараемся встроить работу с битами в трендах в ближайшее время.