Nareshkumar Rao 7 months ago
parent
commit
917f3dac86
  1. 2
      src/actuators.rs
  2. 104
      src/cli_mode.rs
  3. 2
      src/error.rs
  4. 2
      src/io.rs
  5. 127
      src/main.rs
  6. 2
      src/sensors.rs

2
src/actuators.rs

@ -1,7 +1,7 @@
use crate::{ use crate::{
config::*, config::*,
error::GenericResult,
io::{Relay, RelaySwitchState}, io::{Relay, RelaySwitchState},
GenericResult,
}; };
pub fn switch_lights(relay: &mut Relay, state: RelaySwitchState) -> GenericResult<()> { pub fn switch_lights(relay: &mut Relay, state: RelaySwitchState) -> GenericResult<()> {

104
src/cli_mode.rs

@ -0,0 +1,104 @@
use crate::error::GenericResult;
struct LoopFlags {
exit: bool,
}
fn process_input(input: String) -> GenericResult<LoopFlags> {
todo!()
}
fn cli_loop() -> GenericResult<LoopFlags> {
print!("Enter command: ");
let mut input_string = String::new();
std::io::stdin().read_line(&mut input_string)?;
process_input(input_string)
}
pub fn run_cli() {
'cli_loop: loop {
match cli_loop() {
Ok(loop_flags) => {
if loop_flags.exit {
println!("Leaving CLI");
break 'cli_loop;
}
}
Err(e) => println!("{}", e),
}
}
}
// fn process_command(command: String, program_state: &mut ProgramState) -> GenericResult<bool> {
// let command = command
// .strip_suffix('\n')
// .ok_or("Couldn't strip whitespace")?;
// let args = command.split(' ').collect::<Vec<_>>();
// let main_command = *args.first().ok_or("No command found")?;
// match main_command {
// "water" => toggle_water(&args, program_state)?,
// "fan" => toggle_fan(program_state)?,
// "light" => toggle_light(program_state)?,
// "ana" => analogue_command(&args, program_state)?,
// "exit" => return Ok(true),
// _ => return Err(format!("Main command '{}' invalid", main_command).into()),
// }
// Ok(false)
// }
// fn analogue_command(args: &[&str], program_state: &mut ProgramState) -> GenericResult<()> {
// let pin = args.get(1).ok_or("No pin given")?;
// let pin: u8 = pin.parse()?;
// let adc_target = rppal::i2c::I2c::new()?;
// let mut adc_target =
// Ads1x1x::new_ads1115(adc_target, ads1x1x::SlaveAddr::Alternative(false, false));
// let channel: ChannelSelection = match pin {
// 0 => ChannelSelection::SingleA0,
// 1 => ChannelSelection::SingleA1,
// 2 => ChannelSelection::SingleA2,
// 3 => ChannelSelection::SingleA3,
// _ => ChannelSelection::SingleA0,
// };
// loop {
// let value = block!(adc_target.read(channel)).map_err(|e| format!("{:?}", e))?;
// let value = value as f32;
// let voltage = value / i16::MAX as f32 * 2.048;
// let resistance = (3.3 / voltage - 1.) * 9_700.;
// println!("Value: {}", value);
// println!("resistance: {}", resistance);
// let temp = 1. / ((1. / 298.15) + (1. / 3950. * f32::ln(resistance / 10_000.))) - 273.15;
// println!("Temp: {}", temp);
// //println!("Value of pin {} is: {}", pin, value);
// thread::sleep(Duration::from_millis(2000));
// }
// Ok(())
// }
// fn toggle_water(args: &[&str], program_state: &mut ProgramState) -> GenericResult<()> {
// if let Some(duration) = args.get(1) {
// let duration: u64 = duration.parse()?;
// println!("Turning on water for {} milliseconds", duration);
// program_state.water_pin.set_low();
// thread::sleep(Duration::from_millis(duration));
// program_state.water_pin.set_high();
// } else {
// program_state.water_pin.toggle();
// println!("Toggling water output");
// }
// Ok(())
// }
// fn toggle_light(program_state: &mut ProgramState) -> GenericResult<()> {
// program_state.light_pin.toggle();
// println!("Toggling light output");
// Ok(())
// }
// fn toggle_fan(program_state: &mut ProgramState) -> GenericResult<()> {
// program_state.fan_pin.toggle();
// println!("Toggling fan output");
// Ok(())
// }

2
src/error.rs

@ -1,3 +1,3 @@
use std::error::Error; use std::error::Error;
type GenericResult<T> = Result<T, Box<dyn Error>>;
pub type GenericResult<T> = Result<T, Box<dyn Error>>;

2
src/io.rs

@ -2,7 +2,7 @@ use ads1x1x::{Ads1x1x, ChannelSelection, DynamicOneShot};
use nb::block; use nb::block;
use rppal::gpio::{Gpio, OutputPin}; use rppal::gpio::{Gpio, OutputPin};
use crate::{config::*, GenericResult};
use crate::{config::*, error::GenericResult};
pub fn get_input_voltage(pin: u8) -> GenericResult<f32> { pub fn get_input_voltage(pin: u8) -> GenericResult<f32> {
const ADS1115_DEFAULT_RANGE: f32 = 2.048; const ADS1115_DEFAULT_RANGE: f32 = 2.048;

127
src/main.rs

@ -1,131 +1,20 @@
#![allow(dead_code)] #![allow(dead_code)]
use std::{error::Error, thread, time::Duration};
use ads1x1x::{Ads1x1x, ChannelSelection, DynamicOneShot};
use nb::block;
use rppal::gpio::{Gpio, OutputPin};
use cli_mode::run_cli;
mod actuators; mod actuators;
mod cli_mode;
mod config; mod config;
mod error; mod error;
mod io; mod io;
mod sensors; mod sensors;
type GenericResult<T> = Result<T, Box<dyn Error>>;
struct ProgramState {
water_pin: OutputPin,
light_pin: OutputPin,
fan_pin: OutputPin,
}
fn setup_program_state() -> GenericResult<ProgramState> {
let mut water_pin = Gpio::new()?.get(22)?.into_output();
let mut light_pin = Gpio::new()?.get(17)?.into_output();
let mut fan_pin = Gpio::new()?.get(27)?.into_output();
water_pin.set_high();
light_pin.set_high();
fan_pin.set_high();
Ok(ProgramState {
water_pin,
light_pin,
fan_pin,
})
}
fn main() -> GenericResult<()> {
let mut program_state: ProgramState = setup_program_state()?;
loop {
println!("Enter command: ");
let mut input_string = String::new();
std::io::stdin().read_line(&mut input_string)?;
match process_command(input_string, &mut program_state) {
Ok(to_exit) => {
if to_exit {
break;
}
}
Err(err) => println!("Error: {}", err),
fn main() {
let args = std::env::args().collect::<Vec<_>>();
if let Some(mode) = args.first().map(|x| x.as_str()) {
match mode {
"cli" => run_cli(),
_ => run_cli(),
} }
} }
Ok(())
}
fn process_command(command: String, program_state: &mut ProgramState) -> GenericResult<bool> {
let command = command
.strip_suffix('\n')
.ok_or("Couldn't strip whitespace")?;
let args = command.split(' ').collect::<Vec<_>>();
let main_command = *args.first().ok_or("No command found")?;
match main_command {
"water" => toggle_water(&args, program_state)?,
"fan" => toggle_fan(program_state)?,
"light" => toggle_light(program_state)?,
"ana" => analogue_command(&args, program_state)?,
"exit" => return Ok(true),
_ => return Err(format!("Main command '{}' invalid", main_command).into()),
}
Ok(false)
}
fn analogue_command(args: &[&str], program_state: &mut ProgramState) -> GenericResult<()> {
let pin = args.get(1).ok_or("No pin given")?;
let pin: u8 = pin.parse()?;
let adc_target = rppal::i2c::I2c::new()?;
let mut adc_target =
Ads1x1x::new_ads1115(adc_target, ads1x1x::SlaveAddr::Alternative(false, false));
let channel: ChannelSelection = match pin {
0 => ChannelSelection::SingleA0,
1 => ChannelSelection::SingleA1,
2 => ChannelSelection::SingleA2,
3 => ChannelSelection::SingleA3,
_ => ChannelSelection::SingleA0,
};
loop {
let value = block!(adc_target.read(channel)).map_err(|e| format!("{:?}", e))?;
let value = value as f32;
let voltage = value / i16::MAX as f32 * 2.048;
let resistance = (3.3 / voltage - 1.) * 9_700.;
println!("Value: {}", value);
println!("resistance: {}", resistance);
let temp = 1. / ((1. / 298.15) + (1. / 3950. * f32::ln(resistance / 10_000.))) - 273.15;
println!("Temp: {}", temp);
//println!("Value of pin {} is: {}", pin, value);
thread::sleep(Duration::from_millis(2000));
}
Ok(())
}
fn toggle_water(args: &[&str], program_state: &mut ProgramState) -> GenericResult<()> {
if let Some(duration) = args.get(1) {
let duration: u64 = duration.parse()?;
println!("Turning on water for {} milliseconds", duration);
program_state.water_pin.set_low();
thread::sleep(Duration::from_millis(duration));
program_state.water_pin.set_high();
} else {
program_state.water_pin.toggle();
println!("Toggling water output");
}
Ok(())
}
fn toggle_light(program_state: &mut ProgramState) -> GenericResult<()> {
program_state.light_pin.toggle();
println!("Toggling light output");
Ok(())
}
fn toggle_fan(program_state: &mut ProgramState) -> GenericResult<()> {
program_state.fan_pin.toggle();
println!("Toggling fan output");
Ok(())
} }

2
src/sensors.rs

@ -1,4 +1,4 @@
use crate::{config::*, io::get_input_voltage, GenericResult};
use crate::{config::*, error::GenericResult, io::get_input_voltage};
pub fn get_temperature() -> GenericResult<f32> { pub fn get_temperature() -> GenericResult<f32> {
const THERMISTOR_NOMINAL_RESISTANCE: f32 = 10_000.; const THERMISTOR_NOMINAL_RESISTANCE: f32 = 10_000.;

Loading…
Cancel
Save