Программирование AVR AVR221: цифровой PID-контроллер на AVR Mon, November 11 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


AVR221: цифровой PID-контроллер на AVR Печать
Добавил(а) microsin   

Здесь приведен перевод апноута AVR221: Discrete PID controller on tinyAVR and megaAVR devices [1] (дискретный контроллер PID на микроконтроллерах серий tinyAVR и megaAVR).

Возможности описанного контроллера:

• Простой дискретный (цифровой) алгоритм PID-контроллера
• Можно реализовать на всех моделях микроконтроллеров AVR
• Функция управления PID использует 534 байта памяти программ (FLASH) и требует 877 циклов CPU (применен компилятор IAR, включена оптимизация по размеру кода)

[1 Для чего нужен PID-регулятор?]

Этот апноут описывает простую реализацию дискретного пропорционально-интегрально-дифференциального (дословный перевод Proportional-Integral-Derivative, PID) контроллера.

Когда необходимо применить регулирование выхода системы, отслеживая изменение опорного значения или состояния, может потребоваться некий алгоритм управления. Примером таких приложений может служить управление мотором, поддерживание температуры в печи, стабилизация напряжения, давления, потока жидкости, скорости, ускорения или других значений. Одним из таких алгоритмов является PID, который может использоваться для управления любой измеряемой величиной, когда она может быть затронута при манипулировании другими переменными процесса.

За все время использовалось много решений для управления, но в сравнении со всеми PID-контроллер получил репутацию "индустриального стандарта" из-за своей простоты и хорошего быстродействия. Чтобы получить больше информации по контроллерам PID их применению, обратитесь к другим источникам, например к книге "PID Controllers" K. J. Astrom & T. Hagglund (1995).

AVR221-Typical-PID-regulator-response-fig1-1

Рис. 1-1. Типичный отклик PID-регулятора на скачкообразное изменение входной опорной величины.

Примечание к рис. 1-1: ref - входное отслеживаемое воздействие, pi - отклик пропорционально-интегрального регулятора, p - отклик пропорционального регулятора, pid - отклик PID-регулятора.

[2 PID-регулятор]

На рис. 2-1 схематично показана система с PID-регулятором. PID-контроллер сравнивает измеренную отслеживаемую величину y с опорным значение y0. Разность (или ошибка) e обрабатывается для вычисления нового входного значения для системы u. Это входное значение пытается подстроить измеряемую отслеживаемую величину так, чтобы она вернулась в нужное значение, соответствующее опорному. Получается схема с замкнутым циклом управления (управление с обратной связью).

Альтернативой схеме управления с замкнутой петлей управления является схема открытого цикла управления (без обратной связи). Такая схема проще, но во многих случаях является неудовлетворительной, и её часто невозможно реализовать из-за свойств самой системы. Путем добавления обратной связи по входу системы можно улучшить качество регулирования и даже быстродействие.

AVR221-Closed-Loop-System-with-PID-controller-fig2-1

Рис. 2-1. Управление с обратной связью, с применением PID-регулятора.

Кроме того, в отличие от простых алгоритмов управления, PID-контроллер может управлять входным параметром u, основываясь на истории и скорости изменения опорного сигнала y0. Это дает повышение точности и стабильности в методе управления (см. рис. 1-1, где видно, что PID-регулятор дает меньше колебаний при отслеживании выходной величины).

Основная идея состоит в том, контроллер читает состояние какого-то сенсора. Затем он вычитает измеренное значение из опорного, и из этого получается значение ошибки. Эта ошибка может быть обработана тремя способами:

• отслеживание текущего значения, используя пропорциональное регулирование
• восстановление на основе предыдущего значения, используя интегрирование
• предсказывая будущее значение на основе дифференцирования.

На рис. 2-2 показана более подробная схема PID-контроллера, где Tp, Ti, и Td обозначают константы времени для пропорционального, интегрального и дифференциального условий соответственно.

AVR221-PID-controller-schematic-fig2-2

Рис. 2-2. Схема внутреннего устройства PID-регулятора.

2.1 Пропорциональная составляющая PID-регулятора

Пропорциональное условие (P) подает на вход системы значение, пропорциональное ошибке. Использование только P-управления дает постоянную ошибку во всех случаях кроме тех, когда управляющий вход системы равен 0, и выходное отслеживаемое значение равно требуемому. На рисунке 2-3 статическая ошибка появляется после того, как изменилось требуемое (опорное, reference, ref) значение. Использование слишком большого коэффициента P-регулирования (Tp) в PID-регуляторе делает систему управления нестабильной.

AVR221-P-controller-response-fig2-3

Рис. 2-3. Отклик P-регулятора на скачкообразное изменение опорного параметра.

2.2 Интегральная составляющая PID-регулятора

Интегральное условие (I) выдает на вход системы значение управления, зависящее от суммы предыдущих ошибок. Суммирование ошибок будет продолжаться, пока выходное обрабатываемое системой значение не станет равным требуемому, и когда опорное значение стабильно, то статическая ошибка будет нулевой. Чаще всего составляющая регулирования I нормально используется вместе с составляющей регулирования P, в результате чего получается PI-контроллер. Использование только I-составляющей приведет к медленному регулированию и часто к самовозбуждению системы. На рис. 2-4 показаны отклики системы с применением I и PI управления. Как можно видеть, отклик PI-контроллера не имеет статической ошибки, и отклик I-контроллера очень медленный.

AVR221-I-and-PI-controller-response-fig2-4

Рис. 2-4. Отклик I- и PI-регуляторов на скачкообразное изменение опорного параметра.

2.3 Дифференциальная составляющая PID-регулятора

Дифференциальное условие (D) добавляет к входному сигналу системы (u) информацию о скорости изменения опорного сигнала (насколько быстро изменяется ошибка e). Это улучшает отклик на быстрое случайное изменение в состоянии системы или в опорном отслеживаемом значении. Составляющая D обычно используется совместно с P или PI, в результате чего получаются PD- или PID-контроллер. Слишком большая составляющая D обычно приводит к нестабильности системы. Рис. 2-5 показывает результаты работы D-контроллера и PD-контроллера. Ответ от PD-контроллера дает ускоренное возрастание обрабатываемого системой значения по сравнению с P-контроллером. Имейте в виду, что D-составляющая по сути работает как фильтр высокой частоты (ФВЧ), стоящий на сигнале ошибки, и этот факт очень просто может привести к нестабильности системы и делает её более чувствительной к шуму и помехам.

AVR221-D-and-PD-controller-response-fig2-5

Рис. 2-5. Отклик D- и PD-регуляторов на скачкообразное изменение опорного параметра.

Если объединить все три составляющие управления, то получится PID-контроллер, который обычно дает наилучшие результаты в управлении. Рис. 1-1 сравнивает между собой контроллеры P, PI и PID. PI улучшает P удалением статической ошибки, и PID улучшает PI ускорением ответа и отсутствием при этом перерегулирования.

2.4 Настройка параметров PID-регулятора

Самый лучший способ найти нужные параметры PID - получить их из математической модели системы, параметры могут быть вычислены по необходимому отклику системы. Часто полное математическое описание системы отсутствует, и приходится экспериментально подбирать параметры PID-регулятора. Нахождение составляющих PID-регулятора может быть сложной задачей. Важно хорошо знать систему и её поведение в различных условиях. Оптимальное поведение в ответ на изменение условий или изменение опорной заданной величины зависит от конкретного приложения. Некоторые процессы не должны допускать перерегулирования (выбросов) в ответ на изменение входной отслеживаемой величины. Другие процессы должны минимизировать расход энергии на пути достижения отслеживаемой величины. И почти всегда главным требованием является стабильность системы. Процесс управления не должен допускать самовозбуждения для любого варианта текущих условий регулирования или любые изменения входной отслеживаемой величины. Кроме того, эффект стабилизации должен укладываться в заранее заданные ограничения по времени.

Есть несколько методов для настройки петли регулирования PID. Выбор метода зависит от того, может ли процесс регулирования быть отключенным для настройки, или нет. Метод Ziegler-Nichols хорошо известен как стратегия настройки, не требующая отключения системы. На первом шаге этой методики устанавливают усиление I и D составляющих в 0, увеличивают усиление P, пока не выходе не будут получены установившиеся и стабильные колебания (при этом выходной сигнал должен как можно меньше отличаться от опорного). Затем записывают критическое усиление Kc и период генерации Pc, и значения P, I и D подстраиваются по таблице 2-1.

Таблица 2-1. Параметры методики Ziegler-Nichols для настройки PID.

контроллер Kp Ti Td
P 0.5 * Kc
PD 0.65 * Kc 0.12 * Pc
PI 0.45 * Kc 0.85 * Pc
PID 0.65 * Kc 0.5 * Pc 0.12 * Pc

Дальнейшая настройка параметров часто нужна для оптимизации быстродействия PID-регулятора.

Необходимо иметь в виду, что есть системы, для которых PID-регулятор не очень хорош, или системы, где он будет нормально работать только в малом диапазоне имеющихся состояний системы. Это нелинейные системы, но основная проблема с PID-регулятором проявляется с нестабильными системами, и когда эффект от входного воздействия зависит от состояния системы.

2.5 Дискретный PID-регулятор

Дискретный (цифровой) PID-регулятор будет читать ошибку, делать вычисления и выдавать выходное значение с заданными интервалами времени, с периодом выборки T. Время выборки T должно быть гарантированно меньше, чем самый маленький интервал времени, который может иметь в системе (по техзаданию) важное значение.

2.5.1 Основа алгоритма PID-регулятора

В отличие от простых алгоритмов управления, PID-регулятор может манипулировать управляющим сигналом, основываясь на истории и скорости изменения отслеживаемого сигнала. Это дает метод более точного и стабильного управления.

На рис. 2-2 показана схема PID-регулятора, где Tp, Ti и Tp обозначают константы времени для составляющих пропорционального, интегрального и дифференциального регулирования соответственно.

Передаточная функция системы на рис. 2-2:

AVR221-PID-transfer-function

Это дает зависимость u от e по оси времени:

AVR221-PID-u-equation

Аппроксимация составляющих I и D:

AVR221-PID-approx-integral-and-derivative

Здесь n - дискретный шаг времени t. Это дает выражение для регулятора:

AVR221-PID-equation01

Здесь:

AVR221-PID-Ki-Kd

Чтобы избежать изменений в требуемой величине процесса и любых нежелательных быстрых изменений в управляющем сигнале, регулятор улучшен на базе составляющей D только на значении величины процесса:

AVR221-PID-equation02

[3 Реализация PID-регулятора]

Этот апноут поставляется с готовой реализацией PID-регулятора на языке C [2]. Полную документацию по исходному коду можно найти, если открыть файл readme.html, который имеется в пакете архива.

AVR221-PID-block-app-diagram

Рис. 3-1. Блок-схема демонстрационного приложения PID-регулятора.

На рис. 3-1 показана упрощенная схема демо-приложения [2]. PID-регулятор использует структуру (struct) для сохранения своего состояния и параметров. Эта структура инициализируется в теле функции main, и функциям Init_PID() и PID() передается только указатель на структуру.

Функция PID() должна быть вызвана на каждом интервале времени T. Это реализовано с помощью таймера, который устанавливает флаг PID_timer, когда проходит интервал времени T. Когда флаг PID_timer установлен, подпрограмма в цикле main читает требуемое значение процесса (опорное отслеживаемое значение setPoint) и текущее значение процесса системы, вызывается PID(), и выводит результат на управляющий вход.

Чтобы увеличить точность, множители p_factor, i_factor и d_factor смасштабированы с коэффициентом 1:128. Результат алгоритма PID затем масштабируется обратно делением на 128. Число 128 выбрано для того, чтобы задействовать оптимизацию компилятора (умножение на 128 заменяется сдвигом на 1 бит младшего байта и копированием результата в старший байт).

PFactor = 128 * Kp

В дальнейшем эффект от множителей IFactor и DFactor будут зависеть от интервала выборки T.

                      T
IFactor = 128 * Kp * ---
                      Ti
                     Td
DFactor = 128 * Kp * ---
                      T

