программирование петель PID в C

11

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

Изображение PID петли из Википедии

Я также опишу это:

Операционный усилитель с отрицательной обратной связью, с неинвертирующей клеммой, заземленной. Вход через отрицательный терминал. Контур обратной связи представляет собой последовательную цепь RE параллельно с резистором и все это параллельно с заглушкой.

Кто-нибудь есть идеи, как преобразовать эту схему в C-код? Я немного не согласен с этим и могу воспользоваться помощью.

Инженер джедай
источник
Вы можете сделать ссылку на изображение, и кто-то может превратить эту ссылку в реальную для вас картинку.
Йоахим Зауэр
2
Ссылка, которую вы сами разместили, предоставляет базовый псевдокод для этого. Если вы не возражаете против C #, вот пример цикла pid в C # .
Нил
1
Нил прав. Я реализовал почти точно этот цикл в C на TI. Один совет: используйте постоянный цикл времени и делите фиксированное значение dtна константы, вместо того, чтобы делать дополнительные деления и умножения в цикле.
AShelly
1
@Neil, это была ссылка, которую я добавил в редакции 2, потому что я не знал, что такое цикл PID, и я подозревал, что многие другие тоже не знали.
@MichaelT, тогда мои извинения.
Нил

Ответы:

18

Схема

Хорошо, я только что создал учетную запись здесь, когда я увидел этот вопрос. Я не могу отредактировать ваш вопрос, чтобы исправить опечатку, которую вы сделали. Я полагаю, что вы имели в виду параллельную цепь RC вместо RE (если это так, я не имею ни малейшего понятия, что это значит)

Похоже, аналоговая схема, которую вы хотите смоделировать с помощью C выглядит примерно так

                         Ci
                  |------| |--------------|
                  |           Rp          |
                  |----/\/\/\/\-----------|
                  |          Rd    Cd     |
           Rf     |----/\/\/\---| |-------|
Vin o----/\/\/\---|                       |
                  |    |\                 |
                  |    | \                |
                  |----|- \               | 
                       |   \              |
                       |    \-------------|---------o  Vout
                       |    /
                       |   /
                       |+ /
                   ----| /
                  |    |/
                  |
                  |
               ___|___ GND
                _____
                 ___
                  _

LEGEND:
  Vin is the input signal.
  Vout is the Output.
  Rp controls the propotional term ( P in PID) 
  Ci controls the Integral term ( I id PID)
  Rd and Cd controls the differential term ( D in PID)
  Rf is the gain control, which is common to all of the above controllers.

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

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

Я настоятельно рекомендую вам использовать схему из этого источника для изучения.

Хотя это немного утомительно для настройки, математически гораздо проще анализировать, так как вы можете напрямую связать ее со стандартной математической формой вместо идеальной.

Наконец, Vout используется для управления двигателем или чем-либо еще, что необходимо контролировать. А Vin - это переменное напряжение процесса.

Прежде чем промочить ноги в C (море?)

Я предполагаю, что вы читаете сигналы от какого-то аналого-цифрового преобразователя. Если нет, то вам придется смоделировать сигнал в качестве входа.

Если мы используем стандартную форму,

Предполагая, что время выполнения цикла достаточно мало (медленный процесс), мы можем использовать следующую функцию для расчета выхода:

output = Kp * err + (Ki * int * dt) + (Kd * der /dt);

где

Kp = Proptional Constant.
Ki = Integral Constant.
Kd = Derivative Constant.
err = Expected Output - Actual Output ie. error;
int  = int from previous loop + err; ( i.e. integral error )
der  = err - err from previous loop; ( i.e. differential error)
dt = execution time of loop.

где изначально 'der' и 'int' будут равны нулю. Если вы используете функцию задержки в коде для настройки частоты цикла, скажем, 1 кГц, тогда ваш dt будет равен 0,001 секундам.

Рисование в C

Я нашел этот отличный код для PID в C, хотя он не охватывает все его аспекты, тем не менее, он хороший.

//get value of setpoint from user
while(1){
  // reset Timer
  // write code to escape loop on receiving a keyboard interrupt.
  // read the value of Vin from ADC ( Analogue to digital converter).
  // Calculate the output using the formula discussed previously.
  // Apply the calculated outpout to DAC ( digital to analogue converter).
  // wait till the Timer reach 'dt' seconds.
}

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

D34dman
источник
6
Диаграмма Ascii поразила меня. +1
l46kok
1
ссылка "этот источник" не работает
Ccr
О, мне жаль слышать, хороший ресурс потерян :(. Хорошо, концепция была объяснена в примере кода цикла while, которым я поделился. У меня нет опыта, как справиться с этой ситуацией, возможно, некоторые редакторы могут исправить это с помощью собственное сообщение. (мёртвая ссылка)
D34dman
2
Недостающий «этот источник» может быть доступен здесь: educypedia.karadimov.info/library/piddocs.pdf
Дэвид Суарес