diff --git a/red/src/main.rs b/red/src/main.rs index 39e799a..e06696a 100644 --- a/red/src/main.rs +++ b/red/src/main.rs @@ -1,5 +1,6 @@ #![warn(rust_2018_idioms)] +use red::printer::gcode::*; use red::printer::Printer; const DEFAULT_TTY: &str = "/dev/ttyUSB0"; @@ -9,8 +10,16 @@ async fn main() -> tokio_serial::Result<()> { let printer = Printer::connect(DEFAULT_TTY).await.unwrap(); printer .printer_in - .send(Box::new(red::printer::M114Command::new())) - .await; - tokio::time::sleep(std::time::Duration::from_secs(15)).await; + .send(Box::new(M114Command::new())) + .await + .unwrap(); + printer + .printer_in + .send(Box::new(G28Command::new(true, true, true))) + .await + .unwrap(); + loop { + tokio::time::sleep(std::time::Duration::from_secs(2)).await; + } Ok(()) } diff --git a/red/src/printer/gcode/g28.rs b/red/src/printer/gcode/g28.rs new file mode 100644 index 0000000..a62e383 --- /dev/null +++ b/red/src/printer/gcode/g28.rs @@ -0,0 +1,39 @@ +use super::*; + +#[derive(Debug)] +pub struct G28Command { + home_x: bool, + home_y: bool, + home_z: bool, +} + +impl G28Command { + pub fn new(home_x: bool, home_y: bool, home_z: bool) -> G28Command { + G28Command { + home_x, + home_y, + home_z, + } + } +} + +impl GcodeCommand for G28Command { + fn command(&self) -> String { + let x = if self.home_x { "X" } else { "" }; + let y = if self.home_y { "Y" } else { "" }; + let z = if self.home_z { "Z" } else { "" }; + format!("G28 {} {} {}", x, y, z) + } + + fn parse_reply(&self, reply: &str) -> Result { + if reply.is_empty() { + Err(GcodeReplyError { + sent_command: self.command(), + parsed_input: reply.to_string(), + problem: "Expected no reply".to_string(), + }) + } else { + Ok(GcodeReply::G28Reply) + } + } +} diff --git a/red/src/printer/gcode.rs b/red/src/printer/gcode/m114.rs similarity index 59% rename from red/src/printer/gcode.rs rename to red/src/printer/gcode/m114.rs index 77135ac..b1ccb80 100644 --- a/red/src/printer/gcode.rs +++ b/red/src/printer/gcode/m114.rs @@ -1,41 +1,10 @@ -use std::fmt::Debug; - +use super::*; use lazy_static::lazy_static; use regex::Regex; -type Result = std::result::Result; - -#[derive(Debug, Clone)] -pub struct GcodeReplyError { - sent_command: String, - parsed_input: String, - problem: String, -} - -impl std::fmt::Display for GcodeReplyError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "Failed to parse response `{}` to command {}: {}", - self.parsed_input, self.sent_command, self.problem - ) - } -} - -pub trait GcodeCommand: Debug + Send { - fn command(&self) -> &str; - fn parse_reply(&self, reply: &str) -> Result; -} - -#[derive(Debug)] -#[derive(Default)] +#[derive(Debug, Default)] pub struct M114Command; -#[derive(Debug)] -pub enum GcodeReply { - M114Reply { x: f64, y: f64, z: f64, e: f64 }, -} - impl M114Command { pub fn new() -> Self { M114Command @@ -43,9 +12,10 @@ impl M114Command { } impl GcodeCommand for M114Command { - fn command(&self) -> &'static str { - "M114" + fn command(&self) -> String { + "M114".into() } + fn parse_reply(&self, reply: &str) -> Result { lazy_static! { static ref RE_SET: Vec = vec![ @@ -65,7 +35,7 @@ impl GcodeCommand for M114Command { .ok_or(GcodeReplyError { parsed_input: reply.to_string(), problem: format!("Failed to match to regex {}", re.as_str()), - sent_command: self.command().to_string(), + sent_command: self.command(), }) }) .collect(); diff --git a/red/src/printer/gcode/mod.rs b/red/src/printer/gcode/mod.rs new file mode 100644 index 0000000..8442e04 --- /dev/null +++ b/red/src/printer/gcode/mod.rs @@ -0,0 +1,35 @@ +mod g28; +mod m114; +pub use g28::G28Command; +pub use m114::M114Command; +use std::fmt::Debug; + +type Result = std::result::Result; + +#[derive(Debug)] +pub enum GcodeReply { + M114Reply { x: f64, y: f64, z: f64, e: f64 }, + G28Reply, +} + +#[derive(Debug, Clone)] +pub struct GcodeReplyError { + sent_command: String, + parsed_input: String, + problem: String, +} + +impl std::fmt::Display for GcodeReplyError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Failed to parse response `{}` to command {}: {}", + self.parsed_input, self.sent_command, self.problem + ) + } +} + +pub trait GcodeCommand: Debug + Send { + fn command(&self) -> String; + fn parse_reply(&self, reply: &str) -> Result; +} diff --git a/red/src/printer/mod.rs b/red/src/printer/mod.rs index 3685550..e46f612 100644 --- a/red/src/printer/mod.rs +++ b/red/src/printer/mod.rs @@ -1,4 +1,4 @@ -mod gcode; +pub mod gcode; use bytes::BytesMut; use futures::sink::SinkExt; @@ -9,7 +9,7 @@ use tokio::sync::mpsc::{channel, Sender}; use tokio_serial::SerialPortBuilderExt; use tokio_util::codec::{Decoder, Encoder}; -pub use gcode::{GcodeCommand, GcodeReply, M114Command}; +pub use gcode::{GcodeCommand, GcodeReply}; #[derive(Debug)] pub enum PrinterError { @@ -52,7 +52,7 @@ impl Printer { printer_tx.send(command_text).await.unwrap(); while let Some(reply) = printer_rx.next().await { let reply = reply.unwrap(); - if reply.contains("Ok") { + if reply.contains("ok") { break; } else { let reply = command.parse_reply(&reply);