diff --git a/src/cli_mode.rs b/src/cli_mode.rs index 9cf98b1..35067c5 100644 --- a/src/cli_mode.rs +++ b/src/cli_mode.rs @@ -1,8 +1,11 @@ +use std::{thread, time::Duration}; + use rustyline::{config::Configurer, error::ReadlineError, history::FileHistory}; use crate::{ error::GenericResult, io::{self, get_input_voltage}, + sensors, }; struct LoopFlags { @@ -15,6 +18,8 @@ fn process_input(input: String, program_state: &mut ProgramState) -> GenericResu match main_command { "ana" => command_ana(&args)?, "rel" => command_rel(&args, program_state)?, + "soil" => command_soil(&args)?, + "temp" => command_temp(&args)?, "exit" => return Ok(LoopFlags { exit: true }), _ => return Err("Unknown main command".into()), }; @@ -22,6 +27,40 @@ fn process_input(input: String, program_state: &mut ProgramState) -> GenericResu Ok(LoopFlags { exit: false }) } +fn command_temp(args: &[&str]) -> GenericResult<()> { + let show_loop = args + .get(1) + .map(|arg| matches!(*arg, "loop")) + .unwrap_or(false); + loop { + let temperature = sensors::get_temperature()?; + println!("Temperature: {}C", temperature); + if show_loop { + break; + } + thread::sleep(Duration::from_secs(1)); + } + Ok(()) +} + +fn command_soil(args: &[&str]) -> GenericResult<()> { + let show_loop = args + .get(1) + .map(|arg| matches!(*arg, "loop")) + .unwrap_or(false); + + loop { + let humidity = sensors::get_soil_moisture()?; + println!("Soil humidity: {}", humidity); + if show_loop { + break; + } + thread::sleep(Duration::from_secs(1)); + } + + Ok(()) +} + fn command_rel(args: &[&str], program_state: &mut ProgramState) -> GenericResult<()> { let pin = args .get(1) @@ -60,8 +99,19 @@ fn command_ana(args: &[&str]) -> GenericResult<()> { .parse::() .map_err(|_| "Not a valid pin number")?; - let voltage = get_input_voltage(pin)?; - println!("Voltage read: {}", voltage); + let show_loop = args + .get(2) + .map(|arg| matches!(*arg, "loop")) + .unwrap_or(false); + + loop { + let voltage = get_input_voltage(pin)?; + println!("Voltage read: {}", voltage); + if show_loop { + break; + } + thread::sleep(Duration::from_secs(1)); + } Ok(()) } diff --git a/src/config.rs b/src/config.rs index b9f84bb..e27a8af 100644 --- a/src/config.rs +++ b/src/config.rs @@ -6,3 +6,8 @@ pub const LIGHT_RELAY_PIN: u8 = 0; pub const FAN_RELAY_PIN: u8 = 1; pub const WATER_PUMP_RELAY_PIN: u8 = 2; pub const RELAY_GPIO_PINS: [Option; 4] = [Some(17), Some(27), Some(22), None]; + +pub const SOIL_MOISTURE_PIN: u8 = 1; +pub const SOIL_MOISTURE_100_VOLTAGE: f32 = 1.417; +pub const SOIL_NOMINAL_MOISTURE: f32 = 0.41; +pub const SOIL_NOMINAL_MOISTURE_VOLTAGE: f32 = 2.823; diff --git a/src/io.rs b/src/io.rs index 7f93adc..3832139 100644 --- a/src/io.rs +++ b/src/io.rs @@ -5,9 +5,12 @@ use rppal::gpio::{Gpio, OutputPin}; use crate::{config::*, error::GenericResult}; pub fn get_input_voltage(pin: u8) -> GenericResult { - const ADS1115_DEFAULT_RANGE: f32 = 2.048; + const ADS1115_DEFAULT_RANGE: f32 = 4.096; + let adc = rppal::i2c::I2c::new()?; let mut adc = Ads1x1x::new_ads1115(adc, ads1x1x::SlaveAddr::Alternative(false, false)); + adc.set_full_scale_range(ads1x1x::FullScaleRange::Within4_096V) + .map_err(|_| "Could not set full scale range")?; let channel: ChannelSelection = match pin { 0 => ChannelSelection::SingleA0, 1 => ChannelSelection::SingleA1, diff --git a/src/sensors.rs b/src/sensors.rs index 608f65b..229747e 100644 --- a/src/sensors.rs +++ b/src/sensors.rs @@ -13,3 +13,15 @@ pub fn get_temperature() -> GenericResult { - 273.15; Ok(temperature) } + +pub fn get_soil_moisture() -> GenericResult { + let voltage = get_input_voltage(SOIL_MOISTURE_PIN)?; + + const VOLTAGE_ZERO_HUMIDITY: f32 = (SOIL_NOMINAL_MOISTURE_VOLTAGE + - SOIL_MOISTURE_100_VOLTAGE * SOIL_NOMINAL_MOISTURE) + / (1. - SOIL_NOMINAL_MOISTURE); + + let humidity = + (voltage - VOLTAGE_ZERO_HUMIDITY) / (SOIL_MOISTURE_100_VOLTAGE - VOLTAGE_ZERO_HUMIDITY); + Ok(humidity) +}