Hi everybody,
My project is MPPT for solar panel but in my project I have to use digital PID controller to controlbrightness(use lrd control ). My input voltage is 5VDC. By using buck converter and PID controller I want to regulate the output voltage to an desirable value (this value is alternate, of course).
This is my code:
#include <16f877a.h>
#include <def_877A.h>
#device *=16 ADC=10
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#use rs232(baud = 9600, xmit = PIN_D0, rcv = PIN_D1)
#INCLUDE <LCD_LIB_4BIT.c>
#use fast_io(C)
#use fast_io(A)
int8 nghin,tram,chuc,donvi,count,duty;
int1 milivolt;
int16 temp,T1,Udat,Uphoi;
float volt,value,Kp,Kd,Ki,T;
//unsigned int Kp,Kd,Ki,T;
signed int16 e0,e1,e2;
signed int16 u0,u1;
unsigned int16 heso0,heso1,heso2;
unsigned char value_pwm;
#define Umax 1023
#int_timer2
//------------
void LCD_Display(void){
value = (float)(((Uphoi)*5)/1023);
value = value*1000;
nghin = value/1000 + 0x30;
temp = (int16)value%1000;
tram = temp/100 + 0x30;
temp = temp%100;
chuc = temp/10 + 0x30;
donvi = temp%10 + 0x30;
LCD_putcmd(0x84);
printf(LCD_putchar,"V=");
Uphoi=read_adc();
volt=Uphoi*(float)5/1023;
if(volt<1) milivolt=1;
else milivolt=0;
volt=volt*1000;
if(!milivolt)
{
lcd_putchar(nghin);
lcd_putchar(".");
}
{lcd_putchar(tram);
lcd_putchar(chuc);
lcd_putchar(donvi);}
if(milivolt) printf(lcd_putchar,"mv");
else printf(lcd_putchar,"v");
}
//----------
void Init_PID(void) {
Kp=0.1;
Ki=0.01;
Kd=0.2;
T=0.001;
heso0=Kp+Kd/T+Ki*T/2;//heso0=(float)Kp+(float)Kd/(float)T+(float)Ki*(float)T/2;
heso1=-Kp -2*Kd/T+Ki*T/2;
heso2=Kd/T;
//chu ki lay mau T=1ms
u0=0;
u1=0;
e0=0;
e1=0;
e2=0;
}
// Chuong trinh dieu khien vi tich phan ti le //
//----------------------------------------------------------------------------//
void PID_light(void){
float tam;
char tam1;
set_adc_channel(3);
delay_us(10);
Udat = read_adc();
set_adc_channel(0);
delay_us(10);
Uphoi = read_adc();
e0=Udat-Uphoi;
u0=u1+(unsigned int16)heso0*e0+(unsigned int16)heso1*e1+(unsigned int16)heso2*e2;
if ((e0>-5) &&( e0<5)){
// u0=u1+(unsigned int16)heso0*e0+(unsigned int16)heso1*e1+(unsigned int16)heso2*e2;
if (u0>Umax){
u0=Umax;
}
if (u0<=0){
u0=0;
}
else if (e0>=5)
{ u0=Umax; }
else if (e0<=-5)
{ u0=0; }
tam=u0;
tam1=(char)tam*1023/Umax;
value_pwm=tam1;
set_pwm1_duty(value_pwm);
u1=u0;
e2=e1;
e1=e0;
}
}
//void pwm_ccp()
//{
//set_pwm1_duty(1023-tempt);
//while (true) {
//Uphoi = read_ADC();
//set_pwm1_duty(1023-Uphoi);
// delay_ms(20);
//}
// }
//-------------
void main()
{
TRISA =0xFF; // PORTA as input
TRISC =0x00; // PORTC as output
TRISD =0x00;
lcd_init();
setup_adc_ports( ALL_ANALOG );
setup_adc(ADC_CLOCK_INTERNAL );
delay_us(10);
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1,5, 1);
LCD_putcmd(0x84);
printf(LCD_putchar,"Uphoi");
delay_us(10);
// Khoi tao cho ngat ngoai
enable_interrupts (INT_EXT);
ext_int_edge(H_TO_L);
enable_interrupts (GLOBAL);//
//pwm_ccp();
while(1)
{
LCD_Display();
delay_us(10);
PID_light(); //
//Delay_ms(20);
}
}
In this code, the output voltage is not stable and lcd incorrect.when design can i opamp before pin AN0?
Anyone can help me? email to me :multiformcode@gmail.com
Thanks so much for your comment!