diff --git a/src/main.rs b/src/main.rs index 33d986a..ceaf628 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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; diff --git a/src/switch_control.rs b/src/switch_control.rs index 2964758..8d0c3d4 100644 --- a/src/switch_control.rs +++ b/src/switch_control.rs @@ -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 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 MPPT MPPT 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 MPPT MPPT> PWR_AVG_EXPONENT); + logger.log(data.as_bytes()).unwrap(); } } @@ -205,7 +222,7 @@ pub struct SwitchControl 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 SwitchControl 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 SwitchControl // 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 {