Страница 138 из 251 ПерваяПервая ... 3888128136137138139140148188238 ... ПоследняяПоследняя
Показано с 1,371 по 1,380 из 2508

Тема: CODESYS V3.5. Визуализация

  1. #1371

    По умолчанию

    Добрый день!

    Есть главная визуализация Visualisation, на ней элемент Набор вкладок (3 вкладки, соответственно, на каждой по визуализации: Visu1, Visu2, Visu3). Переменная VisuElems.CURRENTVISU в любом случае, независимо от того, какая вкладка, принимает значение 'Visualisation'.

    Существует ли способ из программы узнать, какая вкладка активна? Без использования переменной-переключателя.

  2. #1372
    Супер Модератор Аватар для Евгений Кислов
    Регистрация
    27.01.2015
    Адрес
    Москва
    Сообщений
    12,067

    По умолчанию

    Цитата Сообщение от GoodLuck Посмотреть сообщение
    Добрый день!

    Есть главная визуализация Visualisation, на ней элемент Набор вкладок (3 вкладки, соответственно, на каждой по визуализации: Visu1, Visu2, Visu3). Переменная VisuElems.CURRENTVISU в любом случае, независимо от того, какая вкладка, принимает значение 'Visualisation'.

    Существует ли способ из программы узнать, какая вкладка активна? Без использования переменной-переключателя.
    Добрый день.
    Для начала потребуется получить контекст клиента (pClientData) - см. этот пример:
    https://ftp.owen.ru/CoDeSys3/21_Exam...projectarchive

    После этого в программе:

    Код:
    VAR
        itfFrameManager: VisuElems.VisuElemBase.IFrameManager;
        aiCurrentFrameIndex: ARRAY [1..VISU_MAX_NUMBER_OF_CLIENTS] OF INT; // индексы текущих экранов фреймов для всех клиентов
    END_VAR
    
    
    
    itfFrameManager := VisuElems.VisuElemBase.g_VisuManager.GetFrameManager(); 
    
    FOR := 1 TO VISU_MAX_NUMBER_OF_CLIENTS DO
    
        aiCurrentFrameIndex[i] := itfFrameManager.GetSelectedVisu('MyVisu.MyFrameName', apClientData[i]);
        // MyVisu - название экрана, на котором расположен фрейм
        // MyFrameName - имя элемента, заданное в параметра фрейма (первый параметр в списке)
        // apClienData - массив с контекстами клиентов
    
    END_FOR
    Если у вас используется VisuElems.CURRENTVISU - то контексты клиентов должны совпадать, так что достаточно работать с одним из них.

  3. #1373

    По умолчанию

    Цитата Сообщение от DenisV Посмотреть сообщение
    Добрый день, коллеги!
    Возник следующий вопрос. В коде программы используется функциональный блок усреднения значений,который вызывается раз в секунду. После усреднения необходимо округлить значение до определенного разряда, в данном примере до одной значащей цифры после запятой. Для этого используются функция ROUND библиотеки OSCAT_BASIC. Результат округления отображается в визуализации с форматированием %s, и вроде бы всё работает как надо, но в определенный момент времени с периодичностью примерно раз в три секунды к результату округления добавляется 0.00001.Вложение 55901 Первое число - выходное значение блока усреднения, второе число результат работы функции Round( где вход это выход с блока усреднения и N=1). Оба числа это Real. Почему округление иногда срабатывает некорректно и как можно решить этот вопрос?
    Потому что округлять Real так себе затея. Округляйте WString или в INT перекидывайте. Вот код для генерации WString с округлением:
    PHP код:
    FUNCTION fRealToWString WSTRING
    VAR_INPUT
        In
    :             REAL;
        
    iDec:            INT;    (*Количество знаков после запятой*)
    END_VAR
    VAR
        
    diValue:        DINT;
        
    i:                INT;
    END_VAR
    VAR CONSTANT
        sDot
    :             WSTRING(1):=".";
    END_VAR


    (*Значение с плавающей точкой*)
    iDec:= LIMIT(0,iDec,6);
        
    diValue:= LREAL_TO_DINT(ABS(In) * EXPT(10iDec));
    IF 
    ABS(In) * EXPT(10iDec) - DINT_TO_REAL(diValue) > 0.5 THEN
        diValue
    := diValue 1;        
    END_IF
        
    fRealToWString
    := DINT_TO_WSTRING(diValue);
        
    FOR 
    i:= WLEN(fRealToWStringTO iDec DO
         
    fRealToWString:= WCONCAT("0"fRealToWString);
    END_FOR
        
    IF iDec 0 THEN
        fRealToWString
    := WINSERT(fRealToWStringsDotWLEN(fRealToWString) - iDec);
    END_IF

    IF In 0 THEN
        fRealToWString
    := WCONCAT("-"fRealToWString);
    END_IF 
    Собственно большая его часть из OSCAT

  4. #1374
    Пользователь Аватар для capzap
    Регистрация
    25.02.2011
    Адрес
    Киров
    Сообщений
    10,225

    По умолчанию

    Цитата Сообщение от DenisV Посмотреть сообщение
    Почему округление иногда срабатывает некорректно и как можно решить этот вопрос?
    у меня не воспроизвелось, но можете попробовать как еще один из вариантов округления INT_TO_REAL(REAL_TO_INT(VALUE / 0.1)) * 0.1, где 0.1 один знак после запятой
    Bad programmers worry about the code. Good programmers worry about data structures and their relationships

    среди успешных людей я не встречала нытиков
    Барбара Коркоран

  5. #1375
    Пользователь Аватар для DenisV
    Регистрация
    20.11.2020
    Адрес
    Санкт-Петербург
    Сообщений
    95

    По умолчанию

    Цитата Сообщение от RV9WFJ Посмотреть сообщение
    Потому что округлять Real так себе затея. Округляйте WString или в INT перекидывайте. Вот код для генерации WString с округлением:
    PHP код:
    FUNCTION fRealToWString WSTRING
    VAR_INPUT
        In
    :             REAL;
        
    iDec:            INT;    (*Количество знаков после запятой*)
    END_VAR
    VAR
        
    diValue:        DINT;
        
    i:                INT;
    END_VAR
    VAR CONSTANT
        sDot
    :             WSTRING(1):=".";
    END_VAR


    (*Значение с плавающей точкой*)
    iDec:= LIMIT(0,iDec,6);
        
    diValue:= LREAL_TO_DINT(ABS(In) * EXPT(10iDec));
    IF 
    ABS(In) * EXPT(10iDec) - DINT_TO_REAL(diValue) > 0.5 THEN
        diValue
    := diValue 1;        
    END_IF
        
    fRealToWString
    := DINT_TO_WSTRING(diValue);
        
    FOR 
    i:= WLEN(fRealToWStringTO iDec DO
         
    fRealToWString:= WCONCAT("0"fRealToWString);
    END_FOR
        
    IF iDec 0 THEN
        fRealToWString
    := WINSERT(fRealToWStringsDotWLEN(fRealToWString) - iDec);
    END_IF

    IF In 0 THEN
        fRealToWString
    := WCONCAT("-"fRealToWString);
    END_IF 
    Собственно большая его часть из OSCAT
    Да, спасибо, тоже её находил, но посчитал её слишком ресурсозатратной для ПЛК при большом количестве округляемых значений (могу ошибаться, мб ощутимой разницы и нет) в сравнении например с этой.
    PHP код:
    FUNCTION REAL_TO_FWSTRING wstring
    VAR_INPUT
        rVar
    REAL
        
    usiPrecisionUSINT//кол-во знаков после запятой
        
    END_VAR
    VAR
        
    uliVarULINT;
        
    lrVarlreal;
    END_VAR

    uliVar
    := LREAL_TO_ULINT((rVar)* EXPT(10,usiPrecision));
    lrVar := ULINT_TO_LREAL(uliVar)/EXPT(10,usiPrecision);
    REAL_TO_FWSTRING:= LREAL_TO_WSTRING(lrVar); 

  6. #1376

    По умолчанию

    что касается чисто отображения можно сделать немного по-другому, используя динамические тексты для текстового поля:
    создать динамический лист для переменной вида:
    id текст
    0 - %d //отображение без цифр после запятой
    1 - %.1f // с одним знаком после запятой
    2 - %.2f // 2
    3 - %.3f // 3
    и т.д.

    Только потребуется присвоить для каждого текстового поля переменную с типом отображения и добавить некоторый обработчик в код программы - условия выбора того или иного отображения.

    Что касается появления некоторого 'приращения' у значения, это связано с кодированием типа REAL, также сталкивался с подобным.
    Собс-но с этим же связаны трудности сравнения переменных REAL на равенство, рекомендуется (кажется это было у OSCAT) сравнивать через некотрую дельту, а не в лоб.
    Т.е. код ниже не корректен, т.к. возможны отличия в последних значащих знаках и условие никогда не выполнится (при этом при отладке может казаться что все ок, будет отображаться как будто два одинаковых числа)
    rTmp1 :REAL;
    rTmp2 :REAL;

    IF rTmp1 = rTmp2 <...>

    Соот-но рекомендуется в этом случае сравнивать таким образом

    IF ABS(rTmp1 - rTmp2) < 0000.1 <...> // дельта в зависимости от требуемой точности
    Последний раз редактировалось IgnatTali; 08.07.2021 в 15:54.

  7. #1377

    По умолчанию

    Добрый день.
    Посмотрите, пожалуйста.

    Нужно, что бы на каждом подключаемом WEB-клиенте открывались одни и те же страницы и созданные мной диалоги, что и на первом клиенте, на котором могли быть произведены уже какие-либо действия в интерфейсе.
    Погуглив, пришел к такой конструккции:

    VAR pClientData: POINTER TO VisuElems.VisuStructClientData;

    Далее с помощью

    VisuElems.g_ClientManager.BeginIteration();
    pClientData := VisuElems.g_ClientManager.GetNextClient();

    по числу pClientData > 0 определяем, что произошло изменение числа активных клиентов.
    При увеличении числа активных клиентов, для всех клиентов применяем в цикле сначала открытие нужной страницы, а затем и открытие диалога (информация об открытых хранится в паре массивов), причем эту "синхронгизацию" начинам не сразу, а спустя секунду после подключения клиента, что бы уже загрузиласть стартовая страница.

    Диалоги вызываются так:

    VisuElems.g_ClientManager.BeginIteration();
    REPEAT
    pClientData := VisuElems.g_ClientManager.GetNextClient();
    IF pClientData > 0 THEN
    itfDialogManager:=VisuElems.VisuElemBase.g_VisuMan ager.GetDialogManager();
    itfMyDialog := itfDialogManager.GetDialog('имя нужного диалога');
    itfDialogManager.OpenDialog(itfMyDialog, pClientData, TRUE, null);
    END_IF
    UNTIL pClientData = 0
    END_REPEAT;


    Вопрос. Почти работает - но только для двух вкладок в браузере. Попытка третьего подключения приводит с исключению, которое ведет куда-то вглубь библиотеки визуализации. Может, это потому, что я повторно пытаюсь открыть уже открытые диалоги на более ранних двух клиентах (маловероятно) ? А может, я вообще изобретаю велосипед и есть более простые и правильные способы такой синхронизации интерфейсов?
    Да - специфика задачи. У меня все страницы и диалоги открываются программно. В дизайненре форм к кнопкам никакие действия по открытию страниц или диалогов привязать не получится. Еще среда рекомендует использовть более новую библиотеку VU. Но по ней не нашел особо документации и примеров. Да и не в этом дело, наверное...
    Последний раз редактировалось Петр Петрович; 13.07.2021 в 11:57.

  8. #1378
    Супер Модератор Аватар для Евгений Кислов
    Регистрация
    27.01.2015
    Адрес
    Москва
    Сообщений
    12,067

    По умолчанию

    А может, я вообще изобретаю велосипед и есть более простые и правильные способы такой синхронизации интерфейсов?
    Еще среда рекомендует использовть более новую библиотеку VU. Но по ней не нашел особо документации и примеров.
    Добрый день.
    Посмотрите это видео: https://youtu.be/_kA9WVtbg3A

  9. #1379

    По умолчанию

    Цитата Сообщение от Евгений Кислов Посмотреть сообщение
    Добрый день.
    Посмотрите это видео: https://youtu.be/_kA9WVtbg3A
    Спасибо, посмотрел. Но диалог почему-то не открывается. И ошибок при исполнении вроде не возникает. В среде только начал работать.
    Подскажите, я вообще правильно делаю, в главном цикле, может вызываться при каждом подключении: MyOpenDialog(itfClientFilter:=VU.Globals.AllClient s, xExecute:=TRUE, sDialogName:=sVisuName, xModal:=TRUE);
    sVisuName на момент вызова имеет правильное имя диалога - 'Visualization_3'

  10. #1380
    Супер Модератор Аватар для Евгений Кислов
    Регистрация
    27.01.2015
    Адрес
    Москва
    Сообщений
    12,067

    По умолчанию

    Цитата Сообщение от Петр Петрович Посмотреть сообщение
    Спасибо, посмотрел. Но диалог почему-то не открывается. И ошибок при исполнении вроде не возникает. В среде только начал работать.
    Подскажите, я вообще правильно делаю, в главном цикле, может вызываться при каждом подключении: MyOpenDialog(itfClientFilter:=VU.Globals.AllClient s, xExecute:=TRUE, sDialogName:=sVisuName, xModal:=TRUE);
    sVisuName на момент вызова имеет правильное имя диалога - 'Visualization_3'
    Диалог однократно вызывается по переднему фронту на входе xExecute.
    В вашем случае он должен открыться только один раз (и больше открыть его из кода вы не сможете).

Страница 138 из 251 ПерваяПервая ... 3888128136137138139140148188238 ... ПоследняяПоследняя

Похожие темы

  1. Визуализация CoDeSys
    от Newcomer в разделе ПЛК1хх
    Ответов: 4
    Последнее сообщение: 24.04.2018, 15:26
  2. Визуализация в CoDeSys
    от Newcomer в разделе ПЛК1хх
    Ответов: 15
    Последнее сообщение: 10.05.2017, 21:11
  3. Визуализация CodeSys
    от DanJer в разделе ПЛК1хх
    Ответов: 2
    Последнее сообщение: 30.08.2012, 04:53
  4. Визуализация Codesys
    от Slipknot в разделе ПЛК1хх
    Ответов: 9
    Последнее сообщение: 31.10.2008, 11:36
  5. Визуализация в CoDeSys 2.3
    от Slawa в разделе ПЛК1хх
    Ответов: 10
    Последнее сообщение: 29.08.2008, 18:30

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •