use std::{ env, io::{Read, Write}, time::Duration, }; use rand::{rngs::ThreadRng, thread_rng, Rng}; use serial::SerialPort; struct TriangleIterator { points: [(u32, u32); 3], cur_x: u32, cur_y: u32, // used only so we always output the points first i: usize, rng: ThreadRng, } impl TriangleIterator { pub fn new(width: u32, height: u32) -> Self { let p1 = (0, 0); let p2 = (width, 0); let p3 = (width / 2, height); Self { points: [p1, p2, p3], cur_x: p1.0, cur_y: p1.1, i: 0, rng: thread_rng(), } } } impl Iterator for TriangleIterator { type Item = (u32, u32); fn next(&mut self) -> Option<Self::Item> { if self.i < self.points.len() { let ret = self.points[self.i]; self.i += 1; Some(ret) } else { let p = self.points[self.rng.gen_range(0..self.points.len())]; self.cur_x = (self.cur_x + p.0) / 2; self.cur_y = (self.cur_y + p.1) / 2; Some((self.cur_x, self.cur_y)) } } } fn main() -> anyhow::Result<()> { let args: Vec<_> = env::args().collect(); if args.len() != 2 { println!("Usage: {} /dev/tty***", args[0]); return Ok(()); } let mut ser = serial::open(&args[1])?; ser.reconfigure(&|settings| { settings.set_baud_rate(serial::BaudRate::Baud9600)?; Ok(()) })?; ser.set_timeout(Duration::from_secs(3600))?; let triangle = TriangleIterator::new(10300, 7650); write!(&mut ser, "IN; SP 5; VS 40;")?; let mut buf = [0]; for (i, (x, y)) in triangle.enumerate() { println!("{}", i); // wait until our buffer is empty write!(&mut ser, "OA;")?; loop { ser.read_exact(&mut buf)?; if buf == *b"\r" { break; } } write!(&mut ser, "PU {} {}; PD;", x, y)?; } Ok(()) }