Hi guys,
Trying to implement a maximum power point tracker (MPPT) in PIC C code. I have attached my code below. The inputs are AN0 to measure voltage of the cell and AN1 to measure the current of the cell, both measure between 0-5V. It is driving the mosfet in a boost converter which is fully working however the problem is that the duty cycle stays at the same value (the initial set value) suggesting the code only runs through once. I am new to programming so any help would be appreciated. I am using a 20MHz oscillator. Also forgot to say im using a thevenin equivalent to replicate the cell at the minute using a 30ohm resistor.
Thanks
Trying to implement a maximum power point tracker (MPPT) in PIC C code. I have attached my code below. The inputs are AN0 to measure voltage of the cell and AN1 to measure the current of the cell, both measure between 0-5V. It is driving the mosfet in a boost converter which is fully working however the problem is that the duty cycle stays at the same value (the initial set value) suggesting the code only runs through once. I am new to programming so any help would be appreciated. I am using a 20MHz oscillator. Also forgot to say im using a thevenin equivalent to replicate the cell at the minute using a 30ohm resistor.
Thanks
Rich (BB code):
#include <p18F258.h>
#include <stdio.h>
unsigned int Panel_Power, Panel_Power_Old;
unsigned char Panel_Voltage, Panel_Current, Panel_Voltage_Old, Panel_Current_Old, DUTY = 0x1F, DUTY_MAX = 0xFA, DUTY_MIN = 0x05, FLAG, i;
#pragma config WDT = OFF
void DELAY(void)
{
unsigned char a;
for (a=0; a<1; a++);
}
void main(void)
{
CCP1CON = 0;
PR2 = 0x3F; /* Set Time Period Value */
TRISCbits.TRISC2=0; /* Set RC2 as an output pin */
T2CON = 0x00; /* No Prescalers Timer 2 OFF */
CCP1CON = 0x0C; /* PWM Mode */
CCPR1L = DUTY;
TMR2 = 0; /* Reset Timer 2 */
T2CONbits.TMR2ON = 1; /* Timer 2 ON */
FLAG = 1; /*shows last increment/decrement*/
for(i=1; i>0; i++){
Panel_Power_Old = Panel_Power; /* Set panel power from previous cycle
TRISAbits.TRISA0 = 1; /* AN0 analog input for voltage*/
ADCON0 = 0x81; /* 10000001 */
ADCON1 = 0x44; /* 01000100*/
DELAY(); /* Gives ADC time to sample*/ ADCON0bits.GO = 1; /* Begin A/D Conversion*/
while(ADCON0bits.DONE == 0); /* Wait for the conversion to end*/
Panel_Voltage = ADRESH; /* Save voltage in ADRESH as Voltage_Step_Number*/
TRISAbits.TRISA1 = 1; /* AN1 analog input for current*/
ADCON0 = 0x89; /* 10001001 1st 2 bits fosc/64 along with ADCON1, next 3 select channel AN1, last digit turns ADC on */
ADCON1 = 0x44; /* 01000100 Left justify, fosc/64, 3 analog inputs, Vref+ = VDD, Vref- = VSS */
DELAY(); /* Gives ADC time to sample*/
ADCON0bits.GO = 1; /* Begin A/D Conversion*/
while(ADCON0bits.DONE == 0); /* Wait for the conversion to end*/
Panel_Current = ADRESH; /* Save current in ADRESH as Panel_Current*/
Panel_Power = Panel_Voltage * Panel_Current;
if(FLAG == 1){ /* Compare Voltage and power to previous and increment/decrement DUTY cycle*/
if(Panel_Power - Panel_Power_Old > 0){
DUTY++;
FLAG = 1;
}
else{
DUTY--;
FLAG = 0;
}
}
if(FLAG == 0){
if(Panel_Power - Panel_Power_Old > 0){
DUTY--;
FLAG = 0;
}
else{
DUTY++;
FLAG = 1;
}
}
if(DUTY > DUTY_MAX){ /* Keeps DC between 0 and 95% */
DUTY = DUTY_MAX;
}
if(DUTY < DUTY_MIN){
DUTY = DUTY_MIN;
}
PIR1bits.TMR2IF = 0; /* clear timer 2 flag*/
while(PIR1bits.TMR2IF==0); /* wait for end of period*/
}
}
Last edited by a moderator: