pemrograman PID loop di C

11

Saya seorang insinyur listrik yang didorong ke dunia digital dan belajar saat saya pergi. Saya memprogram prosesor TI untuk melakukan loop PID (proporsional-integral-turunan) , diilustrasikan oleh diagram ini:

Gambar lingkaran PID dari Wikipedia

Saya juga akan menjelaskannya:

Op-amp umpan balik negatif, dengan terminal non-pembalik ground. Masukan melalui terminal negatif. Loop umpan balik adalah rangkaian seri RE yang paralel dengan resistor dan semua yang paralel dengan penutup.

Adakah yang tahu cara mengubah sirkuit ini menjadi kode C? Saya sedikit keluar dari elemen saya tentang ini dan dapat menggunakan bantuan.

Insinyur Jedi
sumber
Anda dapat menautkan ke gambar dan seseorang akan sangat membantu mengubah tautan itu menjadi gambar yang sebenarnya untuk Anda.
Joachim Sauer
2
Tautan yang Anda poskan sendiri menyediakan pseudocode dasar untuk melakukannya. Jika Anda tidak keberatan C #, berikut adalah contoh dari loop pid di C # .
Neil
1
Neil benar. Saya telah menerapkan hampir persis loop itu di C pada TI. Satu petunjuk: gunakan loop waktu konstan, dan faktor tetap dtke konstanta, daripada melakukan pembagian ekstra dan mengalikan dalam loop.
AShelly
1
@ Neil itu adalah tautan yang saya tambahkan di revisi 2 karena saya tidak tahu apa loop PID itu dan saya curiga banyak yang lain juga tidak.
@MichaelT, ah, maafkan saya.
Neil

Jawaban:

18

Sirkuit

Ok saya baru saja membuat akun di sini ketika saya melihat pertanyaan ini. Saya tidak dapat mengedit pertanyaan Anda sehingga saya dapat memperbaiki kesalahan ketik yang Anda lakukan. Saya percaya Anda berarti rangkaian seri RC secara paralel, bukan RE (jika ya, saya tidak memiliki petunjuk apa pun artinya)

Sepertinya rangkaian analog yang ingin Anda simulasikan menggunakan C terlihat seperti ini

                         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.

(Saya tidak bisa menahan keinginan saya untuk menggambar ini karena saya ingin memberi tahu Anda bagaimana insinyur listrik / elektronik digunakan untuk berkomunikasi di forum dan email tanpa gambar ... dan mengapa kami hanya menyukai kurir, font dengan lebar tetap)

Saya harus mengakui bahwa rangkaian yang Anda gunakan sederhana untuk pengaturan tetapi sangat rumit secara matematis, ketika datang untuk menyetel konstanta Propotional, Integral, dan Derivative dari sistem ke nilai yang diinginkan secara individual, itu tidak mungkin.

Saya sangat menyarankan Anda menggunakan sirkuit dari sumber ini untuk belajar.

Meskipun sedikit membosankan untuk diatur, secara matematis jauh lebih mudah untuk dianalisis karena Anda dapat langsung menghubungkannya ke bentuk matematika standar, bukan yang ideal.

Terakhir, Vout digunakan untuk mengendalikan motor atau apa pun yang perlu dikontrol. Dan Vin adalah tegangan variabel Proses.

Sebelum membuat kaki Anda basah di C (laut?)

Saya berasumsi Anda membaca sinyal dari semacam konverter analog ke digital. Jika tidak maka Anda harus mensimulasikan sinyal sebagai input.

Jika menggunakan formulir standar yang kami miliki,

Dengan asumsi waktu berjalan loop cukup kecil (proses lambat), kita dapat menggunakan fungsi berikut untuk menghitung output,

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

dimana

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.

di mana awalnya 'der' dan 'int' akan menjadi nol. Jika Anda menggunakan fungsi penundaan dalam kode untuk menyetel frekuensi loop untuk mengatakan 1 KHz maka dt Anda akan menjadi 0,001 detik.

Diambil dalam C

Saya menemukan ini kode yang sangat baik untuk PID di C, meskipun tidak mencakup setiap aspek itu, salah satu yang baik yang tetap.

//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.
}

Jika kita mengambil proses yang lambat, maka kita dapat menggunakan frekuensi yang lebih rendah sehingga dt >>> waktu eksekusi kode untuk loop tunggal (jauh lebih besar dari). Dalam kasus seperti itu, kita dapat menghilangkan timer dan menggunakan fungsi penundaan.

D34man
sumber
6
Diagram Ascii mengejutkan saya. +1
l46kok
1
tautan "sumber ini" tidak berfungsi
Ccr
Oh, maaf mendengarnya, sumber yang bagus hilang :(. Nah konsepnya telah dijelaskan dalam contoh kode loop sementara yang telah saya bagikan. Saya tidak berpengalaman tentang cara menangani situasi ini, mungkin beberapa editor dapat memperbaikinya dengan pesan yang tepat. (tautan mati)
D34dman
2
"Sumber ini" yang hilang mungkin tersedia di sini: educypedia.karadimov.info/library/piddocs.pdf
David Suarez