Показано с 1 по 10 из 509

Тема: ПИД регулятор

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1

    По умолчанию

    Прошло уже много лет, а тема до сих пор актуальна! Боролся и я в свое время с библиотечными творениями, но закончилось это написанием простого функционального блока, который устраивает в 99% случаев.
    Вот код:

    FUNCTION_BLOCK PID_REG
    VAR_INPUT
    EN:BOOL; (*Включить регулятор*)
    SETP: REAL ; (*Уставка*)
    FEED: REAL ; (*Обратная связь*)
    MAN_IN: REAL; (*Выход в ручном режиме*)
    KP: REAL ; (*Коэффициент усиления*)
    KI: REAL ; (*Коэффициент усиления интегрального звена*)
    KD: REAL; (*Коэффициент усиления дифференциального звена*)
    MAX_V: REAL; (*Максимум выхода*)
    MIN_V: REAL; (*Минимум выхода*)
    RES: BOOL; (*Сброс регулятора*)
    MAN: BOOL; (*Ручной режим*)
    CLOCK: DINT; (*Текущее время*)
    END_VAR
    (*Вход CLOCK - часы, постоянно инкрементируемое двойное слово. Частота может быть любой.
    Это зависит от того с какой точностью необходимо обрабатывать временные интервалы.*)

    VAR_OUTPUT
    END:BOOL; (*Регулятор включен*)
    LMN: REAL ; (*Выход регулятора*)
    END_VAR

    VAR
    E_N,E_N1,E_N2,U_N0,U_N1: REAL;
    DELTA_T,KI_DISCR,KD_DISCR: REAL;
    ST0,ST1: DINT;
    END_VAR

    (*Собственно код*)

    IF EN THEN (*Если включено, то ПОЕХАЛИ!*)
    (*Посчитаем отклонения во все моменты времени*)
    E_N2:=E_N1;
    E_N1:=E_N;
    E_N:=SETP-FEED;
    ST1:=ST0;
    ST0:=CLOCK;
    DELTA_T:=DINT_TO_REAL(ST0-ST1)/10.0; (*Временной интервал X Сек. Часы на входе с дискретностью X/10 Сек*)
    (*А теперь с коэффициентами*)
    KI_DISCR:=KI*DELTA_T;
    KD_DISCR:=KD/DELTA_T;
    (*Собственно - выход, то есть сумма интегрального и дифференциального звена*)
    U_N0:=U_N1+KI_DISCR*E_N+KD_DISCR*(E_N-2*E_N1+E_N2);
    IF KI>0 THEN
    IF KP*E_N+U_N0>MAX_V THEN (*Проверка максимума*)
    U_N0:=MAX_V-KP*E_N;
    END_IF;
    IF KP*E_N+U_N0<MIN_V THEN (*Проверка минимума*)
    U_N0:=MIN_V-KP*E_N;
    END_IF;
    ELSE U_N0:=0;
    END_IF;
    IF RES=TRUE THEN (*Сброс, однако*)
    U_N0:=0;
    END_IF;
    IF MAN=TRUE THEN (*Ручной режим*)
    U_N0:=MAN_IN-KP*E_N;
    END_IF;
    U_N1:=U_N0;
    LMN:=KP*E_N+U_N0; (*Добрались, таки до выхода*)
    END:=TRUE; (*Все посчитано*)
    ELSE
    END:=FALSE; (*Регулятор отключен, дальше тоже ничего не выполняется*)
    LMN:=0; (*Выход, на всякий случай обнулим*)
    END_IF;

    Пробуйте, видоизменяйте как душе угодно!
    Последний раз редактировалось Алексей Дмитриев; 18.06.2013 в 10:44.

  2. #2
    Пользователь
    Регистрация
    27.08.2011
    Адрес
    Курган
    Сообщений
    212

    По умолчанию

    Цитата Сообщение от Алексей Дмитриев Посмотреть сообщение
    Прошло уже много лет, а тема до сих пор актуальна! Боролся и я в свое время с библиотечными творениями, но закончилось это написанием простого функционального блока, который устраивает в 99% случаев.
    Вот код:

    FUNCTION_BLOCK PID_REG
    VAR_INPUT
    EN:BOOL; (*Включить регулятор*)
    SETP: REAL ; (*Уставка*)
    FEED: REAL ; (*Обратная связь*)
    MAN_IN: REAL; (*Выход в ручном режиме*)
    KP: REAL ; (*Коэффициент усиления*)
    KI: REAL ; (*Коэффициент усиления интегрального звена*)
    KD: REAL; (*Коэффициент усиления дифференциального звена*)
    MAX_V: REAL; (*Максимум выхода*)
    MIN_V: REAL; (*Минимум выхода*)
    RES: BOOL; (*Сброс регулятора*)
    MAN: BOOL; (*Ручной режим*)
    CLOCK: DINT; (*Текущее время*)
    END_VAR
    (*Вход CLOCK - часы, постоянно инкрементируемое двойное слово. Частота может быть любой.
    Это зависит от того с какой точностью необходимо обрабатывать временные интервалы.*)

    VAR_OUTPUT
    END:BOOL; (*Регулятор включен*)
    LMN: REAL ; (*Выход регулятора*)
    END_VAR

    VAR
    E_N,E_N1,E_N2,U_N0,U_N1: REAL;
    DELTA_T,KI_DISCR,KD_DISCR: REAL;
    ST0,ST1: DINT;
    END_VAR

    (*Собственно код*)

    IF EN THEN (*Если включено, то ПОЕХАЛИ!*)
    (*Посчитаем отклонения во все моменты времени*)
    E_N2:=E_N1;
    E_N1:=E_N;
    E_N:=SETP-FEED;
    ST1:=ST0;
    ST0:=CLOCK;
    DELTA_T:=DINT_TO_REAL(ST0-ST1)/10.0; (*Временной интервал X Сек. Часы на входе с дискретностью X/10 Сек*)
    (*А теперь с коэффициентами*)
    KI_DISCR:=KI*DELTA_T;
    KD_DISCR:=KD/DELTA_T;
    (*Собственно - выход, то есть сумма интегрального и дифференциального звена*)
    U_N0:=U_N1+KI_DISCR*E_N+KD_DISCR*(E_N-2*E_N1+E_N2);
    IF KI>0 THEN
    IF KP*E_N+U_N0>MAX_V THEN (*Проверка максимума*)
    U_N0:=MAX_V-KP*E_N;
    END_IF;
    IF KP*E_N+U_N0<MIN_V THEN (*Проверка минимума*)
    U_N0:=MIN_V-KP*E_N;
    END_IF;
    ELSE U_N0:=0;
    END_IF;
    IF RES=TRUE THEN (*Сброс, однако*)
    U_N0:=0;
    END_IF;
    IF MAN=TRUE THEN (*Ручной режим*)
    U_N0:=MAN_IN-KP*E_N;
    END_IF;
    U_N1:=U_N0;
    LMN:=KP*E_N+U_N0; (*Добрались, таки до выхода*)
    END:=TRUE; (*Все посчитано*)
    ELSE
    END:=FALSE; (*Регулятор отключен, дальше тоже ничего не выполняется*)
    LMN:=0; (*Выход, на всякий случай обнулим*)
    END_IF;

    Пробуйте, видоизменяйте как душе угодно!
    А на каком языке это написано? Можете выложить готовый блок? И при повторении выдаёт ошибку
    Изображения Изображения
    • Тип файла: jpg пид.jpg (172.5 Кб, Просмотров: 277)
    Последний раз редактировалось kukla100; 20.04.2014 в 18:19.

Похожие темы

  1. регулятор
    от Egor в разделе ПЛК63/73
    Ответов: 8
    Последнее сообщение: 23.02.2011, 10:58
  2. пид регулятор плк 150 и.м.
    от mihan-987654321 в разделе ПЛК1хх
    Ответов: 3
    Последнее сообщение: 23.09.2010, 12:17
  3. пид регулятор с шим в 110-60
    от AKHolod в разделе ПЛК1хх
    Ответов: 2
    Последнее сообщение: 07.07.2010, 14:19
  4. ПИД-регулятор
    от trunf в разделе ПЛК1хх
    Ответов: 6
    Последнее сообщение: 14.11.2008, 23:17
  5. ПИД регулятор
    от Александр М в разделе ПЛК1хх
    Ответов: 6
    Последнее сообщение: 22.10.2007, 08:47

Ваши права

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