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

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

Автор Тема: Работа кнопки без фиксации  (Прочитано 8129 раз)

asnik

  • Новичок
  • *
  • Сообщений: 12
    • Просмотр профиля
Re: Работа кнопки без фиксации
« Ответ #15 : 28 Ноября 2017, 13:51:07 »
1. Можно ли так (речь о кнопке без фиксации):
- первое нажатие - включить, запись в одну переменную (в ОРС и соответственно в контроллер), надпись меняется с "включить" на "выключить"
- второе нажатие - выключить, запись в другую переменную, надпись меняется с "выключить" на "включить"
 На данный момент реализовано с помощью 2-х кнопок, которые меняют видимость и находятся на одном месте на схеме (что не есть хорошо для прозрачности схемы)
2. Как я понял если у кнопки с фиксацией оставить 1 состояние (запись единицы), то это равнозначно кнопке без фиксации, т.е. запись единицы будет происходить однократно?

Simple_Scada

  • Администратор
  • *****
  • Сообщений: 1178
    • Просмотр профиля
Re: Работа кнопки без фиксации
« Ответ #16 : 29 Ноября 2017, 10:38:53 »
Здравствуйте!

Цитировать
Можно ли так (речь о кнопке без фиксации):
- первое нажатие - включить, запись в одну переменную (в ОРС и соответственно в контроллер), надпись меняется с "включить" на "выключить"
- второе нажатие - выключить, запись в другую переменную, надпись меняется с "выключить" на "включить"
Вы можете менять значение нужной переменной по событию OnClick кнопки используя свойство Value:
Код
begin
  { записываем значение 10 в переменную MyVar }
  MyVar.Value := 10;
end.

Менять надписи, цвет и другие свойства нужно у состояния кнопки, например:
Код
begin
  Button1.States[0].Caption := 'Включить';  // изменить название кнопки в состоянии 0
  Button1.States[0].Color := clGreen;       // изменить цвет кнопки в состоянии 0
  Button1.States[0].BorderColor := clBlack; // изменить цвет рамки кнопки в состоянии 0
end.

При таком подходе вряд ли получится сделать проще чем сделано у Вас сейчас. Гораздо проще и правильнее было бы внести изменения в программу контроллера для реализации управления с одной кнопки или просто использовать две кнопки не скрывая их друг за другом.

Цитировать
Как я понял если у кнопки с фиксацией оставить 1 состояние (запись единицы), то это равнозначно кнопке без фиксации, т.е. запись единицы будет происходить однократно?
Нет, не равнозначно. При нажатии на кнопку без фиксации в переменную записывается 1, а при отпускании записывается 0. При нажатии кнопки с фиксацией и одним состоянием в переменную всегда записывается 1.


asnik

  • Новичок
  • *
  • Сообщений: 12
    • Просмотр профиля
Re: Работа кнопки без фиксации
« Ответ #17 : 29 Ноября 2017, 11:31:57 »
Уточню главный вопрос. "Включить" и "выключить" - это две разные переменные в контроллере, а реализовать хочу одной кнопкой, т.е. один раз нажал - записал 1-цу в одну переменную "вкл", второй раз нажал - записал 1-цу в другую переменную "выкл". И так по кругу. Видимо в скрипте надо различать первое и второе нажатие

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3000
    • Просмотр профиля
    • Simple-Scada
Re: Работа кнопки без фиксации
« Ответ #18 : 29 Ноября 2017, 11:46:41 »
asnik, конечно, Вы можете работать в скрипте с любым количеством переменных как угодно. Можете например менять у кнопки значение "Тег" при каждом нажатии и в зависимости от значения тега работать с разными переменными, например:
Код
begin
  { если тег кнопки равен 0, то работаем с первой переменной }
  if Button1.Tag = 0 then
  begin
    MyVariable1.Value := 1;
    Button1.Tag := 1;  // отмечаем, что следующий клик должен работать со второй переменной
  end else
    { если тег кнопки не равен 0, то работаем со второй переменной }
    begin
      MyVariable2.Value := 1;
      Button1.Tag := 0;  // отмечаем, что следующий клик должен работать с первой переменной
    end;
end.

