Saturday 8 February 2020

MPPT CIRCUIT dsPIC30f2010


THREE INTERLEAVED MPPT CIRCUIT dsPIC30f2010 


Maximum Power Point Tracking (MPPT) is one of the best solar charge controller systems that charge a battery with any available sunshine. 
MPPT optimizes the solar panel output due to variation in sun light intensity and voltage and current variation during the changing process. At different irradiance levels of the sun, the solar panel internal resistance changes dynamically. So if a battery is connected directly to the panel and its resistance is high or low than the panel’s internal resistance at MPP, then the power drawn from the panel will be less than its maximum output power. The other available power in the panel will be wasted. Temperature also affects the solar panel output power. Output current usually increases slightly with an increase in temperature, whereas voltage decreases with an increase in temperature. 
MPPT charge controller system understands these changes and environmental factors and then provides the required voltage and current needed to charge the battery.

 MPPT Pix

How MPPT can solve these problems?

MPPT uses MPPT algorithm and a buck-boost converter to convert excess voltage generated from the panel to current and verse versa, hereby extracting and stabilizing the output power of the panel to suit the battery specification. The algorithm is  to monitor and track the solar panels fluctuating power output. This balancing of I x V magnitude is the only way an MPPT can efficiently harness solar energy and charging a battery in the most efficient manner.  

The duty cycle of the MPPT signal is controlled via the algorithm so as to track the changing MPP, the output power is determined by the efficiency of the circuit and usually closely matches the incoming power within 3-10% (typical losses).  


Schematic Circuit Diagram


 

The input voltage and current and output voltage and current are both monitored in the circuit, so the input and output power can be determined. Conclusively, MPPT is employed, to ensure the maximum power is extracted from a solar panel

FUNCTIONS IN THE DSPIC30F2010 MPPT CONTROLLER


1. High efficiency 92%

2. High input voltage (250V PV voltage)

3. High charging current 70A max

4. Battery system is automatically detected by the controller. It can charge 12V, 24V, 36V, 48V, 72V, 96V, 120V, 144V battery system.

5. IGBT Driver system.

6. IGBT protection circuit.

7. Over current protection,

8. PV surge protection

9. Three stages charging algorithm.

10. It can be used to replace other MPPT controller boards.

11. Over temperature protection;

12. Over PV voltage protection

13. Three Interleaved switching topology

13. No programming required since everything is already done for you.

Components Layout and PCB

The Maximum Power Point Tracker (MPPT) circuit is based around a three interleaved synchronous buck-boost circuit topology.

To buy MPPT file, email or whatsapp me on +2348037909203, engrable.ea@gmail.com.

The files contain the following:
·        Complete circuit diagram,
·        Gerber files for the mppt PCBs.
Hex file for programming the microcontroller.


 

SAMPLE SOURCE CODE OF THE DSPIC30F2010 MPPT



THIS IS JUST SAMPLE CODE not complete.

#include "lcdsoft1.h"
#include "functions.h"
#define buzzer    LATDbits.LATD1
#define connect   LATEbits.LATE0
#define fan       LATEbits.LATE2
#define protect   LATEbits.LATE8
#define heat  700
///////////////////////////////////////////////////////////////////////////////////////////
signed int global_duty;
signed int duty_1,duty_2,duty_3;
int switch_condition;
int ad_switch=0;
int factory[15]={1,800,12,12,2500,40,00,148,138,140,120,50,80,88};
int setting[15];
char arr[6];
int speedlimit=20;
struct
{
unsigned int downkey:1;
unsigned int upkey:1;
unsigned int setkey:1;
unsigned int setup:1;
unsigned int gravity:1;
unsigned int loadon:1;
unsigned int solon:1;
unsigned int chrcorrect:1;
unsigned int chon:1;
unsigned int swon:1;
unsigned int pwmopen:1;
unsigned int solraising:1;
unsigned int chrraising:1;
unsigned int fault:1;
unsigned int stop:1;
unsigned int msgrtn:1;
unsigned int pvtemp:1;
unsigned int loadonled:1;
unsigned int bklte:1;
unsigned int faultled:1;

}flags;

