From dda42460cd4ac5a33a277097c74e07eac0dc7374 Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Tue, 9 Mar 2021 22:12:05 +0100 Subject: [PATCH] First somewhat working control scheme --- Cargo.toml | 1 + src/application/mod.rs | 16 +++-- src/application/run_profile.rs | 109 +++++++++++++++++++++++++++++++-- src/application/setup.rs | 19 +++--- src/application/styles.rs | 2 + src/main.rs | 3 + src/max6675.rs | 1 + 7 files changed, 135 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a27560d..9993c0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ embedded-graphics = "0.6.2" tinybmp = {version ="0.2.3", features = ["graphics"]} profont = "0.4.0" arrayvec = {version = "0.5.1", default-features = false} +num-traits = {version = "0.2.14", default-features = false } # this lets you use `cargo fix`! [[bin]] diff --git a/src/application/mod.rs b/src/application/mod.rs index 7dcdbc7..1b55567 100644 --- a/src/application/mod.rs +++ b/src/application/mod.rs @@ -1,5 +1,6 @@ use core::mem; use embedded_hal::digital::v2::OutputPin; +use rtt_target::rprintln; use st7735_lcd::Orientation; use stm32f1xx_hal::{ delay::Delay, @@ -57,11 +58,15 @@ pub struct App { styles: Styles, temp_avg: f32, + + heater: gpiob::PB6>, } impl App { pub fn run(mut self) -> ! { - self.read_temperature(); + //self.read_temperature(); + + rprintln!("Application Startup!"); let mut disp = self.get_display(); disp.init(&mut self.delay).unwrap(); @@ -114,12 +119,13 @@ impl App { self.spi = Some(spi); - self.temp_avg = if self.temp_avg > 0.0 { - self.temp_avg * 0.9 + res.unwrap() * 0.1 + /*self.temp_avg = if self.temp_avg > 0.0 { + self.temp_avg * 0.5 + res.unwrap() * 0.5 } else { res.unwrap() - }; + };*/ - self.temp_avg + //self.temp_avg + res.unwrap() } } diff --git a/src/application/run_profile.rs b/src/application/run_profile.rs index 8024847..f50f007 100644 --- a/src/application/run_profile.rs +++ b/src/application/run_profile.rs @@ -1,3 +1,5 @@ +extern crate num_traits; + use arrayvec::ArrayString; use core::fmt::Write; use embedded_graphics::{ @@ -5,6 +7,9 @@ use embedded_graphics::{ primitives::rectangle::Rectangle, primitives::Line, style::PrimitiveStyle, style::PrimitiveStyleBuilder, style::TextStyleBuilder, }; +use embedded_hal::digital::v2::OutputPin; +use num_traits::float::FloatCore; +use rtt_target::rprintln; use stm32f1xx_hal::{ delay::Delay, gpio::{gpioa, gpiob, gpioc, Alternate, Floating, Input, Output, PushPull}, @@ -59,15 +64,39 @@ impl App { write!(&mut target_buf, "{:.2}", preheat_target).expect("Failed to write to buffer"); let mut preheat_ok_count = 0; + let mut last_temp = 0.0; + let mut overshoot = 0.0; - while preheat_ok_count < 5 { + while preheat_ok_count < 10 { let temp = self.read_temperature(); - if temp > preheat_target { + if last_temp == 0.0 { + last_temp = temp; + } + + let delta = temp - last_temp; + + rprintln!("temp: {} delta: {}, overshoot: {}", temp, delta, overshoot,); + + if overshoot < 0.0 { + overshoot = 0.0; + } + + if temp >= preheat_target || temp + delta + overshoot >= preheat_target { + self.heater.set_low().unwrap(); + overshoot -= 0.5; + } else { + self.heater.set_high().unwrap(); + overshoot += 5.0; + } + + if temp > preheat_target - 1.0 && temp < preheat_target + 1.0 { preheat_ok_count += 1; } else { preheat_ok_count = 0; } + last_temp = temp; + let mut temp_buf = ArrayString::<[_; 10]>::new(); // Output `xxx.xx` write!(&mut temp_buf, "{:.2}", temp).expect("Failed to write to buffer"); @@ -89,9 +118,81 @@ impl App { self.release_display(disp); - self.delay.delay_ms(1000u32); + self.delay.delay_ms(250u32); } + self.heater.set_low().ok(); - loop {} + let mut time = 0.0; + let mut last_temp = 0.0; + let period = 0.25; + + loop { + let target_temp = profiles::REFLOW_PROFILES[self.selected_profile].get_temp(time); + let future_temp = + profiles::REFLOW_PROFILES[self.selected_profile].get_temp(time + period); + let temp = self.read_temperature(); + if last_temp == 0.0 { + last_temp = temp; + } + + let delta = temp - last_temp; + + rprintln!( + "temp: {} delta: {}, overshoot: {}, future_temp: {}", + temp, + delta, + overshoot, + future_temp + ); + + if overshoot < 0.0 { + overshoot = 0.0; + } + + if temp >= target_temp || temp + delta + overshoot >= future_temp { + self.heater.set_low().unwrap(); + overshoot -= 0.5; + } else { + self.heater.set_high().unwrap(); + overshoot += 2.0; + } + + last_temp = temp; + + let mut target_buf = ArrayString::<[_; 10]>::new(); + // Output `xxx.xx` + write!(&mut target_buf, "{:.2}", target_temp).expect("Failed to write to buffer"); + + let mut temp_buf = ArrayString::<[_; 10]>::new(); + // Output `xxx.xx` + write!(&mut temp_buf, "{:.2}", temp).expect("Failed to write to buffer"); + + let mut disp = self.get_display(); + let rect = Rectangle::new(Point::new(0, 0), Point::new(160, 10)) + .into_styled(self.styles.fill_black); + rect.draw(&mut disp).unwrap(); + + Text::new(&temp_buf, Point::new(8, 0)) + .into_styled(self.styles.text_red) + .draw(&mut disp) + .unwrap(); + + Text::new(&target_buf, Point::new(80, 0)) + .into_styled(self.styles.text_green) + .draw(&mut disp) + .unwrap(); + + if time <= 320.0 { + let y = 148 - (temp / 2.0) as i32; + Pixel(Point::new((time / 2.0) as i32, y), self.styles.temp_color) + .draw(&mut disp) + .unwrap(); + } + + self.release_display(disp); + + time += period; + self.delay.delay_ms(250u32); + } } } diff --git a/src/application/setup.rs b/src/application/setup.rs index 203e1b1..97017a8 100644 --- a/src/application/setup.rs +++ b/src/application/setup.rs @@ -1,5 +1,6 @@ use embedded_hal::digital::v2::OutputPin; +use rtt_target::rprintln; use stm32f1xx_hal::{ delay::Delay, prelude::*, @@ -28,19 +29,21 @@ pub fn setup(cp: cortex_m::peripheral::Peripherals, dp: stm32::Peripherals) -> A .pclk1(36.mhz()) .freeze(&mut flash.acr); - // Acquire the GPIOC peripheral - let mut gpioc = dp.GPIOC.split(&mut rcc.apb2); - let mut gpioa = dp.GPIOA.split(&mut rcc.apb2); + rprintln!("Clock Setup done"); + + // Acquire the GPIOC peripheral + let mut gpioa = dp.GPIOA.split(&mut rcc.apb2); + let mut gpiob = dp.GPIOB.split(&mut rcc.apb2); + let mut gpioc = dp.GPIOC.split(&mut rcc.apb2); - // Configure gpio C pin 13 as a push-pull output. The `crh` register is passed to the function - // in order to configure the port. For pins 0-7, crl should be passed instead. let led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh); + let mut heater = gpiob.pb6.into_push_pull_output(&mut gpiob.crl); + heater.set_low().unwrap(); + let delay = Delay::new(cp.SYST, clocks); - let gpiob = dp.GPIOB.split(&mut rcc.apb2); let mut afio = dp.AFIO.constrain(&mut rcc.apb2); - let (_, pb3, pb4) = afio.mapr.disable_jtag(gpioa.pa15, gpiob.pb3, gpiob.pb4); let qei = Timer::tim3(dp.TIM3, &clocks, &mut rcc.apb1).qei( @@ -93,5 +96,7 @@ pub fn setup(cp: cortex_m::peripheral::Peripherals, dp: stm32::Peripherals) -> A styles: Styles::new(), temp_avg: 0.0, + + heater: heater, } } diff --git a/src/application/styles.rs b/src/application/styles.rs index d500ea2..afb82b0 100644 --- a/src/application/styles.rs +++ b/src/application/styles.rs @@ -18,6 +18,7 @@ pub struct Styles { pub cancel_box: PrimitiveStyle, pub grid: PrimitiveStyle, pub profile_color: Rgb565, + pub temp_color: Rgb565, } impl Styles { @@ -51,6 +52,7 @@ impl Styles { ), grid: primitive_style!(stroke_color = Rgb565::new(4, 8, 4), stroke_width = 1), profile_color: Rgb565::new(24, 48, 24), + temp_color: Rgb565::RED, } } } diff --git a/src/main.rs b/src/main.rs index 7cc7a3b..54a5ce6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,13 +16,16 @@ mod profiles; #[entry] fn main() -> ! { rtt_init_print!(); + rprintln!("Startup!"); // Get access to the core peripherals from the cortex-m crate let cp = cortex_m::Peripherals::take().unwrap(); // Get access to the device specific peripherals from the peripheral access crate let dp = pac::Peripherals::take().unwrap(); + rprintln!("Application Setup"); let app = application::setup(cp, dp); + rprintln!("Application Setup done"); app.run() } diff --git a/src/max6675.rs b/src/max6675.rs index 093fb04..44b4f5e 100644 --- a/src/max6675.rs +++ b/src/max6675.rs @@ -1,5 +1,6 @@ use embedded_hal::blocking::spi; use embedded_hal::digital::v2::OutputPin; +use rtt_target::rprintln; pub fn read(spi: &mut SPI, nss_pin: &mut NSS) -> Result where