Regulate heating proportionally
This commit is contained in:
parent
39d65c38e2
commit
95e253efed
127
src/main.rs
127
src/main.rs
|
@ -53,10 +53,15 @@ const HYSTERESIS: u16 = 10;
|
|||
|
||||
const PEAK_TEMPERATURE: u16 = 240;
|
||||
|
||||
const POWER_FACTOR: u16 = 10;
|
||||
const POWER_MAX: u16 = 1000;
|
||||
|
||||
const PREHEAT_TEMPERATURE: u16 = 150;
|
||||
|
||||
const SOAK_TIME: MicrosDurationU64 = MicrosDurationU64::secs(90);
|
||||
|
||||
const TEMPERATURE_BUFF: u16 = 10;
|
||||
|
||||
enum State<'a> {
|
||||
Off,
|
||||
Preheat,
|
||||
|
@ -65,6 +70,14 @@ enum State<'a> {
|
|||
Cooling,
|
||||
}
|
||||
|
||||
fn clamp(value: u16, max: u16) -> u16 {
|
||||
if value > max {
|
||||
max
|
||||
} else {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
fn print_serial<'a, B: UsbBusTrait>(
|
||||
serial: &mut SerialPort<'a, B>,
|
||||
msg: &str,
|
||||
|
@ -231,11 +244,12 @@ fn main() -> ! {
|
|||
button_cooldown.start(0.secs());
|
||||
|
||||
let mut counter = 0;
|
||||
let mut current_temperature = Option::<u16>::None;
|
||||
let mut state = State::Off;
|
||||
let mut heating = false;
|
||||
let mut power = 0;
|
||||
loop {
|
||||
delay.delay_ms(5);
|
||||
counter = (counter + 1) % 100;
|
||||
counter = (counter + 1) % 2000;
|
||||
|
||||
if let Ok(_) = button_cooldown.wait() {
|
||||
let button_pressed = button.is_low().unwrap();
|
||||
|
@ -254,14 +268,58 @@ fn main() -> ! {
|
|||
button_held = button_pressed;
|
||||
}
|
||||
|
||||
if counter == 0 {
|
||||
led.toggle().unwrap();
|
||||
if counter % 50 == 0 {
|
||||
let thermocouple_result = thermocouple.read_temperature(&mut timer.count_down());
|
||||
|
||||
if let Some(mut temperature) = thermocouple_result.as_ref().copied().ok() {
|
||||
temperature = (temperature >> 2) + ((temperature & 2) >> 1);
|
||||
|
||||
match state {
|
||||
State::Off => (),
|
||||
State::Preheat => {
|
||||
if temperature < PREHEAT_TEMPERATURE {
|
||||
heating = true;
|
||||
power = clamp((PREHEAT_TEMPERATURE - temperature + TEMPERATURE_BUFF) * POWER_FACTOR, POWER_MAX);
|
||||
} else {
|
||||
let mut time = timer.count_down();
|
||||
time.start(SOAK_TIME);
|
||||
state = State::Soak(time);
|
||||
}
|
||||
}
|
||||
State::Soak(ref mut time) => match time.wait() {
|
||||
Ok(_) => state = State::Reflow,
|
||||
Err(WouldBlock) => {
|
||||
if temperature < PREHEAT_TEMPERATURE - HYSTERESIS {
|
||||
heating = true;
|
||||
power = clamp((PREHEAT_TEMPERATURE - temperature + TEMPERATURE_BUFF) * POWER_FACTOR, POWER_MAX);
|
||||
} else if temperature > PREHEAT_TEMPERATURE + HYSTERESIS * 2 {
|
||||
state = State::Reflow;
|
||||
} else if temperature > PREHEAT_TEMPERATURE {
|
||||
heating = false;
|
||||
}
|
||||
}
|
||||
Err(_) => state = State::Off,
|
||||
},
|
||||
State::Reflow => {
|
||||
if temperature < PEAK_TEMPERATURE {
|
||||
heating = true;
|
||||
power = clamp((PEAK_TEMPERATURE - temperature + TEMPERATURE_BUFF) * POWER_FACTOR, POWER_MAX);
|
||||
} else {
|
||||
heating = false;
|
||||
|
||||
state = State::Cooling;
|
||||
}
|
||||
}
|
||||
State::Cooling => state = State::Off,
|
||||
}
|
||||
} else {
|
||||
state = State::Off;
|
||||
}
|
||||
|
||||
let mut bytes: [u8; 7] = [32, 32, 32, 32, 194, 176, 67];
|
||||
let text = match thermocouple.read_temperature(&mut timer.count_down()) {
|
||||
let text = match thermocouple_result {
|
||||
Ok(mut temperature) => {
|
||||
temperature >>= 2;
|
||||
current_temperature = Some(temperature);
|
||||
temperature = (temperature >> 2) + ((temperature & 2) >> 1);
|
||||
|
||||
for i in (0..3).rev() {
|
||||
bytes[i] = 48u8 + (temperature % 10) as u8;
|
||||
|
@ -303,48 +361,23 @@ fn main() -> ! {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(temperature) = current_temperature {
|
||||
match state {
|
||||
State::Off => (),
|
||||
State::Preheat => {
|
||||
if temperature < PREHEAT_TEMPERATURE {
|
||||
relay.set_high().unwrap();
|
||||
} else {
|
||||
let mut time = timer.count_down();
|
||||
time.start(SOAK_TIME);
|
||||
state = State::Soak(time);
|
||||
}
|
||||
}
|
||||
State::Soak(ref mut time) => match time.wait() {
|
||||
Ok(_) => state = State::Reflow,
|
||||
Err(WouldBlock) => {
|
||||
if temperature < PREHEAT_TEMPERATURE - HYSTERESIS {
|
||||
relay.set_high().unwrap();
|
||||
} else if temperature > PREHEAT_TEMPERATURE + HYSTERESIS * 2 {
|
||||
state = State::Reflow;
|
||||
} else if temperature > PREHEAT_TEMPERATURE {
|
||||
relay.set_low().unwrap();
|
||||
}
|
||||
}
|
||||
Err(_) => state = State::Off,
|
||||
},
|
||||
State::Reflow => {
|
||||
if temperature < PEAK_TEMPERATURE {
|
||||
relay.set_high().unwrap();
|
||||
} else {
|
||||
relay.set_low().unwrap();
|
||||
|
||||
state = State::Cooling;
|
||||
}
|
||||
}
|
||||
State::Cooling => state = State::Off,
|
||||
}
|
||||
} else {
|
||||
state = State::Off;
|
||||
}
|
||||
|
||||
if let State::Off = state {
|
||||
relay.set_low().unwrap();
|
||||
heating = false;
|
||||
}
|
||||
|
||||
if heating {
|
||||
if counter == 0 {
|
||||
relay.set_high().unwrap();
|
||||
} else if counter >= power {
|
||||
relay.set_low().unwrap();
|
||||
}
|
||||
} else {
|
||||
relay.set_low().unwrap();
|
||||
}
|
||||
|
||||
if counter % 100 == 0 {
|
||||
led.toggle().unwrap();
|
||||
}
|
||||
|
||||
if !usb_dev.poll(&mut [&mut serial]) {
|
||||
|
|
Loading…
Reference in New Issue