Switch to a library and move main to an example

This commit is contained in:
Robert Sammelson 2023-05-14 23:07:54 -04:00
parent 559fbbaa12
commit 2a43bf94bd
No known key found for this signature in database
GPG key ID: 92F1F04EDB06B9E9
9 changed files with 21 additions and 389 deletions

View file

@ -3,7 +3,11 @@ use core::fmt;
pub type Result<T> = std::result::Result<T, Error>;
pub trait Obd2Device {
/// Send an OBD command with mode and PID, and get a list of responses (one for each ECU that
/// responds)
fn obd_command(&mut self, mode: u8, pid: u8) -> Result<Vec<Vec<u8>>>;
/// Like [obd_command](Self::obd_command), but for commands that do not require a PID
fn obd_mode_command(&mut self, mode: u8) -> Result<Vec<Vec<u8>>>;
fn obd_command_len<const RESPONSE_LENGTH: usize>(
@ -33,12 +37,15 @@ pub trait Obd2Device {
.map_err(|_| Error::IncorrectResponseLength("count", RESPONSE_COUNT, count))
}
/// Retreive the VIN (vehicle identification number), this should match the one printed on the
/// vehicle
fn get_vin(&mut self) -> Result<String> {
let mut result = self.obd_command(0x09, 0x02)?.pop().unwrap();
result.remove(0); // do not know what this byte is
Ok(String::from_utf8(result)?)
}
/// Get DTC (diagnostic trouble code) metadata for each ECU
fn get_dtc_info(&mut self) -> Result<Vec<DtcsInfo>> {
let result = self.obd_command(0x01, 0x01)?;
@ -65,6 +72,7 @@ pub trait Obd2Device {
.collect()
}
/// Get DTCs for each ECU
fn get_dtcs(&mut self) -> Result<Vec<Vec<Dtc>>> {
let result = self.obd_mode_command(0x03)?;
result
@ -102,11 +110,13 @@ pub trait Obd2Device {
.collect::<Result<Vec<Vec<Dtc>>>>()
}
/// Get the RPM in increments of 0.25
fn get_rpm(&mut self) -> Result<f32> {
let result = self.obd_command_cnt_len::<1, 2>(0x01, 0x0C)?[0];
Ok(f32::from(u16::from_be_bytes(result)) / 4.0)
}
/// Get the speed in km/h
fn get_speed(&mut self) -> Result<u8> {
Ok(self.obd_command_cnt_len::<1, 1>(0x01, 0x0C)?[0][0])
}

View file

@ -39,7 +39,6 @@ impl Obd2BaseDevice for Elm327 {
fn send_serial_cmd(&mut self, data: &str) -> Result<()> {
self.device.write_all(data.as_bytes())?;
self.device.write_all(b"\r\n")?;
// thread::sleep(time::Duration::from_millis(200));
let line = self.get_line()?;
if line.as_ref().is_some_and(|v| v == data.as_bytes()) {
Ok(())

View file

@ -1,6 +1,6 @@
use log::{debug, trace};
use super::{Error, Obd2BaseDevice, Obd2Device, Result};
use super::{device::Obd2BaseDevice, Error, Obd2Device, Result};
#[derive(Default)]
pub struct Obd2<T: Obd2BaseDevice> {

View file

@ -1,10 +1,10 @@
#![forbid(unsafe_code)]
mod accessors;
use accessors::Result;
pub use accessors::{Error, Obd2Device};
mod device;
pub use device::Elm327;
use device::Obd2BaseDevice;
pub mod device;
mod interface;
pub use interface::Obd2;

View file

@ -1,31 +0,0 @@
#![forbid(unsafe_code)]
mod obd2;
use obd2::Obd2Device;
use std::time;
fn main() {
env_logger::init();
let mut device: obd2::Obd2<obd2::Elm327> = obd2::Obd2::default();
println!("VIN: {:?}", device.get_vin());
println!("DTC Info: {:#?}", device.get_dtc_info());
let dtcs = device.get_dtcs();
println!("DTCs: {:?}", dtcs);
if let Ok(dtcs) = dtcs {
for (i, response) in dtcs.iter().enumerate() {
println!("DTCs from response {}:", i);
for dtc in response {
println!(" - {}", dtc);
}
}
}
let state = time::Instant::now();
while state.elapsed() < time::Duration::from_secs(5) {
println!("RPM: {:?}", device.get_rpm());
println!("Speed: {:?}", device.get_speed());
}
}