Add M154
This commit is contained in:
parent
a5328f5b0b
commit
2a707c0399
9 changed files with 73 additions and 53 deletions
|
@ -62,7 +62,7 @@ pub fn jog(gamepad: &mut Gamepad, mut printer: Printer) -> Result<()> {
|
|||
old_postion.z + distance.z,
|
||||
velocity.into(),
|
||||
)
|
||||
.with_context(|| anyhow!("Sending movement command!"))?;
|
||||
.with_context(|| anyhow!("Failed sending movement command"))?;
|
||||
|
||||
println!(
|
||||
"New position {pos:?}",
|
||||
|
|
|
@ -4,7 +4,7 @@ use anyhow::{Context, Result, anyhow};
|
|||
use futures::never::Never;
|
||||
use red::gamepad::Gamepad;
|
||||
use red::jogger;
|
||||
use red::printer::Printer;
|
||||
use red::printer::{AutoReport, Printer};
|
||||
use std::path::Path;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
|
@ -35,8 +35,10 @@ fn jog() -> Result<()> {
|
|||
let mut gamepad = Gamepad::new().expect("Failed to open gamepad");
|
||||
|
||||
let printer_tty_path = find_printer_port()?;
|
||||
let printer = Printer::connect_to_path(&printer_tty_path)
|
||||
let mut printer = Printer::connect_to_path(&printer_tty_path)
|
||||
.with_context(|| anyhow!("Initializing printer connection"))?;
|
||||
|
||||
printer.set_position_auto_report(AutoReport::EverySeconds(1))?;
|
||||
|
||||
jogger::jog(&mut gamepad, printer).with_context(|| anyhow!("Running jog mode"))
|
||||
}
|
||||
|
|
|
@ -27,14 +27,6 @@ impl GcodeCommand for G0Command {
|
|||
}
|
||||
|
||||
fn parse_reply(&self, reply: &str) -> Result<Self::Reply> {
|
||||
if reply.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(GcodeReplyError {
|
||||
sent_command: self.command(),
|
||||
parsed_input: reply.to_string(),
|
||||
problem: "Expected empty reply".to_string(),
|
||||
})
|
||||
}
|
||||
super::parse_empty_reply(self.command(), reply)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,14 +28,6 @@ impl GcodeCommand for G28Command {
|
|||
}
|
||||
|
||||
fn parse_reply(&self, reply: &str) -> Result<Self::Reply> {
|
||||
if !reply.is_empty() {
|
||||
Err(GcodeReplyError {
|
||||
sent_command: self.command(),
|
||||
parsed_input: reply.to_string(),
|
||||
problem: "Expected no reply".to_string(),
|
||||
})
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
super::parse_empty_reply(self.command(), reply)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,15 +10,7 @@ impl GcodeCommand for G90Command {
|
|||
"G90".into()
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
fn parse_reply(&self, reply: &str) -> Result<Self::Reply> {
|
||||
super::parse_empty_reply(self.command(), reply)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,15 +10,7 @@ impl GcodeCommand for G91Command {
|
|||
"G91".into()
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
fn parse_reply(&self, reply: &str) -> Result<Self::Reply> {
|
||||
super::parse_empty_reply(self.command(), reply)
|
||||
}
|
||||
}
|
||||
|
|
19
red/src/printer/gcode/m154.rs
Normal file
19
red/src/printer/gcode/m154.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
use super::*;
|
||||
|
||||
/// Set up auto reporting of axis positions
|
||||
#[derive(Debug, Default)]
|
||||
pub struct M154Command {
|
||||
/// Seconds between the auto reports. Disable auto report by setting this to 0
|
||||
pub interval: u64,
|
||||
}
|
||||
|
||||
impl GcodeCommand for M154Command {
|
||||
type Reply = ();
|
||||
fn command(&self) -> String {
|
||||
format!("M154 S{}", self.interval)
|
||||
}
|
||||
|
||||
fn parse_reply(&self, reply: &str) -> Result<Self::Reply> {
|
||||
super::parse_empty_reply(self.command(), reply)
|
||||
}
|
||||
}
|
|
@ -15,12 +15,15 @@ mod g90;
|
|||
mod g91;
|
||||
mod m114;
|
||||
mod m997;
|
||||
mod m154;
|
||||
|
||||
pub use g0::G0Command;
|
||||
pub use g28::G28Command;
|
||||
pub use g90::G90Command;
|
||||
pub use g91::G91Command;
|
||||
pub use m114::M114Command;
|
||||
pub use m997::M997Command;
|
||||
pub use m154::M154Command;
|
||||
use std::fmt::Debug;
|
||||
|
||||
type Result<T> = std::result::Result<T, GcodeReplyError>;
|
||||
|
@ -53,3 +56,14 @@ pub trait GcodeCommand: Debug + Send {
|
|||
fn command(&self) -> String;
|
||||
fn parse_reply(&self, reply: &str) -> Result<Self::Reply>;
|
||||
}
|
||||
fn parse_empty_reply(sent_command: String, reply: &str) -> Result<()> {
|
||||
if !reply.is_empty() {
|
||||
Err(GcodeReplyError {
|
||||
sent_command,
|
||||
parsed_input: reply.to_string(),
|
||||
problem: "Expected no reply".to_string(),
|
||||
})
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
pub mod gcode;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use std::panic;
|
||||
pub use gcode::{GcodeCommand};
|
||||
use crate::printer::gcode::{G91Command, M114Command};
|
||||
pub use gcode::GcodeCommand;
|
||||
use regex::Regex;
|
||||
use serialport::SerialPort;
|
||||
use serialport::TTYPort;
|
||||
|
@ -10,17 +10,17 @@ use std::io::Read;
|
|||
use std::io::Write;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::os::fd::{FromRawFd, RawFd};
|
||||
use std::panic;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::mpsc;
|
||||
use std::sync::mpsc::Receiver;
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::sync::mpsc::TryRecvError;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::{io, str};
|
||||
use crate::printer::gcode::{G91Command, M114Command};
|
||||
|
||||
use self::gcode::{G0Command, G28Command, G90Command, GcodeReplyError};
|
||||
use std::sync::mpsc::RecvTimeoutError;
|
||||
use self::gcode::{G0Command, G28Command, G90Command, GcodeReplyError, M154Command};
|
||||
|
||||
/// Recv buffer string will be initialized with this capacity.
|
||||
/// This should fit a simple "OK Pnn Bn" reply for GCODE commands that
|
||||
|
@ -41,6 +41,11 @@ pub enum Port {
|
|||
Path(String),
|
||||
}
|
||||
|
||||
pub enum AutoReport {
|
||||
Disabled,
|
||||
EverySeconds(u64),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PrinterError {
|
||||
IO(io::Error),
|
||||
|
@ -101,10 +106,13 @@ impl Printer {
|
|||
match reply {
|
||||
Ok(reply) => Ok(command
|
||||
.parse_reply(&String::from_utf8(reply).expect("Invalid UTF-8 reply from printer"))
|
||||
.expect("Could not parse reply from printer")),
|
||||
.map_err(|e| PrinterError::GcodeReply(e))?),
|
||||
|
||||
Err(e) => {
|
||||
panic!("Printer didn't reply in time: {}", e)
|
||||
Err(RecvTimeoutError::Timeout) => {
|
||||
Err(PrinterError::NoResponseFromPrinter(command_text))
|
||||
}
|
||||
Err(RecvTimeoutError::Disconnected) => {
|
||||
Err(PrinterError::OutputChannelDropped)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -336,6 +344,15 @@ impl Printer {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Set an interval at which to report the printer position or disable automatic position
|
||||
/// updates
|
||||
pub fn set_position_auto_report(&mut self, report: AutoReport) -> Result<(), PrinterError> {
|
||||
match report {
|
||||
AutoReport::Disabled => self.send_gcode(M154Command { interval: 0 }),
|
||||
AutoReport::EverySeconds(n) => self.send_gcode(M154Command { interval: n }),
|
||||
}
|
||||
}
|
||||
|
||||
/// Background thread that handles direct communication with the printer serial port
|
||||
///
|
||||
/// Parameters
|
||||
|
@ -417,7 +434,7 @@ fn read_line(
|
|||
while Instant::now() < deadline {
|
||||
if let Some(line_break_idx) = already_read.iter().position(|x| *x == b'\n') {
|
||||
let res = Ok(already_read[..line_break_idx].into());
|
||||
*already_read = already_read[line_break_idx+1..].into();
|
||||
*already_read = already_read[line_break_idx + 1..].into();
|
||||
return res;
|
||||
}
|
||||
match port.read(&mut buf) {
|
||||
|
@ -499,7 +516,7 @@ impl Printer {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{Printer, IO_THREAD_TIMEOUT, SERIALPORT_TIMEOUT};
|
||||
use super::{IO_THREAD_TIMEOUT, Printer, SERIALPORT_TIMEOUT};
|
||||
|
||||
#[test]
|
||||
fn test_parse_ok() {
|
||||
|
|
Loading…
Add table
Reference in a new issue