diff --git a/growpi.toml b/growpi.toml index 1c267ba..e83ea8e 100644 --- a/growpi.toml +++ b/growpi.toml @@ -1,21 +1,29 @@ [board_settings] -logic_level = 3.3 +logic_level = 3.299999952316284 [relay_settings] light_pin = 0 fan_pin = 1 water_pump_pin = 2 -relay_gpio_pins = [17, 27, 22, -1] +relay_gpio_pins = [ + 17, + 27, + 22, + -1, +] [soil_moisture_settings] pin = 1 -voltage_100 = 1.417 -voltage_nominal = 2.823 -moisture_nominal = 0.41 +voltage_100 = 1.4170000553131104 +voltage_nominal = 2.822999954223633 +moisture_nominal = 0.4099999964237213 [thermistor_settings] pin = 0 voltage_divider_resistance = 9700.0 nominal_resistance = 10000.0 -nominal_temperature = 298.15 +nominal_temperature = 298.1499938964844 thermal_constant = 3950.0 + +[water_pump_settings] +milliseconds_to_grams = 0.05280999839305878 diff --git a/src/actuators.rs b/src/actuators.rs index abec3cf..76f2593 100644 --- a/src/actuators.rs +++ b/src/actuators.rs @@ -1,3 +1,5 @@ +use std::{thread, time::Duration}; + use crate::{ config::*, error::GenericResult, @@ -27,3 +29,17 @@ pub fn switch_water_pump( ) -> GenericResult<()> { relay.switch(config.relay_settings.water_pump_pin, state, config) } + +pub fn pump_water( + water_mass_g: u16, + relay: &mut Relay, + config: &Configuration, +) -> GenericResult<()> { + let duration_ms = water_mass_g as f32 / config.water_pump_settings.grams_per_millisecond; + let duration_ms = duration_ms.round() as u64; + let duration = Duration::from_millis(duration_ms); + switch_water_pump(relay, RelaySwitchState::On, config)?; + thread::sleep(duration); + switch_water_pump(relay, RelaySwitchState::Off, config)?; + Ok(()) +} diff --git a/src/cli_mode.rs b/src/cli_mode.rs index 47255c6..82d1207 100644 --- a/src/cli_mode.rs +++ b/src/cli_mode.rs @@ -3,6 +3,7 @@ use std::{thread, time::Duration}; use rustyline::{config::Configurer, error::ReadlineError, history::FileHistory}; use crate::{ + actuators, config::Configuration, error::GenericResult, io::{self, get_input_voltage}, @@ -25,6 +26,7 @@ fn process_input( "rel" => command_rel(&args, program_state, config)?, "soil" => command_soil(&args, config)?, "temp" => command_temp(&args, config)?, + "pump" => command_pump(&args, program_state, config)?, "exit" => return Ok(LoopFlags { exit: true }), _ => return Err("Unknown main command".into()), }; @@ -32,6 +34,31 @@ fn process_input( Ok(LoopFlags { exit: false }) } +fn command_pump( + args: &[&str], + program_state: &mut ProgramState, + config: &Configuration, +) -> GenericResult<()> { + let use_grams = args + .get(2) + .map(|arg| matches!(*arg, "grams")) + .unwrap_or(false); + + if use_grams { + let grams: u16 = args.get(1).ok_or("No mass specified.")?.parse()?; + actuators::pump_water(grams, &mut program_state.relay, config)?; + return Ok(()); + } + + let duration_ms: u64 = args.get(1).ok_or("No duration specified.")?.parse()?; + let duration = Duration::from_millis(duration_ms); + actuators::switch_water_pump(&mut program_state.relay, io::RelaySwitchState::On, config)?; + thread::sleep(duration); + actuators::switch_water_pump(&mut program_state.relay, io::RelaySwitchState::Off, config)?; + + Ok(()) +} + fn command_temp(args: &[&str], config: &Configuration) -> GenericResult<()> { let show_loop = args .get(1) diff --git a/src/config.rs b/src/config.rs index f5853f3..4ba95fb 100644 --- a/src/config.rs +++ b/src/config.rs @@ -27,6 +27,11 @@ pub struct SoilMoistureSettings { pub moisture_nominal: f32, } +#[derive(Serialize, Deserialize)] +pub struct WaterPumpSettings { + pub grams_per_millisecond: f32, +} + #[derive(Serialize, Deserialize)] pub struct BoardSettings { pub logic_level: f32, @@ -38,6 +43,7 @@ pub struct Configuration { pub relay_settings: RelaySettings, pub soil_moisture_settings: SoilMoistureSettings, pub thermistor_settings: ThermistorSettings, + pub water_pump_settings: WaterPumpSettings, } impl Configuration { @@ -76,6 +82,9 @@ impl Default for Configuration { nominal_temperature: 298.15, thermal_constant: 3950., }, + water_pump_settings: WaterPumpSettings { + grams_per_millisecond: 0.05281, + }, } } }