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

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

Автор Тема: Проблема с сетевой переменной  (Прочитано 5886 раз)

StanleyTucci

  • Новичок
  • *
  • Сообщений: 22
    • Просмотр профиля
Проблема с сетевой переменной
« : 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.  Я хочу, чтобы в текстовое поле выводился правильный перевод этой переменной, какой бы она ни была.
« Изменён: 13 Июня 2023, 13:42:03 от Simple_Scada »

Simple Scada

  • Глобальный модератор
  • *****
  • Сообщений: 285
    • Просмотр профиля
    • Simple-Scada
Re: проблема с сетевой переменной
« Ответ #1 : 13 Июня 2023, 13:15:25 »
Здравствуйте.

1. Компоненты "Кнопка" и "Флажок" могут работать с битом переменной напрямую - см. свойство "Бит". Поэтому, если требуется работа с битами в данных компонентах, то в этом случае можно обойтись без скриптов. Для других компонентов можно работать с битами через скрипты. Например, чтобы извлечь нужный бит из значения переменной, нужно использовать функцию GetBit. См. примеры изменения цвета по биту переменной по ссылке.
2. Если требуется работать с переменной, созданной в редакторе переменных, то ее не нужно объявлять в скрипте. В Вашем случае, в разделе "var", объявлена локальная переменная скрипта с именем "Data_net" и далее в скрипте Вы работаете именно с ней. Соответственно, при изменении внешней переменной с именем "Data_net" результат выполнения скрипта будет неправильным.
3. Чтобы скрипт выполнялся по изменению переменной, указанной в свойстве объекта "Переменная" или "Доп.переменная" он должен быть назначен на событие OnDataChange или OnDataChangeEx соответственно. Либо можно использовать скрипт с типом события "Изменились переменные".
4. Если в свойстве "Переменная" для компонента "Поле" указать переменную, то в нем будет отображаться ее значение. Поэтому для вывода преобразованного значения нужно использовать компонент "Текст".

Если разобраться не получится, то пришлите для проверки на support@simple-scada.com текущую версию Вашего проекта из директории "..\Simple-Scada 2\Projects" и укажите, какой скрипт нужно проверить.
« Изменён: 13 Июня 2023, 13:40:56 от Simple_Scada »

teplocom

  • Новичок
  • *
  • Сообщений: 47
  • с чувством уверенности в завтрашнем дне
    • Просмотр профиля
Re: Проблема с сетевой переменной
« Ответ #2 : 14 Июня 2023, 09:00:28 »
Добрый день!

Мне нужно сетевую переменную Data_net перевести в двоичное число, чтобы в будущем извлекать биты.
Код: (delphi)
var
Data_net: word;
begin
  Data_net := ?????;
 
Мой вопрос состоит в том, что почему без строчки  Data_net := 24576 все ломается?
Мне кажется вы наблюдаете эффект из: Изменение 1
И, как вам написал производитель, при работе с внешней переменной этого эффекта наблюдаться не будет.
« Изменён: 14 Июня 2023, 09:11:11 от teplocom »

StanleyTucci

  • Новичок
  • *
  • Сообщений: 22
    • Просмотр профиля
Re: Проблема с сетевой переменной
« Ответ #3 : 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.

То что моя переменная - сетевая, разве не означает, что она уже внешняя?
« Изменён: 15 Июня 2023, 11:37:53 от Simple Scada »

Nomad

  • Новичок
  • *
  • Сообщений: 27
    • Просмотр профиля
Re: Проблема с сетевой переменной
« Ответ #4 : 15 Июня 2023, 11:59:01 »
myInt := Data_net.AsInt;
может так?

И inttobin у меня заработала только со значением 15, а не 16. Если ставлю 16, то в выходной строке 17 символов получается.
Версия 2.6.5.0
« Изменён: 15 Июня 2023, 12:51:47 от Simple-Scada »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3214
    • Просмотр профиля
    • Simple-Scada
Re: Проблема с сетевой переменной
« Ответ #5 : 15 Июня 2023, 12:50:37 »
Цитировать
То что моя переменная - сетевая, разве не означает, что она уже внешняя?
Внешняя переменная - это переменная, которая объявлена в меню редактирования переменных и у которой задан тип = "Внешний тег";
Внутренняя переменная - это переменная, которая объявлена в меню редактирования переменных и у которой задан тип = "Внутренний тег";
Локальная переменная - это переменная объявленная в скрипте, в разделе var.

Внутренние и внешние переменные в Simple-Scada являются объектами типа TM_Variable с множеством свойств и методов, которые подробно описаны по этой ссылке. Если нужно получить значение переменной в виде целого числа, то нужно использовать свойство 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 символов получается.
Да, выводится на один символ больше, добавим исправление в ближайшее обновление.

StanleyTucci

  • Новичок
  • *
  • Сообщений: 22
    • Просмотр профиля
Re: Проблема с сетевой переменной
« Ответ #6 : 15 Июня 2023, 15:46:53 »
Это помогло мне, спасибо большое
я правда так и не понял, почему мой способ не работал

Nomad

  • Новичок
  • *
  • Сообщений: 27
    • Просмотр профиля
Re: Проблема с сетевой переменной
« Ответ #7 : 15 Июня 2023, 16:13:52 »
я правда так и не понял, почему мой способ не работал
Integer(Dat_net) возвращает скорее всего номер указателя в памяти на переменную Dat_Net (грубо говоря адрес, где располагается значение переменно), поэтому он меняется от каждого запуска клиента или сервера.
Dat_Net.AsInt возвращает непосредственно значение переменной, т.е. содержимое по ячейке памяти с адресом Integer(Dat_net).
Поэтому Integer(Dat_net.AsInt) тоже корректно работает.