use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::Duration;
use log::{debug, error, info};
use simplelog::{ColorChoice, LevelFilter, SimpleLogger, TermLogger, TerminalMode};
use structopt::StructOpt;
use linux_embedded_hal::{Delay, I2cdev};
use sensor_tlv493d::{Mode, Tlv493d};
#[derive(PartialEq, Clone, Debug, StructOpt)]
pub struct Options {
#[structopt(long, default_value = "/dev/i2c-1")]
pub i2c_dev: String,
#[structopt(long, default_value = "400")]
pub i2c_baud_khz: u32,
#[structopt(long, parse(try_from_str=u8_from_hex), default_value = "5e")]
pub i2c_addr: u8,
#[structopt(long, default_value = "1")]
pub freq_hz: u32,
#[structopt(long)]
pub angle: bool,
#[structopt(long, default_value = "info")]
pub log_level: LevelFilter,
}
fn u8_from_hex(s: &str) -> Result<u8, std::num::ParseIntError> {
u8::from_str_radix(s, 16)
}
fn main() -> Result<(), anyhow::Error> {
let running = Arc::new(AtomicBool::new(true));
let opts = Options::from_args();
let log_config = simplelog::ConfigBuilder::new().build();
if let Err(_e) = TermLogger::init(
opts.log_level,
log_config.clone(),
TerminalMode::Mixed,
ColorChoice::Auto,
) {
SimpleLogger::init(opts.log_level, log_config).unwrap();
}
info!(
"Connecting to sensor: 0x{:02x} on bus: {}",
opts.i2c_addr, opts.i2c_dev
);
let i2c = I2cdev::new(opts.i2c_dev)?;
let mut sensor = match Tlv493d::new_sync(i2c, Delay {}, opts.i2c_addr, Mode::Master) {
Ok(s) => s,
Err((e, _)) => {
error!("Failed to connect to sensor: {e}");
return Err(e.into());
}
};
let r = running.clone();
ctrlc::set_handler(move || {
r.store(false, Ordering::SeqCst);
})
.expect("Error setting Ctrl-C handler");
debug!("Running");
while running.load(Ordering::SeqCst) {
if opts.angle {
let v = sensor.read_angle_f32_sync()?;
println!("{:03.04?}", v);
} else {
let v = sensor.read_sync()?;
println!("{:03.04?}", v);
}
std::thread::sleep(Duration::from_secs(1) / opts.freq_hz);
}
sensor.configure_sync(Mode::Disabled, false)?;
Ok(())
}