Учитывайте, что кнопка не должна быть связана с переменной, иначе по-клику скада будет автоматически менять эту переменную. Также нужно учитывать, что предложенный выше вариант работы с двумя переменными никак не связан с состояниями кнопки, т.е. состояние кнопки будет всегда одним и тем же, просто каждый четный клик будет выполнять присвоение в первую переменную, а каждый нечётный во вторую. Также после перезапуска проекта на сервере тег у кнопки будет равен 0 (т.к. он не зависит от значений переменных) и первый клик всегда будет работать с первой переменной (что может привести к проблемам).
« Изменён: 29 Ноября 2017, 11:50:00 от Simple-Scada »

asnik

  • Новичок
  • *
  • Сообщений: 12
    • Просмотр профиля
Re: Работа кнопки без фиксации
« Ответ #19 : 29 Ноября 2017, 14:01:23 »
Спасибо, примерно так я  себе это и представлял. Опять же, если я буду иметь информацию с контроллера, что в данный момент механизм "Выкл" , то соответственно кнопка должна быть с надписью "Вкл" и при нажатии писать 1-цу в соответствующую переменную контроллера

Denissimo

  • Новичок
  • *
  • Сообщений: 2
    • Просмотр профиля
Re: Работа кнопки без фиксации
« Ответ #20 : 14 Июня 2019, 05:08:31 »
Спасибо, примерно так я  себе это и представлял. Опять же, если я буду иметь информацию с контроллера, что в данный момент механизм "Выкл" , то соответственно кнопка должна быть с надписью "Вкл" и при нажатии писать 1-цу в соответствующую переменную контроллера
Извините, я не понял.

Приведу пример своей проблемы. Дано:
Simple-SCADA Демо-версия с ограничением по времени работы. Я автоматчик, но о языках программирования только слышу от программистов, которым ставлю задачу. Никто из них не знает Simple-SCADA. Вижу перспективу в этом продукте у нас в плане построения диспетчеризации на руднике - Решил сам учиться. Извините за длиннотекст, больше так не буду)).
Создал пробный проект типа для "Брэйн-Ринга" через веб-интерфейс между нашими сотрудниками)). В нём задействован скриптовый таймер на событии "Прошла секунда":
Код: (delphi)
begin
  // Если таймер разрешён и не дошёл до граничной уставки,
  //то таймер считает дальше
  if TimerRun.Value and (Time.Value < TimerSetPoint.Value) then
    begin
      Time.Value := Time.Value + 1;
    end;

  // Если Таймер дошёл до предупредительной уставки,
  // то просигнализировать о достижении предупредительной уставки
  if Time.Value >= TimerPreAlarmSetPoint.Value then
    begin
      TimerAlarm_1.Value := True;
    end;

  // Если Таймер дошёл до граничной уставки,
  // то запретить таймер и просигнализировать о достижении граничной уставки
  if Time.Value >= TimerSetPoint.Value then
    begin
      TimerRun.Value := False;
      TimerAlarm_2.Value := True;
    end;
end.
Нужны были кнопки без фиксации с надписью "ПУСК", "СТОП", "СБРОС". После нажатия и отпускания кнопок я должен получить в переменную логическую единицу ("1"), а нажатая кнопка должна вернуться в исходное ненажатое состояние.

Как делал:
Добавил на экран кнопку;
Выбрал Тип "Без фиксации";
Оставил Состояние по умолчанию "Отпущена" (Номер 0, Значение 1, Текст "Включить");
Создал переменную btnStart_1 типа "Boolean" и прицепил к кнопке, потому что без прицепленной к кнопке переменной ничего не выходит - проверял выводом значений переменных кнопок в виде состояний элементов CheckBox на мнемосхеме;
Создал вторую такую переменную  btnStart_2 что бы запоминать факт того что кнопка была нажата, даже если уже отпустили - прицепил к кнопке скрипт по событию OnClick (Аналогичные скрипты на кнопку СТОП и СБРОС):
Код: (delphi)
begin
  // Если нажат ПУСК, то запомнить это и обнулить СТОП, СБРОС
  if btnStart_1.Value then
    begin
      btnStart_2.Value := True;
      btnStop_2.Value := False;
      btnReset_2.Value := False;

      // Алгоритмическая часть
      FirstTeamFlag.Value := False;
      FirstTeamNumber.Value := 0;
      TimerRun.Value := True;
    end;
