Various fixes and improvements

This commit is contained in:
Thomas Kolb 2023-03-17 19:41:13 +01:00
parent c1ec46305d
commit 8746b51bd5
2 changed files with 32 additions and 15 deletions

View file

@ -71,7 +71,7 @@ const SWITCH_PWM_LIMIT: i32 = 93 * SWITCH_PWM_MAX / 100;
fn convert_adc_measurements(raw: &[u16; 4]) -> (i32, i32, i32)
{
let iout = (raw[0] - raw[1]) as i32 * 3300 * 20 / 4096 / 28; // *20 = division by 50 mΩ shunt
let iout = (raw[0] as i32 - raw[1] as i32) * 3300 * 20 / 4096 / 28; // *20 = division by 50 mΩ shunt
let vout = raw[2] as i32 * 3300 * (47 + 10) / 10 / 4096;
let vin = raw[3] as i32 * 3300 * (10 + 10) / 10 / 4096;
@ -217,7 +217,7 @@ fn main() -> ! {
pac::NVIC::unmask(pac::Interrupt::TIMER_IRQ_0);
}
let mut switchctrl = switch_control::SwitchControl::<1>::new(8000, 100, SWITCH_PWM_LIMIT);
let mut switchctrl = switch_control::SwitchControl::<1>::new(12000, 100, SWITCH_PWM_LIMIT);
// track nano_joules (== nanoVoltAmpereSeconds) generated, for LED flashing
let mut nano_joules: u32 = 0;

View file

@ -1,6 +1,8 @@
use crate::logger::Logger;
use heapless::String;
const PWR_AVG_EXPONENT: i64 = 12;
#[derive(Copy, Clone)]
pub enum ControlMode {
MPPT,
@ -105,6 +107,8 @@ struct MPPT<const INTERVAL: u32, const PERCENT_LOSS_TOLERANCE: i32>
pwm: i32,
increment: i32,
avg_power: i64, // averaged power value
last_power: i32,
peak_power: i32, // highest power seen so far. Decreases over time.
@ -121,8 +125,9 @@ impl<const INTERVAL: u32, const PERCENT_LOSS_TOLERANCE: i32> MPPT<INTERVAL, PERC
update_delay: INTERVAL - 1,
pwm: start_pwm,
increment: 1,
last_power: 0,
avg_power: 0,
peak_power: 0,
last_power: 0,
min_pwm,
max_pwm
}
@ -137,28 +142,38 @@ impl<const INTERVAL: u32, const PERCENT_LOSS_TOLERANCE: i32> MPPT<INTERVAL, PERC
pub fn update(&mut self, vout: i32, iout: i32) -> i32
{
let cur_power = vout * iout;
self.avg_power = self.avg_power - (self.avg_power >> PWR_AVG_EXPONENT) + cur_power as i64;
let avg_power_uw = (self.avg_power >> PWR_AVG_EXPONENT) as i32;
if self.update_delay == 0 {
self.update_delay = INTERVAL - 1;
let cur_power = vout * iout;
// decrease peak power over time
self.peak_power = (998 * (self.peak_power as i64) / 1000) as i32;
self.peak_power = (990 * (self.peak_power as i64) / 1000) as i32;
if cur_power > self.peak_power {
self.peak_power = cur_power;
/*
if avg_power_uw > self.peak_power {
self.peak_power = avg_power_uw;
} else if self.peak_power <= 0 {
self.peak_power = 1;
}
let peak_power_loss_percent = 100 - (100 * cur_power / self.peak_power);
let peak_power_loss_percent = 100 - (100 * avg_power_uw / self.peak_power);
// invert search direction if measured power is significantly lower than previous measurement
if peak_power_loss_percent > PERCENT_LOSS_TOLERANCE {
*/
if avg_power_uw < self.last_power {
//self.peak_power = cur_power; // prevent immediate turnaround
self.increment = -self.increment;
}
self.last_power = avg_power_uw;
// enforce the pwm limits
if self.pwm == self.max_pwm {
self.increment = -1;
@ -166,9 +181,6 @@ impl<const INTERVAL: u32, const PERCENT_LOSS_TOLERANCE: i32> MPPT<INTERVAL, PERC
self.increment = 1;
}
// update the reference power
self.last_power = cur_power;
// step to the next test PWM value
self.pwm += self.increment;
} else {
@ -197,6 +209,11 @@ impl<const INTERVAL: u32, const PERCENT_LOSS_TOLERANCE: i32> MPPT<INTERVAL, PERC
data = String::from(self.peak_power);
logger.log(data.as_bytes()).unwrap();
logger.log(b" Pavg: ").unwrap();
data = String::from(self.avg_power >> PWR_AVG_EXPONENT);
logger.log(data.as_bytes()).unwrap();
}
}
@ -205,7 +222,7 @@ pub struct SwitchControl<const T0: i32>
mode: ControlMode,
mode_switch_delay_counter: u32,
cv_pid: PID<10000, T0>,
mppt: MPPT<20, 3 /* percent loss of peak power */>,
mppt: MPPT<200, 0 /* percent loss of peak power */>,
pwm_max: i32,
pwm_cur: i32,
cv_target: i32,
@ -220,7 +237,7 @@ impl<const T0: i32> SwitchControl<T0>
mode: ControlMode::MPPT,
mode_switch_delay_counter: 0,
cv_pid: PID::<10000, T0>::new(100, 50, 50, cv_target, 0, 0, pwm_max * 10000),
mppt: MPPT::<20, 3>::new(pwm_max/2, 0, pwm_max),
mppt: MPPT::<200, 0>::new(3*pwm_max/4, 0, pwm_max),
pwm_max,
pwm_cur: 0,
cv_target,
@ -250,7 +267,7 @@ impl<const T0: i32> SwitchControl<T0>
// begin MPPT tracking by searching downwards, because the CV PID controller
// probably has pushed the PWM to the upper limit due to too low output
// voltage.
self.mppt.restart(self.pwm_cur, -1);
self.mppt.restart(self.pwm_max * 80 / 100, -1);
}
}
} else {