програмування циклів 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 іде контролювати двигун або все, що потрібно контролювати. І Він - змінна напруга Процесу.

Перш ніж намочити ноги в С (море?)

Я припускаю, що ви читаєте сигнали від якогось аналогового до цифрового перетворювача. Якщо ні, то вам доведеться імітувати сигнал як вхід.

Якщо ми використовуємо стандартну форму,

Якщо припустити, що час роботи циклу досить малий (повільний процес), ми можемо використовувати наступну функцію для обчислення виходу,

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 секунди.

Малювання в С

Я знайшов цей чудовий код для 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 >>> для одиночного циклу (набагато більше, ніж). У таких випадках ми можемо усунути таймер і використовувати замість нього функцію затримки.


6
Діаграма Ассії підірвала мій розум. +1
l46kok

1
посилання "це джерело" не працює
Ccr

Пробачте, почувши це, гарний ресурс загубився :(. Ну, поняття було пояснено в прикладі коду циклу while, яким я поділився. Я не досвідчений, як вирішити цю ситуацію, можливо, деякі редактори можуть це виправити правильне повідомлення. (мертве посилання)
D34dman

2
Відсутнє "це джерело" може бути доступне тут: educypedia.karadimov.info/library/piddocs.pdf
Девід Суарес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.