end.
Проблема:
После нажатия и отпускания кнопок, индикация кнопки остаётся в нажатом состоянии, о чём свидетельствует текст на кнопке "Выключить".

Вопрос:
Что я делаю не так? Я же вроде не влияю на переменную, прикреплённую к кнопке, и Тип кнопки "Без фиксации".

Такая же проблема возникает у кнопок команд столов:
Код: (delphi)
begin
  if FirstTeamFlag.Value = False then
    begin
  // Обработка кнопки 1
  if btnTeam1_1.Value and (btnTeam1_2.Value = False) then
    begin
      btnTeam1_2.Value := True;
      FirstTeamFlag.Value := True;
      FirstTeamNumber.Value := 1;
      TimerRun.Value := False;
    end;

  // Обработка кнопки 2
  if btnTeam2_1.Value and (btnTeam2_2.Value = False) then
    begin
      btnTeam2_2.Value := True;

      // Алгоритмическая часть
      FirstTeamFlag.Value := True;
      FirstTeamNumber.Value := 2;
      TimerRun.Value := False;
    end;

  // Обработка кнопки 3
  if btnTeam3_1.Value and (btnTeam3_2.Value = False) then
    begin
      btnTeam3_2.Value := True;

      // Алгоритмическая часть
      FirstTeamFlag.Value := True;
      FirstTeamNumber.Value := 3;
      TimerRun.Value := False;
    end;

  // Обработка кнопки 4
  if btnTeam4_1.Value and (btnTeam4_2.Value = False) then
    begin
      btnTeam4_2.Value := True;

      // Алгоритмическая часть
      FirstTeamFlag.Value := True;
      FirstTeamNumber.Value := 4;
      TimerRun.Value := False;
    end;

  // Обработка кнопки 5
  if btnTeam5_1.Value and (btnTeam5_2.Value = False) then
    begin
      btnTeam5_2.Value := True;

      // Алгоритмическая часть
      FirstTeamFlag.Value := True;
      FirstTeamNumber.Value := 5;
      TimerRun.Value := False;
    end;

  end;
end.
« Изменён: 15 Июня 2019, 22:45:58 от Simple-Scada »

Denissimo

  • Новичок
  • *
  • Сообщений: 2
    • Просмотр профиля
Re: Работа кнопки без фиксации
« Ответ #21 : 14 Июня 2019, 05:22:28 »
Прошу игнорировать файловое вложение в предыдущем посте.
В этом посте актуальная версия с вышеописанной проблемой.

Neskad

  • Новичок
  • *
  • Сообщений: 31
    • Просмотр профиля
Re: Работа кнопки без фиксации
« Ответ #22 : 17 Июня 2019, 09:17:07 »
Цитировать
Проблема:
После нажатия и отпускания кнопок, индикация кнопки остаётся в нажатом состоянии, о чём свидетельствует текст на кнопке "Выключить".
Кажется я понял в чем ваша проблема, сам недавно сталкивался с подобным.
Для глобальных переменных TM_Variable с типом boolean (которые вы создаете в меню "переменные") такой код не работает:
Код: (delphi)
if Variable.Value = True then myVar := True;
Хотя никакой ошибки при компиляции нет.

Для использования с условным оператором нужно глобальную переменную приводить к логическому типу:
Код: (delphi)
if Variable.asBool = True then myVar := True;
Выглядит немного странно, что к Boolean надо применять метод AsBool. Скорее всего, это особенность типа TM_Variable у SimpleScada.
« Изменён: 17 Июня 2019, 09:21:51 от Neskad »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3000
    • Просмотр профиля
    • Simple-Scada
Re: Работа кнопки без фиксации
« Ответ #23 : 17 Июня 2019, 10:48:05 »
Выглядит немного странно, что к Boolean надо применять метод AsBool. Скорее всего, это особенность типа TM_Variable у SimpleScada.
Neskad, у типа TM_Variable нет никаких особенностей, как и у всех других типов в  Simple-Scada, все работают стандартно. Компилятор который мы используем в Simple-Scada работает с переменными также как и любой другой современный компилятор. Он никак не меняет значения переменных, не выполняет с ними никаких лишних преобразований. Поэтому, если бы переменная действительная была Boolean, то не нужно было бы вызывать AsBool. Это значит, что в Вашу переменную с OPC-сервера приходит не Boolean значение (true или false), а например целочисленное (1 или 0), поэтому Вам и приходится явно приводить его к типу Boolean вызывая AsBool. В этой ситуации можно обойтись и без AsBool, только в этом случае 1 или 0 нельзя сравнивать с true и false и нужно писать так:
Код: (delphi)
if Variable.Value then myVar := True;

Neskad

  • Новичок
  • *
  • Сообщений: 31
    • Просмотр профиля
Re: Работа кнопки без фиксации
« Ответ #24 : 17 Июня 2019, 16:26:21 »
Цитировать
Это значит, что в Вашу переменную с OPC-сервера приходит не Boolean значение (true или false), а например целочисленное (1 или 0), поэтому Вам и приходится явно приводить его к типу Boolean вызывая AsBool.
Я проверял это с внутренней глобальной переменной (внутренний тег) с типом Boolean, привязав её к кнопке с фиксацией.
Выражение (Variable.Value = True) не истинно при любом состоянии кнопки.

Стало интересно, проверил с Matrikon Simulation OPC и c arOPС.
С Matrikon не работает, с arOPC всё нормально, условие (Variable.Value = True) выполняется, если внешний тег True.

Но с внутренними тегами, работает только через Variable.AsBool.

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3000
    • Просмотр профиля
    • Simple-Scada
Re: Работа кнопки без фиксации
« Ответ #25 : 17 Июня 2019, 16:48:52 »
Цитировать
Я проверял это с внутренней глобальной переменной (внутренний тег) с типом Boolean, привязав её к кнопке с фиксацией.
Всё верно, при нажатии кнопки в переменную записывается 1 / 0, вместо true / false. Поэтому, если во внутреннюю переменную значения записываются через компонент Кнопка, то придётся использовать либо AsBool, либо сравнивать так: "if Variable.Value then myVar := True;".

Цитировать
С Matrikon не работает, с arOPC всё нормально
Значит от Matrikon в скаду приходит 1 / 0, а от arOPC true / false.


Neskad

  • Новичок
  • *
  • Сообщений: 31
    • Просмотр профиля
Re: Работа кнопки без фиксации
« Ответ #26 : 17 Июня 2019, 17:11:31 »
Цитировать
Значит от Matrikon в скаду приходит 1 / 0, а от arOPC true / false.
Любопытно, но кажется это скада пишет в matrikon 1 / 0. Если менять значение (true / false) в самом Matrikon, то в скаде оно обрабатывается правильно - как true/ false, а если переключать кнопку из скады, то она посылает в Matrikon 1 / 0.
Впрочем, невелика проблема, судя по всему - со всеми реальными OPC скада взаимодействует хорошо, в то что у меня под рукой: arOPC,  MasterOPC и Овен OPC теги читаются и пишутся нормально.

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3000
    • Просмотр профиля
    • Simple-Scada
Re: Работа кнопки без фиксации
« Ответ #27 : 17 Июня 2019, 17:24:35 »
Да, если тег записывается из скады, например через Кнопку, то, как мы и писали выше, в тег идут значения 1 и 0 (кнопка всегда записывает в целочисленном виде). Если запись идёт через скрипты, то скада будет записывать то, что написано в скрипте:
Код: (delphi)
Variable.Value := True; // скада запишет True
Код: (delphi)
Variable.Value := 1; // скада запишет 1
Но далее OPC-сервер может по-разному работать с значением, например он может знать что переменная имеет тип Boolean и вместо 1 которую хочет записать скада он может записать True в переменную и вернуть скаде True. Другой OPC-сервер может записать 1 и вернуть скаде 1, это зависит от OPC-сервера и типа данных который назначен переменной на OPC-сервере. Мы только говорим о том, что скаде все эти значения безразличны и она никак дополнительно не работает с этими значениями и не меняет их. Если переменная внешняя и от OPC-сервера пришла 1, то скада будет работать с ней как с 1. Если придёт True, то будет работать как с Boolean-значением True. Для внутренних переменных правила те же, только значения внутренних переменных присваиваются либо скриптами внутри скады, либо через компоненты скады, такие как Кнопка (целочисленные значения 1 и 0).
« Изменён: 17 Июня 2019, 17:26:05 от Simple-Scada »