Various fixes and improvements
This commit is contained in:
parent
c1ec46305d
commit
8746b51bd5
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue