Nomar记录一段历史
通过串口直接传输 g 代码的问题

打印机的型号未知,现在就拿到了,可能是 arduino mega 上的通用笛卡尔和坡道板上的东西,用马林鱼固件缝合在一起。

我已经使用这里接受的答案来尝试从终端移动这个东西。 如何从 Linux 终端直接将 G 代码发送到打印机?

我第一次尝试访问低级打印机接口看起来像这样:

 ./baud.py <> /dev/ttyACM0 250000 tail -f /dev/ttyACM0 & cat > /dev/ttyACM0

首先很好:我已经输入了 g 代码,打印机执行了它并在我的终端中返回了一条 ok 消息。

然后我关闭并再次打开打印机并重复整个过程,但现在tail -f没有输出任何内容,并且在我运行命令后打印机 LCD 在状态行中显示垃圾。

我还注意到每次访问串行端口时打印机控制器都会重新启动,不确定是否在第一次一切正常时发生。

波特率设置后cat /dev/ttyACM0的输出也cat /dev/ttyACM0 - 状态行中有垃圾而不是标准的“%printername% ready”:

 start echo:Marlin1.0.0 echo: Last Updated: May 20 2017 18:12:04 | Author: (none, default config) Compiled: May 20 2017 echo: Free Memory: 3763 PlannerBufferBytes: 1232 echo:Hardcoded Default Settings Loaded echo:Steps per unit: echo: M92 X80.00 Y80.00 Z3200.00 E97.94 echo:Maximum feedrates (mm/s): echo: M203 X50.00 Y50.00 Z2.50 E25.00 echo:Maximum Acceleration (mm/s2): echo: M201 X750 Y750 Z100 E10000 echo:Acceleration: S=acceleration, T=retract acceleration echo: M204 S500.00 T500.00 echo:Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s) echo: M205 S0.00 T0.00 B20000 X20.00 Z1.00 E5.00 echo:Home offset (mm): echo: M206 X0.00 Y0.00 Z0.00 echo:PID settings: echo: M301 P22.20 I1.08 D114.00 echo:SD init fail echo:Unknown command: "starto" ok echo:Unknown command: "SD init failstartuthor" ok echo:Unknown command: " (none, default config)50.00 Z2.50 E2rBy00.00 Y0.00 Z0.00echo" ok echo:Unknown command: "Unknown command" ok echo:Unknown command: " "starto"own comm" ok echo:Unknown command: "aximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s)echo" ok echo:Unknown command: "PID settings" ok echo:Unknown command: "okechecho" ok

“SD init fail”行以及当传感器数据出现在 LCD 上时出现的所有内容,在 LCD 为空之前有一段延迟。

如果您使用echo "G0 X10" > /dev/ttyACM0类的东西向打印机发送命令,它只会在下一个串行端口访问(并因此重新启动)时执行它们 - 或者根本不执行。

有趣的是,Cura“监视器”选项卡实际上可以操纵插入符号,而 Cura 本身可以打印一般的东西 - 但我希望能够手动完成。

2个回答

我的猜测是一个疯狂的猜测,但从以下方面来看:

 echo:Unknown command: "starto" ok echo:Unknown command: "SD init failstartuthor" ok echo:Unknown command: " (none, default config)50.00 Z2.50 E2rBy00.00 Y0.00 Z0.00echo" ok echo:Unknown command: "Unknown command" ok echo:Unknown command: " "starto"own comm" ok echo:Unknown command: "aximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s)echo" ok echo:Unknown command: "PID settings" ok

看起来您可能将打印机的输出作为自身的输入循环返回。我对您的线路非常怀疑: tail -f /dev/ttyACM0 &因为这似乎表明您在开始监视串行连接后正在尝试在同一终端窗口中执行其他操作。

如果是这种情况,您应该明确地单独的终端( tail -f /dev/ttyACM0 ) 中打开监视器并在不同的终端中提供输入(请注意,您不得使用最后的& )。

最后,您可能希望使用cat >> /dev/ttyACM0而不是cat > /dev/ttyACM0因为您希望在不截断现有流的情况下附加您的命令。

这不是`tail -f /dev/ttyACM0 &` 输出,而是`cat /dev/ttyACM0` 输出。而且是在新打开的终端窗口中,甚至波特率设置在另一个。
@KarashevichB。要么你误读了我,要么你认为命令做的事情与他们所做的不同。 :) `tail - f fname` 将**输出**“fname”的最后一位,并在添加行时继续输出行。 `cat > fname` 将使用您在活动控制台上输入或获取的任何内容作为“fname”的**输入**。请注意,这与 `cat fname` _非常_不同!!
正如您从 `echo:Unknown command: "Unknown command"` 中看到的那样,您的打印机似乎在某些时候收到了自己的响应“Unknown command”作为命令本身。
另外,如果你在它自己的控制台中运行 `tail` 命令,你不想使用最后的 `&` 而你想使用 `>>` 而不是 `>`(参见我的最后一次编辑)。
随便。问题实际上完全不同,默认情况下串口参数设置错误。从这里 https://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c 在我的端口上运行 set_interface_attribs 以某种方式解决了这个问题。不知道我是如何第一次让端口正常工作的,但是很好。

这很奇怪,但我从这里得到了一些代码: https : //stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c ,稍微改变了一下,删除几行,运行它 - 我的端口开始工作得很好。这是完整的代码(当然适用于 Linux)。

我猜那是解决问题的 c_lflag 行。

 #include <asm/termios.h> #include <stropts.h> #include <unistd.h> #include <fcntl.h> #include <string.h> int set_interface_attribs (int fd) { struct termios2 tty; memset (&tty, 0, sizeof tty); ioctl(fd, TCGETS2, &tty); tty.c_cflag&=~CBAUD; tty.c_cflag|=BOTHER; tty.c_ispeed=tty.c_ospeed=250000; tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; tty.c_iflag &= ~IGNBRK; tty.c_lflag = 0; tty.c_oflag = 0; tty.c_cc[VMIN] = 0; tty.c_cc[VTIME] = 5; tty.c_iflag &= ~(IXON | IXOFF | IXANY); tty.c_cflag |= (CLOCAL | CREAD); tty.c_cflag &= ~(PARENB | PARODD); tty.c_cflag &= ~CSTOPB; tty.c_cflag &= ~CRTSCTS; ioctl(fd, TCSETS2, &tty); return 0; } int main() { int fd=open("/dev/ttyACM0",O_RDWR|O_NOCTTY|O_SYNC); set_interface_attribs(fd); close(fd); return 0; }
哦,在不知道它做什么的情况下运行代码的奇迹! ;)

随机文章