use std::io::Read;
use std::time::Duration;
const DETECT_RATES: &[u32] = &[115200, 9600, 57600, 38400, 19200, 230400, 460800, 921600, 4800, 2400, 1200];
pub fn auto_detect_baud(port_name: &str) -> Option<u32> {
let mut best_rate: Option<u32> = None;
let mut best_score: f64 = 0.0;
let threshold = 0.70;
for &rate in DETECT_RATES {
match serialport::new(port_name, rate)
.timeout(Duration::from_millis(350))
.open()
{
Ok(mut port) => {
let mut buf = [0u8; 4096];
let mut all_bytes = Vec::new();
let start = std::time::Instant::now();
while start.elapsed() < Duration::from_millis(300) {
match port.read(&mut buf) {
Ok(n) if n > 0 => {
all_bytes.extend_from_slice(&buf[..n]);
}
_ => break,
}
}
if all_bytes.len() >= 4 {
let printable = all_bytes.iter()
.filter(|&&b| b.is_ascii_graphic() || b.is_ascii_whitespace())
.count();
let score = printable as f64 / all_bytes.len() as f64;
if score > best_score {
best_score = score;
best_rate = Some(rate);
}
}
}
Err(_) => continue,
}
}
if best_score >= threshold {
best_rate
} else {
None
}
}