unsigned int rising=0;
unsigned int pol=0;
unsigned int *adjust;
unsigned int *ptr;
unsigned int adj;
unsigned int *value;
signed int moov,mwhtmp;
unsigned int pvmax;
unsigned int pvmin;
unsigned int counter,post;
unsigned int fault=0;
unsigned int millisec=0;
unsigned int sec=0;
unsigned int min=0;
unsigned int mintemp=0;
unsigned long hrs=0;
long btv;

///functions
unsigned int pv_sense();

void interrupt_Init(void);

////////////////////////////////////
unsigned int solwattdisp,max_solwatt,chrtemp,chrtmr,batwatts,bat_v,soladc,hes1adc,ttmr,bzdly,batfultemp;
unsigned int soldisp,batdisp,chdisp,bath,batl,batfloat,batful,stmr,setuptmr,kwhtemp,kwh,mwh,lcdtmr,champs,ofset1,ofset2;
unsigned int solvolt,solh,soll,batvolt,batamps,solamps,keyvalue,heatntc,keyavg,ktmr,btmr,exittmr,hes1tmr,batcurtmr;
unsigned int batsel,ampsel,sol_mv,bat_mv,loadonv,loadofv,batnos,solmax,eraser,solhes,bathes,ct2,batcurrent,solampdisp;
signed int batclb,solclb,dummy_cycle;

int flag=0;
long result,result1,ch_amps,chpower;
int batfunction=0;
int solfunction=0;
int pptfunction=0;
int tlimit=500;
unsigned int tmrs=0;
unsigned int defaults,batavg,solavg,*temp;
unsigned int New_PW_Out;
unsigned int mode;
unsigned int code,adchanel;
int dec=0;
int ctmr;
int keytmr=0;
unsigned int track=0;
unsigned int backlite=0;
unsigned int initcount,yaxis;
unsigned int litedly=0;
///////////////////////////////////////////