3.1 Свертка для интеграла

Входное значение регулирования u иногда достигает некоторого предела. Предел связан либо с ограниченным числовым диапазоном переменных PID-регулятора (в коде могут использоваться целочисленные переменные ограниченной разрядности), либо с выходным диапазоном регулятора, либо насыщением (ограничением сигнала) в усилителях, либо с вычислениями в алгоритме. Это произойдет, если имеется слишком большое различие между измеренной величиной и опорным сигналом. Причина может быть в больших возмущениях / перегрузке, которые система должна обработать.

Если регулятор использует целочисленные составляющие регулирования, ситуация может стать проблематичной. Интеграл по сути просто сумма предыдущих значений, которая может переполниться, и регулятор перестанет работать. Работа восстановится, когда большое возмущение / нагрузка исчезнет, и PID скомпенсирует управляющий сигнал, как только интегральная сумма вернется к нормальному значению.

Проблему целочисленного переполнения можно обойти несколькими способами. В этой реализации максимальная сумма в интеграле ограничена, но ей не позволено превысить значение MAX_I_TERM. Корректное значение MAX_I_TERM будет зависеть от самой системы и используемого времени выборки T.

Прим. переводчика: похожие проблемы есть и в алгоритмах ЦОС (цифровая обработка сигналов, DSP), когда применяется целочисленная арифметика для ускорения работы [3]. другие методы устранения проблемы переполнения - повышение разрядности переменных в вычислениях, и даже переход на арифметику с плавающей запятой. К сожалению, это часто связано с увеличением объема вычислений и усложнением оптимизации и разработки, так что имеет ограниченную область применения. В любом случае для вычислений старайтесь задействовать аппаратные ресурсы ядра AVR [4].

[4 Дополнительные замечания]

Представленный PID-регулятор является упрощенным примером. Регулятор должен хорошо работать, однако может потребоваться улучшение, связанным с конкретным применением (к примеру, устранение переполнений и/или неточностей в регулировании). Можно добавить коррекцию (устранение) насыщения в I-составляющей за счет P-составляющей, если это позволяют условия обработки регулируемой величины.

В вычисление множителей IFactor и DFactor время выборки T является частью выражения. Если T выбрано слишком маленьким, или сделано больше 1 секунды, то будет нарушена точность вычисления либо множителя IFactor, либо множителя DFactor. Примите решение по доработке алгоритма PID при масштабировании, чтобы сохранить точность вычисления I-составляющией (интеграл) и D-составляющей (производная).

[Ссылки]

1. AVR221: Discrete PID controller on tinyAVR and megaAVR devices site:atmel.com.
2. AVR221.zip.
3. AVR223: Digital Filters with AVR (цифровые фильтры на AVR).
4. AVR201: использование аппаратного перемножителя AVR.

 

Комментарии  

 
-1 #8 Макс 08.02.2020 13:40
Я решил попробовать использовать этот алгоритм. Хочу регулировать температуру паяльника. Но, на выходе с регулятора имею -32768 - +32768 значение. Для моего 8 битного ШИМ это не годится. Как правильно было бы его использовать в моем случае? И ещё, он сильно скачет от минимального порога -32768 до максимального 32768.

microsin: значение у Вас 16-битное. Для того, чтобы превратить в 8-битное, нужно просто его поделить на 256. А скачет либо потому что помехи ловите, либо неправильно датчик температуры опрашиваете.
Цитировать
 
 
0 #7 trengtor 09.01.2016 16:53
Я верно понимаю, что на входе этого PID нужно масштабировать не только коэффициенты, но и контролируемый параметр с уставкой?
Цитировать
 
 
+1 #6 xsmirnov 09.01.2015 22:43
Цитирую Станислав:
e(t)=SP-y(t),
SP, как правило, = const. Таким образом,
de(t)/dt = d(SP - y(t))/dt = -dy(t)/dt.

