我正在处理一个现有的驱动程序,该程序通过串口控制8位MCU。这个MCU有许多不同版本的固件,但它们都采用了一种通用的方法来确保链路完整性。然而这种方法并不是非常健壮,因此我正在寻找如何修改驱动程序行为以达到最佳效果的想法。
命令是带有行号和校验和的gcode:
N3 T0*57
N4 G92 E0*67
N5 G28*22
N6 G1 F1500.0*82
N7 G1 X2.0 Y2.0 F3000.0*85
N8 G1 X3.0 Y3.0*33
行号必须是连续的(但可以通过M110
重置)。如果校验和不匹配或者行号不连续,固件将返回Resend:nnn
,其中nnn
是最后一个成功的N
加1。 "校验和"非常原始:
// Calc checksum.
byte checksum = 0;
byte count = 0;
while(instruction[count] != '*')
checksum = checksum^instruction[count++];
主要问题在于主要的错误机制是由于中断被挂起导致的丢失字节,从而导致1字节MCU FIFO溢出。实际的串行总线是在FTDI(或类似设备)USB串行桥和MCU之间的几厘米距离内,因此比特错误不太可能发生。我从未观察到来自固件的比特错误。
如您所见,上面的算法将检测到一个丢失的字节,但如果您丢失了两个相同的字节(任何位置!),结果仍将匹配。因此,
F3000.0
(进给速率3000mm / min)可以转换为F30.0
并仍然匹配。此外,字符集非常小,因此某些位永远不会涉及。驱动程序能否做些什么使给定的行更加稳健?
- 添加或删除尾随(甚至前导)零
- 添加或删除空格
- 重新排序单词(
X1 Y1
与Y1 X1
相同) - 添加或删除空格
- 对某些公差内的值进行“不重要”的修改(例如
F2999.9
代替F3000
) - 重置行号以获得给定行的某些特定
N
- 将单个命令分成多个等效命令(例如,假设X = 0,则
G1 X2
变为G1 X1
G1 X2
) - 消除(或添加)不必要的单词(例如
T0
对于大多数命令来说是无意义的,并且如果您发送了F3000
一次,则在未来会隐含它,因此可以选择发送或不发送)
00
,这将(如果一起丢失)是不可见的。