void beep(int s)
{
char ts;
for(ts=0;ts
{
buzzer=1;
delay_ms(7);
buzzer=0;
delay_ms(7);
}
}

///long chpower();

void pwm_control(void)
{
    if(global_duty > 2390)             
       global_duty = 2390 ;

      if(global_duty<1 font="">
        global_duty=0;

switch(switch_condition)
{
case 0:
duty_1=(global_duty-0);
PDC1=dutycyle_limit(duty_1);

duty_2=(global_duty-820);
PDC2=dutycyle_limit(duty_2);

duty_3=(global_duty-1640);
PDC3=dutycyle_limit(duty_3);

switch_condition=1;
break;

case 1:
duty_1=(global_duty-820);
PDC1=dutycyle_limit(duty_1);

duty_2=(global_duty-1640);
PDC2=dutycyle_limit(duty_2);

duty_3=(global_duty-0);
PDC3=dutycyle_limit(duty_3);

switch_condition=2;
break;

case 2:
duty_1=(global_duty-1640);
PDC1=dutycyle_limit(duty_1);

duty_2=(global_duty-0);
PDC2=dutycyle_limit(duty_2);

duty_3=(global_duty-820);
PDC3=dutycyle_limit(duty_3);

switch_condition=0;
break;
}
}

void __attribute__((__interrupt__, __auto_psv__))_INT0Interrupt(void)
    {
    if(IFS0bits.INT0IF==1)
    {
     IFS0bits.INT0IF == 0;
     __asm__ volatile ("reset");
     OVDCON=0X0000;
     PDC1=PDC2=PDC3=0;
     lcd_init();
   

    }
 
     }


////////////////////////////////////////////////////////////
void __attribute__((__interrupt__, __auto_psv__)) _ADCInterrupt(void)
{
   IFS0bits.ADIF = 0;


batavg+=ADCBUF2;
btmr++;
if(btmr==63)
{
batvolt=batavg>>6;
bat_v=batvolt;
batavg=0;
btmr=0;
switch(batfunction)
{
case 0:
batvolt*=12;
batvolt/=10;

batfunction=1;
bath=(batvolt*batnos)+batclb;
break;

case 1:
batvolt*=10;
batvolt/=10;
batfunction=0;
batl=(batvolt*batnos)+batclb;
batdisp=__builtin_divsd((bath+batl),10);
if(batdisp>batful+30)
{
fault=2;              // battery devider failure
OVDCON=0X0000;
PDC1=PDC2=PDC3=0;
}
break;
}
}


solavg+=ADCBUF0;
stmr++;
if(stmr==63)
{
solvolt=solavg>>6;
soladc=solvolt;
if((signed int)soladc<0 font="">
soladc=0;
solavg=0;
stmr=0;

soldisp=(solvolt*2)+100;

if(soldisp<((130*batnos)+150))//not solar
{
OVDCON=0X0000;
PDC1=PDC2=PDC3=0;
soldisp=0;
flags.solon=0;
litedly++;
if(fault==0)
{
if(litedly>1000)
flags.bklte=0;
}
}

else
{

if(soldisp>2500)
{

fault=1;// solar devider failure
OVDCON=0X0000;
PDC1=PDC2=PDC3=0;
connect =0;
}
//////////////////////////////////////

/////////////////////////////////////
if(fault==0)//&&(protect==!0))

litedly=0;
flags.bklte=1;
connect=1;
flags.solon=1 ;
LCD_DB5=1; //solar led on
//delay_ms(8000);
{
OVDCON= 0b0010101000010101;

}
}

}
}
keyavg+=ADCBUF5;
ktmr++;
if(ktmr==63)
{
ktmr=0;
keyvalue=keyavg>>6;
keyavg=0;

if(flags.setup==0)
{
if((keyvalue<790 amp="" keyvalue="">700))
flags.loadon=1;
else
flags.loadon=0;
}

if(flags.setup==1)
{
litedly=0;
flags.bklte=1;
if(keyvalue>700)
{
exittmr++;
if(exittmr>32000)
__asm__ volatile ("reset");
}
else
exittmr=0;
}
if((keyvalue<900 amp="" keyvalue="">525))
{
litedly=0;
flags.bklte=1;
flags.upkey=1;
return;
}
else
flags.upkey=0;

if((keyvalue<600 amp="" keyvalue="">225))
{
litedly=0;
flags.bklte=1;
flags.downkey=1;
return;
}
else
flags.downkey=0;


if(keyvalue<300 font="">
{
if(flags.setup==0)
{
setuptmr++;
if(setuptmr>100)
{
OVDCON=0X0000;
PDC1=PDC2=PDC3=0;
flags.setup=1;
flags.msgrtn=1;

}
}


flags.setkey=1;
exittmr=0;
}
else
{
setuptmr=0;
flags.setkey=0;
return;
}
}

if(flags.setup==0)
{
heatntc=ADCBUF4;
if(heatntc>1100)

fault=3;          // heat sensor failure

if(heatntc
fan=1;


//*****************************************************************************/
int main()
{
TRISF=0X0000;
TRISE=0X0080;
TRISD=0X0000;
TRISC=0X0000;
TRISB=0XFFFF;
OVDCON=0X0000;
PWMCON1 = 0x0000;
PTCONbits.PTEN = 0;
buzzer=0;
fan=0;
CNPU1bits.CN0PUE=1;
//opto=0;
//change=0;
connect =0;
lcd_init();
flags.setup=0;
flags.stop=1;
flags.pwmopen=0;
global_duty=0;
flags.bklte=1;
pol=0;
memread();


defaults=Eeprom_ReadWord(11);
if(defaults!=50)
{
memwrite();
__asm__ volatile ("reset");
}
init_PWM();

       batnos=setting[0];
      //  batnos=8;
        batsel=batnos*12;
        ampsel=setting[1];
        sol_mv=setting[2];
        bat_mv=setting[3];
        solmax=setting[4];
        batclb = setting[5];
        solclb=setting[6];
        batful = setting[7]*batnos;
        batfloat=setting[8]*batnos;
        loadonv=setting[9]*batnos;
        loadofv=setting[10]*batnos;
        defaults=setting[11];
        kwh=Eeprom_ReadWord(50);
        kwhtemp=kwh;
        ofset1=setting[12];
        ofset2=setting[13];
        // ofset2=494;
        init_PWM();
        interrupt_Init();
        InitADC1();

__delay32(55000);
__delay32(55000);


while(1)
{
    while(PORTEbits.RE8==0)
 backlite=1; 
 flags.faultled=1; 
        printmes(str80,100,1);
        printmes(str81,100,2);
        
}

flags.loadonled=0;
pptfunction=0;
flags.stop=0;
track=1;

   
dec=1;

//printmes(str26,100,1);    // TITLE NAME

pol=1;
temp=&chdisp;
printmes(str14,1,3);    //"CHARGING:     "
pol=0;
dec=1;



dec=1;
temp=&batdisp;
printmes(str12,1,1);      //"BATT VOLT:     V" 


temp=&soldisp;
printmes(str13,1,2);    //"SOLAR VOLT:     "



//temp=&solampdisp;
//printmes(str15,1,3);    //"SOL-AMPS    "
dec=1;
temp=&chpower;
printmes(str09,1,4);    //"TOTAL KW "



if(kwh!=kwhtemp)
Eeprom_WriteWord(50,kwh);

if(flags.setup==1)
{
function_set();
}

if(fault==1)
{

while(1)
{
OVDCON=0X0000;
PDC1=PDC2=PDC3=0;
buzzer=1;
printmes(str22,100,1);    // fault1
if(keyvalue>1000)
{
while(keyvalue>1000);
 __asm__ volatile ("reset");
}
if(keyvalue<1000 p="">
{
while(keyvalue<1000 p="">
 __asm__ volatile ("reset");
}

}
}

if(fault==2)
{
while(1)
{
OVDCON=0X0000;
PDC1=PDC2=PDC3=0;
buzzer=1;
printmes(str23,100,1);    // fault2
if(keyvalue>1000)
{
while(keyvalue>1000);
 __asm__ volatile ("reset");
}
if(keyvalue<1000 p="">
{
while(keyvalue<1000 p="">
 __asm__ volatile ("reset");
}
}
}


if(fault==3)
{
while(1)
{
OVDCON=0X0000;
PDC1=PDC2=PDC3=0;
buzzer=1;
printmes(str24,100,1);    // fault3
if(keyvalue>1000)
{
while(keyvalue>1000);
 __asm__ volatile ("reset");
}
if(keyvalue<1000 p="">
{
while(keyvalue<1000 p="">
 __asm__ volatile ("reset");
}
}
}

if((ofset1==0)||(ofset2==0))
{
OVDCON=0X0000;
PDC1=PDC2=PDC3=0;
fault=4;

while(1)
{
buzzer=1;
printmes(str25,100,1);    // fault4
if(keyvalue>1000)
{
while(keyvalue>1000);
 __asm__ volatile ("reset");
}
if(keyvalue<1000 p="">
{
while(keyvalue<1000 p="">
 __asm__ volatile ("reset");
}
}
}
flags.pwmopen=1;

}
}

//main


///////////////////////////////////////////////////////////////////////////////////////
void InitADC1()
{
_ADON = 1; // Turn ADC ON

ADCON1 = 0x00EC; 
            ADCON3 = 0x0003;
            ADPCFG = 0x0000;
_SMPI=0x07;
_ADCS=0b111111;
_SAMC=0b11111;
_ADRC=1;
ADCON2bits.CHPS=0;
_BUFM=0;
_ALTS=0;
_CH0NA=0;
_CSCNA=1;
ADCSSL=0b111111;
ADCON1bits.ADON=1;
IEC0bits.ADIE = 1;
//interrupt_Init();
}

//////////////////////////////////////////
void delay_ms(unsigned int gs)
{
  while(gs--) 
{
__delay32(55000);

}

}
///////////////////////////////////////////////////////////
void delay_us(unsigned int gs)
{
 while(gs--)
 __delay32(3000);
}
//////////////////////////////////////
int getvalue(int ch)
{

ADCON1bits.DONE=0;
ADCHS = ch;         
ADCON1bits.SAMP = 1;      
__delay32(50);              
ADCON1bits.SAMP = 0;      
while (!ADCON1bits.DONE); 
return ADCBUF1;
}  

void interrupt_Init(void)
{
  
  INTCON2 = 0x0001;     //set up INTO on falling edge of MMA8452Q interrupt output signal 
  IFS0bits.INT0IF = 0;  //clear INT0 interrupt flag
  IEC0bits.INT0IE = 1;  //enable INT0 ISR
  IPC0bits.INT0IP = 7;  //set highest priority
  IFS0bits.CNIF   = 0;
  
}
/////////////////////////////////////////////////////

To buy MPPT file, email or whatsapp me on +2348037909203, engrable.ea@gmail.com.