Berikut ini contoh program PID dengan menggunakan CodeVisionC Compiler. Jika anda belum memiliki CodeVision maka silahkan mendownload program tersebut. download.
Dalam Program ini saya menggunakan referensi ADC 5V dengan potensiometer. Saya menggunakan mikrokontroller ATMega 8.Secara Garis besar Diagram Blok kontroller PID yakni
#include <stdio.h>
#include <delay.h>
#include <mega8.h>
#define ADC_VREF_TYPE 0x00
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
#define Enki PORTB.0
#define Dir PORTB.1
#define F_Ref read_adc(1)
#define F_sensor read_adc(0)
#define MAXPWM 1000
#define MINPWM 200
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>
unsigned int xcount1;
int PWM;
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
xcount1++;
if ( xcount1 <= PWM ){ Enki=0;}
else { Enki=1;}
if ( xcount1 > MAXPWM ){xcount1 = 0;}
}
// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Reinitialize Timer 1 value
TCNT1H=0xD2;
TCNT1L=0x39;
}
unsigned char det1;
int P, I=0,D, ii, error, error1=0, PWMout,rate;
float Kp, Ki, Kd;
char buf[33];
char buf1[33];
char buf2[33];
char buf3[33];
char buf4[33];
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
det1++;
if (det1>5)
{
Kp = 1;
Ki = 0.05;
Kd = 1;
error = F_Ref - F_sensor;
P = Kp * error;
I = I + error;
I = Ki * I;
D = Kd * (error - error1);
error1 = error;
PWMout = PWMout + P + I + D;
if ( PWMout > 2000 )
{
PWMout = 2000;
}
else if ( PWMout < -2000 )
{
PWMout = -2000;
}
//else {
PWM = (int)(0.4*(float)PWMout) + 600;
// }
//putsf("AA");
//delay_ms(1);
putchar(F_Ref & 0xff);
//putchar((F_Ref >> 8) & 0xFF);
//delay_ms(1);
// putchar(F_sensor & 0xFF);
// putchar((F_sensor >> 8) & 0xFF);
//kirim=0xFF+0xBA+0xFF+0xBA;
//strcopy(kirim,0xFF);
// i=0;
/*
lcd_clear();
lcd_gotoxy(0,0);
sprintf(buf,"%d",F_sensor);
lcd_puts(buf);
lcd_gotoxy(0,1);
sprintf(buf1,"%d",F_Ref);
lcd_puts(buf1);
lcd_gotoxy(5,0);
sprintf(buf2,"%d",error);
lcd_puts(buf2);
lcd_gotoxy(5,1);
sprintf(buf3,"%d",error1);
lcd_puts(buf3);
lcd_gotoxy(10,0);
sprintf(buf4,"%d",P);
lcd_puts(buf4);
lcd_gotoxy(10,1);
sprintf(buf,"%d",I);
lcd_puts(buf);
lcd_gotoxy(15,0);
sprintf(buf1,"%d",D);
lcd_puts(buf1);
det1 = 0;
*/
}
// TCNT2=0xff;
}
unsigned char kPp, kIi, kDd;
// Declare your global variables here
void setPID ()
{
if(PINB.7==0){kPp++;}
if(PINB.6==0){kIi++;}
if(PINB.5==0){kDd++;}
Kp = kPp;
Ki = kIi;
Kd = kDd;
}
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0xFE;
DDRB=0xFF;
// Port C initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTC=0x00;
DDRC=0xFF;
// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=0
PORTD=0x0F;
DDRD=0xFF;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 11.719 kHz
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x01;
TCNT0=0xFF;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 11.719 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0xD2;
TCNT1L=0x39;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 11.719 kHz
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x07;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x45;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC Clock frequency: 187.500 kHz
// ADC Voltage Reference: AREF pin
// ADC High Speed Mode: Off
// ADC Auto Trigger Source: None
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x85;
SFIOR&=0xEF;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x4D;
// LCD module initialization
lcd_init(16);
// Global enable interrupts
#asm("sei")
while (1)
{
lcd_clear();
lcd_gotoxy(0,0);
sprintf(buf,"%d %d %d %d",F_Ref, F_sensor, error, D);
lcd_puts(buf);
lcd_gotoxy(0,1);
sprintf(buf1,"%d %d %d %d",PWM, PWMout, I, P);
lcd_puts(buf1);
delay_ms(100);
};
}
Untuk rangkaian F2V yang saya gunakan nanti saya posting lagi.. Code diatas dapat diunduh disini download
Semoga bermanfaat.
15 Comments:
artikel yng sangat membantu kebetulan saya juga pengen mempraktekkan kontrol PID ini, bisa minta skema rangkaian + program + penjelasan + dll ke email saya (sri_rzk@yahoo.com). Terimakasih
Maaf ga.. mohon donk code di reupload... Link nya udah mati..
klw boleh sih, request ane sama kyk yang diatas ane.. Email:carl.siano@gmail.com
thanks gan.. inpoh nya...
oh ya mau tanya kenapa PID nya dimasukan dalam interupt. kalo gak dimasukan dalam interupt bisa kan.. soalnya saya perah dapet yg langsung pake void PID()>> isinya itung itungan PID nya..
kalo gak salah agan dimasukan ke interupsi timer 2 ya gan..
Salam...
saya ingin menanyakan terkait program diatas secara lebih rinci..apakah ada alamat email admin yang bisa diajak berdiskusi terkait program diatas??
best regards
salam ..artikelnya sangat membantu bagi saya,,,kebetulan Tugas akhir saya mengenai desain algoritma PID dengan bahasa C sbg penegendali kecepatan motor DC, bisa minta skema rangkaian + program + penjelasan + dll ke email saya (zainuddinmuhammad24@yahoo.com). Terimakasih
salam... artikel nya sangat membantu untuk bahan kuliah sistem cerdas, boleh minta program sama penjelasan
please email ke aqiens@yahoo.co.id
nice mas ilmu sharenya...
kebetulan saya buat modul pembelajaran
mas bisa minta rangkaiannya dan simulasinya
kirim e email mas
udinz_12@yahoo.com
terima kasih
mas mau nanya apakah PID selalu memakai PWM
mohon pencerahannya
mana file nya gann?di link terrsebut udh error
maaf min,Link nya sudah mati.klaw bisa minta skema rangkaian, program, penjelasan dll ke email saya (rizkanafia1@gmail.com)untuk referensi belajar. artikelnya menarik,Terimakasih share ilmunya.
min boleh minta listing program AVR nya soalnya di postingan nya LINk nya sudah mati. Minta kirim email nasrul.adi97@gmail.com ya min... terima kasih banyak lagi butuh bangat
minta link nya min raisjatmiko23@gmail.com trimkasih semoga barokhah
saya juga mau dong gan
lexyardiansyah7@gmail.com
in tuk ngontrol kecepatan motor dc ya gan? tapi pake potensiomenter, dibaca adc?
Posting Komentar