Показано с 1 по 4 из 4

Тема: Дискретное управление клапаном по ПИД.

  1. #1

    По умолчанию Дискретное управление клапаном по ПИД.

    Есть ПИД-регулятор. Есть клапан, который управляется дискретными выходами Открыть, Закрыть, с него приходят дискретные Открыто/Закрыто.
    Время полного хода клапана - 100 секунд.
    Написал впервые что-то на ST, оцените, может кто-то что-то дополнит. Может кому-то понадобится.
    Коротко: запоминается предыдущее воздействие, рассчитывается новое как разница предыдущее-новое.
    В другой части программы обрабатываю условия, если ПИД выдал 0% или 100%, то выдаю на соответствующие выходы время равное 1,2 полного хода, чтоб клапан точно дошёл.
    Как запихнуть подобное условие в этот блок - я не смог разобраться.
    А может уже есть готовые кейсы подобного управления и я просто изобрёл велосипед.

    Скрытый текст:
    PHP код:
    FUNCTION_BLOCK ValveControl

    VAR_INPUT
        PIDOutput
    REAL;    // 0-100% от PID-регулятора
        
    FullTimeREAL;    // Время полного хода клапана в секундах
        
    OpenStateBOOL;    // Состояние клапана "Открыт"
        
    CloseStateBOOL;    // Состояние клапана "Закрыт"
        
    UnixTimeUDINT;     // Текущее время в Unix формате (секунды)
    END_VAR

    VAR_OUTPUT
        OpenOutput
    BOOL;    // Выход "Открыть"
        
    CloseOutputBOOL;    // Выход "Закрыть"
        
    OpenTimeREAL;    // Рассчитанное время открытия (секунды)
        
    CloseTimeREAL;   // Рассчитанное время закрытия (секунды)
    END_VAR

    VAR
        
    PreviousOutputREAL;    // Предыдущее значение сигнала PID
        
    OpenTimeCounterREAL;         // Счетчик времени открытия
        
    CloseTimeCounterREAL;       // Счетчик времени закрытия
        
    OpenTimerStartedBOOL;     // Флаг запуска таймера открытия
        
    CloseTimerStartedBOOL;    // Флаг запуска таймера закрытия
        
    InitializedBOOL;     // Флаг инициализации 
        
    LastOpenTimeUDINT// Время начала таймера открытия
        
    LastCloseTimeUDINT// Время начала таймера закрытия
    END_VAR

    // Инициализация переменных при первом вызове функции
    IF NOT Initialized THEN
        PreviousOutput 
    := 0;
        
    OpenTimeCounter := 0;
        
    CloseTimeCounter := 0;
        
    OpenTimerStarted := FALSE;
        
    CloseTimerStarted := FALSE;
        
    Initialized := TRUE;
    END_IF

    // Проверка состояния клапана
    IF OpenState THEN
        OpenTimeCounter 
    := 0// Сбрасываем счетчик времени открытия
        
    OpenTimerStarted := FALSE;
        
    OpenOutput := FALSE// Сбрасываем выход "Открыть"
    ELSIF CloseState THEN
        CloseTimeCounter 
    := 0// Сбрасываем счетчик времени закрытия
        
    CloseTimerStarted := FALSE;
        
    CloseOutput := FALSE// Сбрасываем выход "Закрыть"
    END_IF

    // Вычисление времени удержания выхода
    IF PIDOutput PreviousOutput THEN
        OpenTimeCounter 
    := OpenTimeCounter + (PIDOutput PreviousOutput) / 100 FullTime;
    ELSIF PIDOutput PreviousOutput THEN
        CloseTimeCounter 
    := CloseTimeCounter + (PreviousOutput PIDOutput) / 100 FullTime;
    END_IF

    // Установка выхода "Открыть"
    IF OpenTimeCounter AND NOT OpenTimerStarted THEN
        OpenTimerStarted 
    := TRUE;
        
    LastOpenTime := UnixTime// Запоминаем начальное время
        
    OpenOutput := TRUE;
    END_IF

    // Проверка таймера открытия
    IF OpenTimerStarted THEN
        
    // Сбрасываем выход "Открыть" только если таймер сработал
        
    IF UnixTime LastOpenTime >= REAL_TO_UDINT(OpenTimeCounterTHEN 
            OpenOutput 
    := FALSE;
            
    OpenTimerStarted := FALSE;
            
    OpenTimeCounter := 0;
        
    END_IF

        
    // Сбрасываем выход "Открыть" если клапан уже открыт
        
    IF OpenState THEN
            OpenOutput 
    := FALSE;
            
    OpenTimerStarted := FALSE;
            
    OpenTimeCounter := 0;
        
    END_IF
    END_IF

    // Установка выхода "Закрыть"
    IF CloseTimeCounter AND NOT CloseTimerStarted THEN
        CloseTimerStarted 
    := TRUE;
        
    LastCloseTime := UnixTime// Запоминаем начальное время
        
    CloseOutput := TRUE;
    END_IF

    // Проверка таймера закрытия
    IF CloseTimerStarted THEN
        
    // Сбрасываем выход "Закрыть" только если таймер сработал
        
    IF UnixTime LastCloseTime >= REAL_TO_UDINT(CloseTimeCounterTHEN
            CloseOutput 
    := FALSE;
            
    CloseTimerStarted := FALSE;
            
    CloseTimeCounter := 0;
        
    END_IF

        
    // Сбрасываем выход "Закрыть" если клапан уже закрыт
        
    IF CloseState THEN
            CloseOutput 
    := FALSE;
            
    CloseTimerStarted := FALSE;
            
    CloseTimeCounter := 0;
        
    END_IF
    END_IF

    // Сохранение текущего значения сигнала PID
    PreviousOutput := PIDOutput;

    // Установка выходных значений OpenTime и CloseTime
    OpenTime := OpenTimeCounter
    CloseTime := CloseTimeCounter

    END_FUNCTION_BLOCK 

  2. #2

    По умолчанию

    Ваше решение напоминает RegKZR из менеджера компонентов.

    На мой взгляд, эти решения неудачны тем, что при переполнении на краях диапазона выхода "аналогового" ПИД регулятора (0 или 100 %) будет неоднозначное поведение:
    1 вариант: прироста по сравнению с предыдущим пересчётом нет, значит и нет управляющих сигналов (больше или меньше)
    2 вариант: т.к. ПИД выдал 0 % (или 100 %), то значит требуется полное закрытие (открытие) задвижки.

    На мой взгляд, оба варианта неправильны, т.к. программа лишь предполагает реальное положение регулирующего клапана. Поэтому будет или потеряно управление (1 вариант) или в систему будет вносится ненужное возмущающее воздействие (2 вариант).

    Поясню по возмущению. Клапаны отрываются и закрываются неравномерно. Например, было подано 10 минимальных импульсов открытия, а чтобы вернуть клапан в исходное положение требуется не 10, а 11 импульсов закрытия. Да, после возвращения П составляющая остаётся неизменной, но на дополнительный импульс потребовалось изменить И составляющую, и, таким образом, хотя клапан вернулся в исходное состояние, выход ПИД немного уменьшился. Через время выход станет равным 0 и программа подаст огромный импульс закрытия - внесёт возмущение.
    С таким явлением я сам столкнулся, причём у меня было 5 шиберов и одни смещали ПИД к 0%, а другие к 100% - никакой определённости.
    Это не только со мной происходило
    https://owen.ru/forum/showthread.php...l=1#post434043


    Т.к. тогда у меня был ПЛК и полный доступ ко всем потрохам ПИД, то быстрым решением стало поддержание И составляющей около 50% (с пересчётом всех переменных из преобразования в импульсы).

    Правильное решение - переписать ПИД под управление 3-позиционным клапаном.
    Посмотрите, тут пояснял математику и показал пример на FBD (о причинах такого выбора пояснил ниже)
    https://owen.ru/forum/showthread.php...l=1#post430251
    https://owen.ru/forum/showthread.php...l=1#post436517

    И добавлю, для нормального регулирования важен подбор не только Кп, Ти, Тд, но и сглаживание зашумлённого аналогового сигнала и период пересчёта регулятора.
    Время минимального импульса не может быть меньше времени переключения реле - менее 200 мс.

    Если что-то непонятно по алгоритму - спрашивайте.
    Может, сможете переписать на ST - я без проверки и отладки не решился.
    Ещё думал добавить в ПИД ещё один фильтр 1-порядка для сглаживания измерений, тогда и Д составляющую можно было бы использовать.
    Последний раз редактировалось FPavel; 27.08.2024 в 18:50.

  3. #3

    По умолчанию

    Просто погонял блок, с 20 до 80 % вручную (концевики выключены), в некоторых случаях включаются выходы Отрыть и Закрыть одновременно, с одним временем. Такого быть не должно.

  4. #4

    По умолчанию

    Цитата Сообщение от FPavel Посмотреть сообщение
    Ваше решение напоминает RegKZR из менеджера компонентов.

    На мой взгляд, эти решения неудачны тем, что при переполнении на краях диапазона выхода "аналогового" ПИД регулятора (0 или 100 %) будет неоднозначное поведение:
    1 вариант: прироста по сравнению с предыдущим пересчётом нет, значит и нет управляющих сигналов (больше или меньше)
    2 вариант: т.к. ПИД выдал 0 % (или 100 %), то значит требуется полное закрытие (открытие) задвижки.
    Спасибо, попробую ваш макрос на реальной системе как будет возможность.
    Вынужден согласиться со всеми вашими доводами.
    Выглядит, конечно, как нечто гениальное)
    На st не смогу переписать, не хватает знаний.
    Да и зачем, если оно в fbd работает.

Похожие темы

  1. Ответов: 2
    Последнее сообщение: 05.04.2020, 21:34
  2. Управление клапаном 4-20 мА
    от corvuscineris в разделе ПЛК63/73
    Ответов: 5
    Последнее сообщение: 26.03.2020, 04:47
  3. МУ110-6У управление клапаном
    от Dimooon в разделе Мх110
    Ответов: 7
    Последнее сообщение: 02.06.2016, 13:46
  4. Управление пропорциональным клапаном?
    от Tyshkovets в разделе Подбор Оборудования
    Ответов: 4
    Последнее сообщение: 29.03.2013, 11:26
  5. Управление пропорциональным клапаном
    от Elektron76 в разделе Подбор Оборудования
    Ответов: 2
    Последнее сообщение: 05.08.2008, 19:22

Ваши права

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