CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

PID for Buck design

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
thanhtuan



Joined: 03 Sep 2009
Posts: 3
Location: Vietnam

View user's profile Send private message Yahoo Messenger

PID for Buck design
PostPosted: Wed Sep 23, 2009 10:24 pm     Reply with quote

Hi everybody,
My project is MPPT for solar panel but in my project I have to use digital PID controller to control voltage output from buck converter. My input voltage is 12VDC. By using buck converter and PID controller I want to regulate the output voltage to an desirable value (this value is alternate, of course). In my circuit, the feedback voltage is divided by 2. And this is my code:
Code:

////////////////////////////////////////////////////////////////////////////////
/////////////////////***********************************////////////////////////
/////////////*****************************************************//////////////
// Project : TEST DIGITAL PID    v2.1                                         //
// Hardware: PIC 16F877A, LCD, Buck converter (Extra: RS232 connect)          //
// Software: PCM compiler v4.038                                              //
// Date    : 14.09.2009                                                       //
// Author  : Nguyen Thanh Tuan (ENTETE)                                       //
// Status  : Not OK                                                           //
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

#include <16F877A.h>
#include <DEFS_16F877A.h>
#include <def_877A.h>
#device *=16 ADC=10
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#fuses NOWDT NOPROTECT NODEBUG NOBROWNOUT HS
#use fast_io(C)
#use fast_io(A)
#include <stdlib.h>
#include <lcd_lib_4bit.c>

//int1  startPID;   // PID flag bit
int8  count,nghin, tram, chuc, donvi;
signed int16 feedback,error,pre_error,integral,derivative;
long control;
long temp, setpoint, feed;
float Kp, Ki, Kd, P, I, D, dt, value;

#INT_RTCC
void RTCC_IRS()
{
 ++count;
 if(count==10)
  {
    count=0;
    setpoint=115;
    set_adc_channel(0);
    feedback=read_adc();
    error=setpoint-feedback;
    integral+=error;            // Accumulated sum of error
    derivative=error-pre_error; // Derivative of error
    if((error<5)&&(error>-5))
        {
         Kp = 0.0;
         Kd = 0.0;
         Ki = 0.0;
         control = control;     // Don't use PID
           }
      else
       {
         Kp = 8.0;
         Ki = 5.0;
         Kd = 0.0001; // Assign value for Kp, Ki, Kd
           
         P=Kp*error;
         I=Ki*integral*dt;
         D=Kd*derivative/dt;
           
         control=(int16)(P+I+D);
         
         if(control >920)
          {
            control = 800;   // Limit the maximum value control at 90%
           }
         if(control < 100)
          {
            control = 100;   // Limit the minimum value control at 10%
             }
        }
         set_pwm1_duty(control);
         pre_error = error;         // Update error
    }
  }
 
void LCD_Display()   // Need display the value >= 10 ????
{
    value = (float)(2*feed*5)/1024;
    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=");
    LCD_putchar(nghin);
    LCD_putchar(tram);
    LCD_putchar(chuc);
    LCD_putchar(donvi);
    printf(LCD_putchar,"mV");
    delay_ms(1000);
  }

void main()
{
  dt = 0.001;  // Sample time = 1ms = 100us(overflow time)*10 (count)
  control = 0;
 
  derivative = 0;
  integral = 0;
  error = 0;
  Kp = 0.0;
  Kd = 0.0;
  Ki = 0.0;
 
  setup_CCP1(CCP_PWM);                 // Configre for PWM mode
  setup_timer_2(T2_DIV_BY_16,255,1);   // prescale=16, PR2=255, postscale=1
  set_pwm1_duty(0);                    // --> fsw = 78.12 kHz
 
  setup_adc(ADC_CLOCK_INTERNAL);       // Configure ADC
  setup_adc_ports(AN0_AN1_AN3);        //
 
  set_tris_a(0b00011111);              // RA0 -> RA4 as input
  set_tris_c(0x00);                    // Port C as output
 
  LCD_init();                          // Configure for LCD
  LCD_putcmd(0x84);
  printf(LCD_putchar,"Test PID");      // Display project's name
  LCD_putcmd(0xc1);
  printf(LCD_putchar,"Status: NOT OK");//
  delay_ms(2000);
  LCD_putcmd(0x01);
 
  setup_timer_0(RTCC_DIV_2);
  set_timer0(6);                       // T_overflow = 2*(256-6)*0.2us = 100us
  enable_interrupts(INT_RTCC);         // enable interrupts Timer0
  enable_interrupts(GLOBAL);           // enable global interrupts         
 
 while(true)
  {
   //set_adc_channel(0);
   //feed = read_adc();
   //LCD_display();
   }
}

In this code, when I change the setpoint value, the output voltage is not change.
Anyone can help me?
Thanks so much for your comment!
thanhtuan



Joined: 03 Sep 2009
Posts: 3
Location: Vietnam

View user's profile Send private message Yahoo Messenger

PostPosted: Thu Sep 24, 2009 7:29 pm     Reply with quote

Anyone can help me, please?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 24, 2009 8:19 pm     Reply with quote

Take the code out of the #int_rtcc routine, and put it in main in a loop.
Don't use interrupts. Put in printf statements to display intermediate
values. Display the output in a terminal window on your PC.

Disconnect the PIC from the buck converter circuit. Connect a trimpot
to the AN0 pin. Turn the trimpot with your hand. Watch the display
of the values as you turn the trimpot. Look for anything that appears
to be incorrect. This will show you the problem area in your code.

If everything in your code (during the testing given above) is correct,
then connect the external Buck Converter circuits to your PIC again.
The code will still be in a while() loop in main(). Add a delay_ms()
statement to the while() loop, to simulate the #int_rtcc interval.
Add a printf statement after the read_adc() statement. Display the
value read from the ADC. It may not be in the correct range of values.

In other words, simplify the program, display intermediate values, and
trouble-shoot the problem by analyzing the behavior of the program.
thanhtuan



Joined: 03 Sep 2009
Posts: 3
Location: Vietnam

View user's profile Send private message Yahoo Messenger

PostPosted: Thu Sep 24, 2009 8:34 pm     Reply with quote

Thank you for your help, PCM programmer!
I'll do it and reply the result when it's OK.
Thanks again,
zamzam23



Joined: 25 Aug 2010
Posts: 47

View user's profile Send private message

PostPosted: Sat Oct 02, 2010 2:34 am     Reply with quote

What is the result? If you succeeded, can you share with us the full working code? Thanks
MiniMe



Joined: 17 Nov 2009
Posts: 50

View user's profile Send private message

PostPosted: Sat Oct 02, 2010 6:12 am     Reply with quote

I tested and i tried to use this code in design.

From point of view of PID --- WORKS. It takes in 2 values and outputs 1 value. Works like PID should work.

In this code there are no scaled variable limit. Because of that values will overflow, for example from 32 768 to - 32 768.
Scaled means some variables are overgrowing faster... so whole thing is not compensated.

My suggestion use code from " AVR221: Discrete PID controller - Atmel" google it. Its 100 times faster and well done.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group