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)
|
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 vout = raw[2] as i32 * 3300 * (47 + 10) / 10 / 4096;
|
||||||
let vin = raw[3] as i32 * 3300 * (10 + 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);
|
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
|
// track nano_joules (== nanoVoltAmpereSeconds) generated, for LED flashing
|
||||||
let mut nano_joules: u32 = 0;
|
let mut nano_joules: u32 = 0;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use crate::logger::Logger;
|
use crate::logger::Logger;
|
||||||
use heapless::String;
|
use heapless::String;
|
||||||
|
|
||||||
|
const PWR_AVG_EXPONENT: i64 = 12;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum ControlMode {
|
pub enum ControlMode {
|
||||||
MPPT,
|
MPPT,
|
||||||
|
@ -105,6 +107,8 @@ struct MPPT<const INTERVAL: u32, const PERCENT_LOSS_TOLERANCE: i32>
|
||||||
|
|
||||||
pwm: i32,
|
pwm: i32,
|
||||||
increment: i32,
|
increment: i32,
|
||||||
|
|
||||||
|
avg_power: i64, // averaged power value
|
||||||
last_power: i32,
|
last_power: i32,
|
||||||
|
|
||||||
peak_power: i32, // highest power seen so far. Decreases over time.
|
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,
|
update_delay: INTERVAL - 1,
|
||||||
pwm: start_pwm,
|
pwm: start_pwm,
|
||||||
increment: 1,
|
increment: 1,
|
||||||
last_power: 0,
|
avg_power: 0,
|
||||||
peak_power: 0,
|
peak_power: 0,
|
||||||
|
last_power: 0,
|
||||||
min_pwm,
|
min_pwm,
|
||||||
max_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
|
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 {
|
if self.update_delay == 0 {
|
||||||
self.update_delay = INTERVAL - 1;
|
self.update_delay = INTERVAL - 1;
|
||||||
|
|
||||||
let cur_power = vout * iout;
|
|
||||||
|
|
||||||
// decrease peak power over time
|
// 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 {
|
} else if self.peak_power <= 0 {
|
||||||
self.peak_power = 1;
|
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
|
// invert search direction if measured power is significantly lower than previous measurement
|
||||||
if peak_power_loss_percent > PERCENT_LOSS_TOLERANCE {
|
if peak_power_loss_percent > PERCENT_LOSS_TOLERANCE {
|
||||||
|
*/
|
||||||
|
|
||||||
|
if avg_power_uw < self.last_power {
|
||||||
//self.peak_power = cur_power; // prevent immediate turnaround
|
//self.peak_power = cur_power; // prevent immediate turnaround
|
||||||
self.increment = -self.increment;
|
self.increment = -self.increment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.last_power = avg_power_uw;
|
||||||
|
|
||||||
// enforce the pwm limits
|
// enforce the pwm limits
|
||||||
if self.pwm == self.max_pwm {
|
if self.pwm == self.max_pwm {
|
||||||
self.increment = -1;
|
self.increment = -1;
|
||||||
|
@ -166,9 +181,6 @@ impl<const INTERVAL: u32, const PERCENT_LOSS_TOLERANCE: i32> MPPT<INTERVAL, PERC
|
||||||
self.increment = 1;
|
self.increment = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the reference power
|
|
||||||
self.last_power = cur_power;
|
|
||||||
|
|
||||||
// step to the next test PWM value
|
// step to the next test PWM value
|
||||||
self.pwm += self.increment;
|
self.pwm += self.increment;
|
||||||
} else {
|
} else {
|
||||||
|
@ -197,6 +209,11 @@ impl<const INTERVAL: u32, const PERCENT_LOSS_TOLERANCE: i32> MPPT<INTERVAL, PERC
|
||||||
|
|
||||||
data = String::from(self.peak_power);
|
data = String::from(self.peak_power);
|
||||||
logger.log(data.as_bytes()).unwrap();
|
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: ControlMode,
|
||||||
mode_switch_delay_counter: u32,
|
mode_switch_delay_counter: u32,
|
||||||
cv_pid: PID<10000, T0>,
|
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_max: i32,
|
||||||
pwm_cur: i32,
|
pwm_cur: i32,
|
||||||
cv_target: i32,
|
cv_target: i32,
|
||||||
|
@ -220,7 +237,7 @@ impl<const T0: i32> SwitchControl<T0>
|
||||||
mode: ControlMode::MPPT,
|
mode: ControlMode::MPPT,
|
||||||
mode_switch_delay_counter: 0,
|
mode_switch_delay_counter: 0,
|
||||||
cv_pid: PID::<10000, T0>::new(100, 50, 50, cv_target, 0, 0, pwm_max * 10000),
|
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_max,
|
||||||
pwm_cur: 0,
|
pwm_cur: 0,
|
||||||
cv_target,
|
cv_target,
|
||||||
|
@ -250,7 +267,7 @@ impl<const T0: i32> SwitchControl<T0>
|
||||||
// begin MPPT tracking by searching downwards, because the CV PID controller
|
// 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
|
// probably has pushed the PWM to the upper limit due to too low output
|
||||||
// voltage.
|
// voltage.
|
||||||
self.mppt.restart(self.pwm_cur, -1);
|
self.mppt.restart(self.pwm_max * 80 / 100, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue