Simple-Scada forum

Simple-Scada 2 => Ваши вопросы => Тема начата: StanleyTucci от 13 Июня 2023, 11:04:31

Название: Проблема с сетевой переменной
Отправлено: StanleyTucci от 13 Июня 2023, 11:04:31
Добрый день!

Мне нужно сетевую переменную Data_net перевести в двоичное число, чтобы в будущем извлекать биты. В текущий момент Data_net := 24576. Пока эта строчка не закомментирована, в текстовом поле выдаётся правильный перевод. (картинка не ерунда)
Но стоит эту строчку закомментировать (ведь сетевая переменная может меняться, она не должна быть всегда равна 24576), выдаёт ерунду.

Код: (delphi)
var
Data_net: word;
myInt : integer;
BinaryNumber: string;
begin
  Data_net := 24576;
  myInt := Integer(Data_net);
  BinaryNumber := inttobin(Data_net,16);
  Field3.Text := Copy(BinaryNumber, 1, 4) + ' ' + Copy(BinaryNumber, 5, 4) + ' ' +
                 Copy(BinaryNumber, 9, 4) + ' ' + Copy(BinaryNumber, 13, 4);
end.

Мой вопрос состоит в том, что почему без строчки  Data_net := 24576 все ломается? Ну и по картинке "ерунда подробнее" видно, что эта переменная и так равна 24576.  Я хочу, чтобы в текстовое поле выводился правильный перевод этой переменной, какой бы она ни была.
Название: Re: проблема с сетевой переменной
Отправлено: Simple Scada от 13 Июня 2023, 13:15:25
Здравствуйте.

