90 lines
2.2 KiB
Rust
90 lines
2.2 KiB
Rust
mod motor;
|
|
|
|
use crate::motor::{Motor, MotorConfig, MotorPins};
|
|
use anyhow::{Context, anyhow};
|
|
use clap::{Parser, Subcommand};
|
|
use rppal::gpio::Gpio;
|
|
use std::fs;
|
|
use std::path::{Path, PathBuf};
|
|
use std::sync::atomic::{AtomicBool, Ordering};
|
|
|
|
#[derive(Parser)]
|
|
struct Opt {
|
|
#[clap(short, long, default_value = "/etc/motor.toml")]
|
|
config: PathBuf,
|
|
|
|
#[clap(subcommand)]
|
|
command: Command,
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
enum Command {
|
|
/// Reset motor pins, making sure the motor is off
|
|
Reset,
|
|
|
|
/// Turn the motor
|
|
Turn {
|
|
/// The direction to turn
|
|
#[clap(subcommand)]
|
|
direction: Direction,
|
|
|
|
/// The number of full stepper motor steps to turn, if not specified the motor will turn
|
|
/// forever
|
|
#[clap(long, short)]
|
|
steps: Option<usize>,
|
|
},
|
|
}
|
|
|
|
#[derive(Clone, Copy, Subcommand)]
|
|
pub enum Direction {
|
|
Left,
|
|
Right,
|
|
}
|
|
|
|
fn load_config(path: &Path) -> anyhow::Result<MotorConfig> {
|
|
fs::read_to_string(path)
|
|
.context("Failed to open/read file")
|
|
.and_then(|file| toml::from_str(&file).context("Failed to deserialize config"))
|
|
.context(anyhow!("Error opening reading file at {path:?}"))
|
|
}
|
|
|
|
fn main() -> anyhow::Result<()> {
|
|
let opt = Opt::parse();
|
|
let config = load_config(&opt.config)?;
|
|
|
|
let exit = Box::leak(Box::new(AtomicBool::new(false)));
|
|
ctrlc::set_handler(|| {
|
|
exit.store(true, Ordering::Release);
|
|
})
|
|
.expect("Error setting Ctrl-C handler");
|
|
|
|
let gpio = Gpio::new().context("Failed to access GPIOs")?;
|
|
|
|
match &opt.command {
|
|
Command::Reset => {
|
|
let _ = MotorPins::new(&gpio, config.pin_mappings);
|
|
}
|
|
Command::Turn { direction, steps } => {
|
|
let mut motor = Motor::new(&gpio, &config)?;
|
|
for i in 0.. {
|
|
if exit.load(Ordering::Acquire) {
|
|
break;
|
|
}
|
|
|
|
motor.spin_step(*direction);
|
|
if i % 100 == 0 {
|
|
println!("{i}");
|
|
}
|
|
|
|
if let Some(steps) = steps
|
|
&& i >= *steps
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|