Ошибки в реализации (файл pid.c) - нет (я об этом писал). Ошибка допущена в описании реализации - текст на данном сайте и исходный pdf на английском.
Вы совершенно правы, что
de(t)/dt = d(SP - y(t))/dt = -dy(t)/dt.
Но dy(t)/dt = y(n)-y(n-1), т.е. от значения на текущем шаге надо отнять значение с предыдущего шага.
А -dy(t)/dt = y(n-1)-y(n), следовательно:
de(t)/dt = y(n-1)-y(n). Именно эта формула использована в реализации (pid.c) - я об этом писал раньше. Но вот в тексте описания реализации в последней формуле в разделе 2.5.1 формула отличается от приведенной.
Если, все-таки, непонятно, посмотрите внимательно мои комментарии #3 и #4.
Цитировать
 
 
+1 #5 Станислав 31.12.2014 13:12
Цитирую xsmirnov:
Теперь посмотрим исходник pid.c на 93 строке:
// Calculate Dterm
d_term = pid_st->D_Factor * (pid_st->lastProcessValu e - processValue);
processValue - это текущее значение выходной переменной, т.е. y(n);
pid_st->lastProcessValu e - это значение выходной переменной на предыдущем шаге, т.е. y(n-1).
Отсюда следует, что дифференциально е слагаемое в коде вычисляется по формуле
Kd*(y(n-1) - y(n)), следовательно в последней формуле в разделе 2.5.1 допущена ошибка в оригинальной документации.

Ошибки нет. Тот, кто писал реализацию, хорошо разбирается в теории автоматического регулирования. e(t)=SP-y(t),
SP, как правило, = const. Таким образом,
de(t)/dt = d(SP - y(t))/dt = -dy(t)/dt.
Этот изящный приём используется для устранения "дифференциально го всплеска" при изменении задания SP (setpoint).
Цитировать
 
 
+1 #4 xsmirnov 04.11.2014 12:50
Теперь посмотрим исходник pid.c на 93 строке:
// Calculate Dterm
d_term = pid_st->D_Factor * (pid_st->lastProcessValu e - processValue);
processValue - это текущее значение выходной переменной, т.е. y(n);
pid_st->lastProcessValu e - это значение выходной переменной на предыдущем шаге, т.е. y(n-1).
Отсюда следует, что дифференциально е слагаемое в коде вычисляется по формуле
Kd*(y(n-1) - y(n)), следовательно в последней формуле в разделе 2.5.1 допущена ошибка в оригинальной документации.
Цитировать
 
 
+1 #3 xsmirnov 04.11.2014 12:48
Цитирую:
Цитирую Alex:
Если y(n) это ошибка, то написано верно всё, Вы не правы. А если y(n) это не ошибка, то вообще непонятно что там выражается в формуле.


Ошибка - это разность между y0(t) и y(t), т.е. e(t)=y0(t)-y(t) (см. схему на рис. 2-1).
В алгоритме для того, чтобы избежать изменение управляющего воздействия u(t) при быстром изменении задающего воздействия y0(t), предлагается проводить дифференцирован ие не сигнала ошибки e(t), а выходного сигнала y(t) (т.е. полагается, что y0(t)=const). Поэтому:
de(t)/dt = d/dt(y0(t) - y(t)) ~= -dy(t)/dt = -(y(n) - y(n-1)) = y(n-1) - y(n).
Цитировать
 
 
0 #2 Alex 12.10.2014 21:13
Цитирую xsmirnov:
В разделе 2.5.1 в последней формуле допущена ошибка (в том числе, в оригинальной документации pdf). Последним слагаемым должно быть Kd*(y(n-1) - y(n)). Так требует теория, так реализовано в самом алгоритме (файл pid.c из архива AVR221.zip)

Если y(n) это ошибка, то написано верно всё, Вы не правы. А если y(n) это не ошибка, то вообще непонятно что там выражается в формуле.
Цитировать
 
 
+2 #1 xsmirnov 28.09.2014 18:18
В разделе 2.5.1 в последней формуле допущена ошибка (в том числе, в оригинальной документации pdf). Последним слагаемым должно быть Kd*(y(n-1) - y(n)). Так требует теория, так реализовано в самом алгоритме (файл pid.c из архива AVR221.zip)
Цитировать
 

Добавить комментарий


Защитный код
Обновить

Top of Page