1. Компоненты "Кнопка (https://simple-scada.com/help/manual/button.html)" и "Флажок (https://simple-scada.com/help/manual/checkbox.html)" могут работать с битом переменной напрямую - см. свойство "Бит". Поэтому, если требуется работа с битами в данных компонентах, то в этом случае можно обойтись без скриптов. Для других компонентов можно работать с битами через скрипты (https://simple-scada.com/help/script/work-bits.html). Например, чтобы извлечь нужный бит из значения переменной, нужно использовать функцию GetBit (https://simple-scada.com/help/script/getbit.html). См. примеры изменения цвета по биту переменной по ссылке (https://simple-scada.com/help/script/bit-color.html).
2. Если требуется работать с переменной, созданной в редакторе переменных (https://simple-scada.com/help/manual/variable-editor.html), то ее не нужно объявлять в скрипте. В Вашем случае, в разделе "var", объявлена локальная переменная скрипта (https://simple-scada.com/help/script/compilerchange.html) с именем "Data_net" и далее в скрипте Вы работаете именно с ней. Соответственно, при изменении внешней переменной с именем "Data_net" результат выполнения скрипта будет неправильным.
3. Чтобы скрипт выполнялся по изменению переменной, указанной в свойстве объекта "Переменная" или "Доп.переменная" он должен быть назначен на событие OnDataChange или OnDataChangeEx (https://simple-scada.com/help/script/general-events.html) соответственно. Либо можно использовать скрипт с типом события "Изменились переменные (https://simple-scada.com/help/script/changed-the-variables.html)".
4. Если в свойстве "Переменная" для компонента "Поле (https://simple-scada.com/help/manual/field.html)" указать переменную, то в нем будет отображаться ее значение. Поэтому для вывода преобразованного значения нужно использовать компонент "Текст (https://simple-scada.com/help/manual/text.html)".

Если разобраться не получится, то пришлите для проверки на support@simple-scada.com текущую версию Вашего проекта из директории "..\Simple-Scada 2\Projects" и укажите, какой скрипт нужно проверить.
Название: Re: Проблема с сетевой переменной
Отправлено: teplocom от 14 Июня 2023, 09:00:28
Добрый день!

Мне нужно сетевую переменную Data_net перевести в двоичное число, чтобы в будущем извлекать биты.
Код: (delphi)
var
Data_net: word;
begin
  Data_net := ?????;
 
Мой вопрос состоит в том, что почему без строчки  Data_net := 24576 все ломается?
Мне кажется вы наблюдаете эффект из: Изменение 1 (https://simple-scada.com/help/script/compilerchange.html)
И, как вам написал производитель, при работе с внешней переменной этого эффекта наблюдаться не будет.
Название: Re: Проблема с сетевой переменной
Отправлено: StanleyTucci от 15 Июня 2023, 11:12:27
Я чуть-чуть переработал код для большей наглядности:
Код: (delphi)
var
myInt : integer;
BinaryNumber: string;
correct : integer; //24576
correctBinaryNumber : string;
begin
  myInt := Integer(Data_net); //перевод сетевой переменной из word в int
  BinaryNumber := inttobin(myInt,16); //перевод из десятичной в двоичную систему
  correct := 24576;
  correctBinaryNumber := inttobin(correct,16); //перевод из десятичной в двоичную систему
  Text1.Text := inttostr(myInt);

  Field1.Text := Copy(BinaryNumber, 1, 4) + ' ' + Copy(BinaryNumber, 5, 4) + ' ' +
                 Copy(BinaryNumber, 9, 4) + ' ' + Copy(BinaryNumber, 13, 4);
  Field2.Text := Copy(correctBinaryNumber, 1, 4) + ' ' + Copy(correctBinaryNumber, 5, 4) + ' ' +
                 Copy(correctBinaryNumber, 9, 4) + ' ' + Copy(correctBinaryNumber, 13, 4);
end.

То что моя переменная - сетевая, разве не означает, что она уже внешняя?
Название: Re: Проблема с сетевой переменной
Отправлено: Nomad от 15 Июня 2023, 11:59:01
myInt := Data_net.AsInt;
может так?

И inttobin у меня заработала только со значением 15, а не 16. Если ставлю 16, то в выходной строке 17 символов получается.
Версия 2.6.5.0
Название: Re: Проблема с сетевой переменной
Отправлено: Simple-Scada от 15 Июня 2023, 12:50:37
Цитировать
То что моя переменная - сетевая, разве не означает, что она уже внешняя?
Внешняя переменная - это переменная, которая объявлена в меню редактирования переменных (https://simple-scada.com/help/manual/variable-editor.html) и у которой задан тип = "Внешний тег" (https://simple-scada.com/help/manual/varmain.html#:~:text=%D0%A2%D0%B8%D0%BF%20%E2%80%93%20%D0%B2%D0%BD%D0%B5%D1%88%D0%BD%D1%8F%D1%8F%20(%D1%81%20OPC%2D%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0)%20%D0%B8%D0%BB%D0%B8%20%D0%B2%D0%BD%D1%83%D1%82%D1%80%D0%B5%D0%BD%D0%BD%D1%8F%D1%8F%20(%D0%B2%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F)%20%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F.);
Внутренняя переменная - это переменная, которая объявлена в меню редактирования переменных (https://simple-scada.com/help/manual/variable-editor.html) и у которой задан тип = "Внутренний тег" (https://simple-scada.com/help/manual/varmain.html#:~:text=%D0%A2%D0%B8%D0%BF%20%E2%80%93%20%D0%B2%D0%BD%D0%B5%D1%88%D0%BD%D1%8F%D1%8F%20(%D1%81%20OPC%2D%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0)%20%D0%B8%D0%BB%D0%B8%20%D0%B2%D0%BD%D1%83%D1%82%D1%80%D0%B5%D0%BD%D0%BD%D1%8F%D1%8F%20(%D0%B2%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F)%20%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F.);
Локальная переменная - это переменная объявленная в скрипте, в разделе var.

Внутренние и внешние переменные в Simple-Scada являются объектами типа TM_Variable с множеством свойств и методов, которые подробно описаны по этой ссылке (https://simple-scada.com/help/script/tmvariable.html). Если нужно получить значение переменной в виде целого числа, то нужно использовать свойство AsInt, например:
Код: (delphi)
var
  myInt: integer;
begin
  myInt := Data_net.AsInt;
  //...

Также можно сразу из числа получить значение бита. Например:
Код: (delphi)
var
  aInt: Integer;
  aBit0, aBit1, aBit2: Boolean;
begin
  aInt := Data_net.AsInt;    // получаем значение переменной Data_net в виде целого числа
  aBit0 := GetBit(aInt, 0);  // получаем значение нулевого бита
  aBit1 := GetBit(aInt, 1);  // получаем значение первого бита
  aBit2 := GetBit(aInt, 2);  // получаем значение второго бита

  // если биты 0 и 1 включены
  if (aBit0) and (aBit1) then
  begin
    // что-то делаем
  end;
end.

Цитировать
И inttobin у меня заработала только со значением 15, а не 16. Если ставлю 16, то в выходной строке 17 символов получается.
Да, выводится на один символ больше, добавим исправление в ближайшее обновление.
Название: Re: Проблема с сетевой переменной
Отправлено: StanleyTucci от 15 Июня 2023, 15:46:53
Это помогло мне, спасибо большое
я правда так и не понял, почему мой способ не работал
Название: Re: Проблема с сетевой переменной
Отправлено: Nomad от 15 Июня 2023, 16:13:52
я правда так и не понял, почему мой способ не работал
Integer(Dat_net) возвращает скорее всего номер указателя в памяти на переменную Dat_Net (грубо говоря адрес, где располагается значение переменно), поэтому он меняется от каждого запуска клиента или сервера.
Dat_Net.AsInt возвращает непосредственно значение переменной, т.е. содержимое по ячейке памяти с адресом Integer(Dat_net).
Поэтому Integer(Dat_net.AsInt) тоже корректно работает.