First implementation of MPP tracking

This commit is contained in:
Thomas Kolb 2016-08-07 00:36:15 +02:00
parent 97db9c24db
commit 33dea2e7a4
1 changed files with 115 additions and 19 deletions

View File

@ -22,6 +22,7 @@ enum OperState {
Bootstrap, Bootstrap,
ConvConstVoltage, ConvConstVoltage,
ConvConstCurrent, ConvConstCurrent,
ConvMPP,
Idle, Idle,
}; };
@ -216,6 +217,11 @@ int main(void)
fxp_t pErr, iErr = 0; fxp_t pErr, iErr = 0;
fxp_t controlAction; fxp_t controlAction;
fxp_t power_avg, refPower;
fxp_t testPower[2];
int32_t testPWM[2];
int testPWMStep;
fxp_t PGAIN_CV = fxp_from_float( 50.000f); fxp_t PGAIN_CV = fxp_from_float( 50.000f);
fxp_t IGAIN_CV = fxp_from_float( 0.300f); fxp_t IGAIN_CV = fxp_from_float( 0.300f);
fxp_t IERR_LIMIT = fxp_from_int(4000); fxp_t IERR_LIMIT = fxp_from_int(4000);
@ -228,8 +234,11 @@ int main(void)
fxp_t AVG_FACT = fxp_from_float(0.10f); fxp_t AVG_FACT = fxp_from_float(0.10f);
fxp_t AVG_FACT_INV = fxp_sub(fxp_from_int(1), AVG_FACT); fxp_t AVG_FACT_INV = fxp_sub(fxp_from_int(1), AVG_FACT);
fxp_t maxVoltage = fxp_from_float(12.000f); fxp_t MAX_VOLTAGE = fxp_from_float(12.000f);
fxp_t maxCurrent = fxp_from_float( 5.000f); fxp_t MAX_CURRENT = fxp_from_float( 5.000f);
fxp_t MPP_VOLTAGE_THR = fxp_sub(MAX_VOLTAGE, fxp_from_float(0.500f));
fxp_t MPP_CURRENT_THR = fxp_sub(MAX_CURRENT, fxp_from_float(0.500f));
// Calculated values // Calculated values
//fxp_t VIN_SCALE = fxp_from_float(3.3f * (100 + 12.4f) / 12.4f / 4095.0f); //fxp_t VIN_SCALE = fxp_from_float(3.3f * (100 + 12.4f) / 12.4f / 4095.0f);
@ -300,7 +309,6 @@ int main(void)
fxp_right_align(number, msg, 3, '0'); fxp_right_align(number, msg, 3, '0');
lcd_send_string("L:"); lcd_send_string("L:");
lcd_send_string(msg); lcd_send_string(msg);
lcd_send_string("m");
} }
} }
@ -319,6 +327,8 @@ int main(void)
vout_avg = fxp_add(fxp_mult(vout, AVG_FACT), fxp_mult(vout_avg, AVG_FACT_INV)); vout_avg = fxp_add(fxp_mult(vout, AVG_FACT), fxp_mult(vout_avg, AVG_FACT_INV));
current_avg = fxp_add(fxp_mult(current, AVG_FACT), fxp_mult(current_avg, AVG_FACT_INV)); current_avg = fxp_add(fxp_mult(current, AVG_FACT), fxp_mult(current_avg, AVG_FACT_INV));
power_avg = fxp_mult(vout_avg, current_avg);
// Main FSM // Main FSM
if(timebase_ms >= 1000) { if(timebase_ms >= 1000) {
switch(operState) { switch(operState) {
@ -339,7 +349,7 @@ int main(void)
timer_set_oc_value(TIM1, TIM_CH_BOOTSTRAP, 0); timer_set_oc_value(TIM1, TIM_CH_BOOTSTRAP, 0);
// calculate error values // calculate error values
pErr = fxp_sub(maxVoltage, vout_avg); pErr = fxp_sub(MAX_VOLTAGE, vout_avg);
iErr = fxp_add(iErr, pErr); iErr = fxp_add(iErr, pErr);
// limit integral error range // limit integral error range
@ -366,7 +376,11 @@ int main(void)
nextState = ConvConstVoltage; nextState = ConvConstVoltage;
} }
if(current_avg > maxCurrent) { if(time_in_state > 1000 && vout_avg < MPP_VOLTAGE_THR) {
operState = ConvMPP;
}
if(current_avg > MAX_CURRENT) {
operState = ConvConstCurrent; operState = ConvConstCurrent;
} }
break; break;
@ -376,7 +390,7 @@ int main(void)
timer_set_oc_value(TIM1, TIM_CH_BOOTSTRAP, 0); timer_set_oc_value(TIM1, TIM_CH_BOOTSTRAP, 0);
// calculate error values // calculate error values
pErr = fxp_sub(maxCurrent, current_avg); pErr = fxp_sub(MAX_CURRENT, current_avg);
iErr = fxp_add(iErr, pErr); iErr = fxp_add(iErr, pErr);
// limit integral error range // limit integral error range
@ -403,11 +417,80 @@ int main(void)
nextState = ConvConstCurrent; nextState = ConvConstCurrent;
} }
if(vout_avg > maxVoltage) { if(time_in_state > 1000 && current_avg < MPP_CURRENT_THR) {
operState = ConvMPP;
}
if(vout_avg > MAX_VOLTAGE) {
operState = ConvConstVoltage; operState = ConvConstVoltage;
} }
break; break;
case ConvMPP:
// bootstrap off
timer_set_oc_value(TIM1, TIM_CH_BOOTSTRAP, 0);
if((time_in_state % 50) == 0) {
switch(testPWMStep) {
case 0:
case 2:
pwm = testPWM[testPWMStep/2];
timer_set_oc_value(TIM1, TIM_CH_CONV, pwm);
break;
case 1:
case 3:
testPower[testPWMStep/2] = power_avg;
break;
case 4:
if(testPower[1] > testPower[0]) {
refPower = testPower[1];
pwm = testPWM[1];
} else {
refPower = testPower[0];
pwm = testPWM[0];
}
if(pwm < (CONV_PWM_PERIOD/2) || pwm > CONV_PWM_MAX) {
pwm = 3 * CONV_PWM_PERIOD / 4;
}
timer_set_oc_value(TIM1, TIM_CH_CONV, pwm);
break;
case 5:
// power test is currently idle, but power has changed
// too much.
// -> start a new one.
testPWM[0] = pwm + 7;
testPWM[1] = pwm - 6;
testPWMStep = 0;
break;
default:
testPWMStep = 4;
break;
}
testPWMStep++;
}
if(time_in_state > 1000 && current < CURRENT_THRESHOLD) {
operState = Bootstrap;
nextState = ConvMPP;
}
if(vout_avg > MAX_VOLTAGE) {
operState = ConvConstVoltage;
}
if(current_avg > MAX_CURRENT) {
operState = ConvConstCurrent;
}
break;
case Idle: case Idle:
// disable all PWMs // disable all PWMs
timer_set_oc_value(TIM1, TIM_CH_CONV, 0); timer_set_oc_value(TIM1, TIM_CH_CONV, 0);
@ -426,22 +509,25 @@ int main(void)
time_in_state = 0; time_in_state = 0;
lastState = operState; lastState = operState;
lcd_set_cursor_pos(0, 7); lcd_set_cursor_pos(0, 6);
switch(operState) { switch(operState) {
case Idle: case Idle:
lcd_send_string("ID"); lcd_send_string("IDL");
break; break;
case Bootstrap: case Bootstrap:
lcd_send_string("BS"); lcd_send_string("BTS");
break; break;
case ConvConstCurrent: case ConvConstCurrent:
lcd_send_string("CC"); lcd_send_string("CC ");
break; break;
case ConvConstVoltage: case ConvConstVoltage:
lcd_send_string("CV"); lcd_send_string("CV ");
break;
case ConvMPP:
lcd_send_string("MPP");
break; break;
default: default:
lcd_send_string("??"); lcd_send_string("???");
break; break;
} }
} else { } else {
@ -458,12 +544,6 @@ int main(void)
debug_send_string(msg); debug_send_string(msg);
} }
debug_send_string("\r\n");
debug_send_string("State: ");
fxp_format_int((int)operState, msg);
debug_send_string(msg);
sentSomething = 1; sentSomething = 1;
} }
@ -483,6 +563,22 @@ int main(void)
sentSomething = 1; sentSomething = 1;
} }
if((timebase_ms % 500) == 200) {
debug_send_string("power_avg=");
fxp_format(power_avg, msg, 2);
debug_send_string(msg);
debug_send_string("; ref=");
fxp_format(refPower, msg, 2);
debug_send_string(msg);
debug_send_string("; pwm=");
fxp_format_int(pwm, msg);
debug_send_string(msg);
sentSomething = 1;
}
if(sentSomething) { if(sentSomething) {
debug_send_string("\r\n"); debug_send_string("\r\n");
sentSomething = 0; sentSomething = 0;