First implementation of MPP tracking
This commit is contained in:
parent
97db9c24db
commit
33dea2e7a4
130
src/main.c
130
src/main.c
|
@ -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,13 +509,13 @@ 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 ");
|
||||||
|
@ -440,8 +523,11 @@ int main(void)
|
||||||
case ConvConstVoltage:
|
case ConvConstVoltage:
|
||||||
lcd_send_string("CV ");
|
lcd_send_string("CV ");
|
||||||
break;
|
break;
|
||||||
|
case ConvMPP:
|
||||||
|
lcd_send_string("MPP");
|
||||||
|
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;
|
||||||
|
|
Loading…
Reference in a new issue