Monday, June 30, 2014

[Finished] Motor Controller Using PID Algorithm and ATMega8535

Teori Singkat Algoritma PID

Untuk memhami algoritma ini, diharapkan pembaca telah memahami dasar-dasar integral, derivative dan control system dengan baik.

PID singkatan dari Proportional, Integral, Derivative, adalah suatu metode kontrol untuk menentukan presisi dari suatu sistem instrumentasi dengan adanya feedback. Ini adalah tipe kontrol paling tua yang ada. Berikut ini adalah diagram sederhana dari PID:

Umumnya algoritma ini menggunakan kombinasi: P(jarang digunakan), PI(sering digunakan), PID(agak sering digunakan) atau PD(paling jarang digunakan).

Penjelasan paling sederhana dari algoritma PID adalah:

Menggunakan algotima PID ibarat kita sedang mengemudikan kendaraan di sebuah jalan tol. Kita ingin berpindah dari satu lajur ke lajur yang lain. Lajur tujuan kita diibaratkan set point. Kita sebagai pengemudi diibaratkan algoritma PID-nya. Kendaraan yang kita gunakan adalah plant/sistem yang kita kontrol. Di dalam sistem pasti ada gangguan(disturbance), hal ini bisa diibaratkan angin samping yang menerpa mobil kita. Sensor yang dipasang pada plant/sistem diibaratkan sebagai mata pengemudi yang memberikan sinyal feedback. Sinyal error adalah selisih set point dikurangi sinyal feedback.

Jika hanya menggunakan gain Proportional(Kp), output yang keluar hanya akan proporsional dengan sinyal error, akan selalu ada steady state error. Jika besarnya gangguan berubah, kita tidak akan pernah sampai ketujuan(set point). Untuk mengatasi masalah ini, dapat ditambahkan gain Integral(Ki), sehingga kombinasinya menjadi PI. Dengan Ki, ibaratnya jika gangguan semakin besar, maka perlawanan yang kita berikan juga semakin besar, karena dengan integral semua nilai error dijumlahkan, sehingga menigkatkan nilai output dan mempercepat perbaikan error. Sebenarnya kita bisa memperbesar nilai Kp, tapi sistem kita menjadi tidak stabil. Gain Derivative(Kd), dengan menambahkan Kd, kita bisa memberikan nilai yang lebih besar pada Kp dan Ki, sehingga sistem kita menjadi lebih cepat dan lebih baik. Hal ini dilakukan dengan melihat laju perubahan(rate of change) sistem. Jika akan terjadi overshoot, Kd akan menarik controller, sehingga tidak overshoot.
------------------------------------------------------------------------------------------------------------
Motor controller

Pengaplikasian PID ini sangat luas, tapi saat ini saya akan mencontohkan dalam sistem motor controller. Secara sederhana motor controller dapat dibuat secara open loop, sehingga user masih aktif mengontrol kecepatan motor dan jika ada error sistem tidak dapat mengkompensasi. Jika dibuat secara closed loop ditambah dengan algoritma PID, maka sistem dapat melakukan kompensasi dengan cepat dan otomatis dan mempertahankan posisi terhadap set point. Berikut ini adalah skematik alatnya:


Komponen elektronik yang digunakan adalah:
  1. uC ATMega8535
  2. X-TAL 4 Mhz
  3. LCD HD44780
  4. Motor driver L298N
  5. Trimpot/Potensio
  6. Motor DC 6V
  7. Rotary Encoder 22 lubang
  8. LED
  9. Push Button
  10. Beberapa capacitor dan resistor

Untuk menentukan nilai set point dengan menggunakan trimpot. Nilai keluaran dari trimpot diubah menjadi digital menggunakan fitur ADC pada ATMega8535. LCD berfungsi untuk menampilkan nilai set point dan nilai feedback dari rotary encoder. Dengan begitu saya membuat perubahan 1 RPM sama dengan perubahan 1 bit dari trimpot. L298N adalah modul dual H-bridge. Dapat digunakan untuk mengendalikan 2 motor DC. Sinyal PWM untuk mengendalikan kecepatan motor didapat dari output timer 2(8 bit) yang terdapat pada PORT D.7. Push button yang terhubung ke PORT D.2 berfungsi untuk mengubah arah putaran motor.

Flowchart program:


Setelah melakukan inisialisasi yang dilakukan  oleh uC adalah melakukan konversi ADC dari nilai keluaran trimpot. Sinyal dari rotary encoder akan men-trigger interrupt 0. Di dalam interrupt service routine(ISR) interrupt 0 akan dihitung banyaknya sinyal dari rotary encoder. Perhitungan sinyal rotary encoder dipakai untuk perhitungan RPM yang dilakukan pada ISR timer 1 setiap 0.1 detik sekali. PID dihitung dalam sebuah subroutine tersendiri. Hasil perhitungan PID akan dikeluarkan sebagai PWM yang dihasilkan dari proses perhitungan timer 2. Setelah menampilkan nilai set point dan hasil bacaan rotary encoder, proses akan kembali ke konversi ADC, begitupun seterusnya. Jika dianalogikan dengan penjelasan PID diatas, nilai dari trimpot menjadi set point, hasil perhitungan RPM menjadi sinyal feedback, hasil perhitungan PID adalah sinyal PWM dan sinyal error adalah pengurangan nilai dari trimpot dengan hasil perhitungan RPM. Coding dilakukan menggunakan AVR Studio.

Berikut  ini adalah potongan-potongan codingnya:

set point dan PWM:
//ngoper nilai potensio ke timer buat ngehasilin PWM motor
potensio = readADC(0);

//menghasilkan sinyal PWM berdasarkan perhitungan PID
OCR2 = hasil_pid;

PID:
float pi_ai_di(void)
{
sp=potensio;
vp=rpm;
timeChange = 0.1;
error = sp-vp;
p_error = error;
i_error += (error*timeChange);
d_error = (error-prev_error) / timeChange;
prev_error = error;

hasil_pid=(0.8*p_error)+(0.005*i_error)+(0.002*d_error);
//return hasil_pid;
}

Konversi ADC:
unsigned char readADC(unsigned char conversionChannel)
{
ADMUX = (1<<ADLAR)|(conversionChannel); //8 bit ADC on channel conversionChannel with AREF as reference
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS0); //ADC Freq=4MHz/32= 125 kHz, meng-enable ADC, mulai konversi
//nunggu ADC selesai bekerja
while(!(ADCSRA & (1<<ADIF)));
return ADCH; //yang dibaca ADCH doang
}

Perhitungan RPM:
ISR(INT1_vect)
{
frekuensi++;
}

ISR(TIMER1_OVF_vect)
{
//reload TCNT1
TCNT1H=0xE7;
TCNT1L=0x96;
rpm=((frekuensi*60)/(0.1*22)); //rumus ngitung rpm = (frekuensi*60)/(Ts*N); N= jumlah pulsa per 1 putaran; Ts= waktu sampling(detik)
pi_ai_di();
frekuensi=0; //ngereset nilai frekuensi
PORTD ^= (1<<4); //toggling LED
}

Bentuk alatnya:
Sisi rotary encoder

Sisi LCD

-----------------------------------------Semoga Bermanfaat-----------------------------------------