Rabu, 22 September 2010

Kontrol PID Motor DC dengan Bahasa C


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.

Stumble
Delicious
Technorati
Twitter
Facebook

15 Comments:

Anonim said...

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

Anonim said...

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

OvisNivicola89 said...

thanks gan.. inpoh nya...

OvisNivicola89 said...

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

fabiana_site said...

Salam...
saya ingin menanyakan terkait program diatas secara lebih rinci..apakah ada alamat email admin yang bisa diajak berdiskusi terkait program diatas??

best regards

zain said...

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

aQieN said...

salam... artikel nya sangat membantu untuk bahan kuliah sistem cerdas, boleh minta program sama penjelasan
please email ke aqiens@yahoo.co.id

Anonim said...

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

Unknown said...

mas mau nanya apakah PID selalu memakai PWM

mohon pencerahannya

Muhammad Fadhli said...

mana file nya gann?di link terrsebut udh error

Rizka Nafi'a said...

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.

Unknown said...

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

Unknown said...

minta link nya min raisjatmiko23@gmail.com trimkasih semoga barokhah

Unknown said...

saya juga mau dong gan
lexyardiansyah7@gmail.com

Unknown said...

in tuk ngontrol kecepatan motor dc ya gan? tapi pake potensiomenter, dibaca adc?

Posting Komentar

Entri Populer

 

Menanam Ilmu Copyright © 2010 LKart Theme is Designed by Lasantha