2016-11-02 43 views
0

我想要如在说明书中所定义与串行端口进行通信。如何构建字节数组帧并计算校验

ser = serial.Serial("/dev/ttyUSB0", baudrate="115200") 

frame = bytearray([ 
    0x00, 0x00, #frame control (2 bytes) 
    0x00, 0x00, #machine id (2 bytes) 
    0x07, # number of bytes in data field 
    0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, #data field itself 
    0x00, 0x0A #checksum 
]) 

ser.write(frame) 
ser.close() 

该代码执行时没有错误,我正在监视单独的脚本/进程中的同一个端口。该设备应该在收到成功的帧时返回帧。

在本例中,我已手动计算出的校验和,其被定义为:

两字节的校验和,MSB第一,计算在整个帧上从FSN.msb reanging ... DATA [DSIZE] 。校验和由一个简单的16位无符号字节加法计算得出

所以在这种情况下,除了校验和之外,在帧中添加所有东西将等于10,如sum(frame)所示,不添加它。有了它添加,总和为20

的设备上,另一端可能有故障,所以这是一个困难的环境中工作的,但它巨大的,如果任何人都可以审核我的做法这么远?

是生成校验字面上那么简单,还是需要别的东西吗?

+0

到底是什么问题?校验和的作用是保证真实的数据没有被改变。因此,即使不可靠,只要简单地添加所有字节即可担任该角色。通常校验和是有效载荷的散列,这可能更可靠,但更需要更多的计算。 – Guillaume

回答

2

是的,它就是这么简单 - 你通常将填补你的框架,并添加校验和在另一阶段 - 像:

In [73]: frame = bytearray([ 
    ...:  0x00, 0x00, #frame control (2 bytes) 
    ...:  0x00, 0x00, #machine id (2 bytes) 
    ...:  0x07, # number of bytes in data field 
    ...:  0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, #data field itself 
    ...:  ]) 


In [75]: checksum = sum(frame) 

In [76]: frame.extend((checksum // 256, checksum % 256)) 

In [80]: print (", ".join("\\x%02X" % v for v in frame)) 
\x00, \x00, \x00, \x00, \x07, \x01, \x01, \x01, \x00, \x00, \x00, \x00, \x00, \x0A 

现在,请注意一个细节:我添加了2个字节的“自然顺序”中的校验和 - 首先是“MSB”(最高有效字节)。正如你的规格。这应该可行 - 如果不是的话,你可能在其他字段中有一些格式错误。

+1

更好的解决方案因为Python 3.2:'frame.extend(总和(帧).to_bytes(2, '大'))'https://docs.python.org/3/library/stdtypes.html#int.to_bytes – Guillaume

+0

谢谢你,真的很有用。当我打印阵列我得到这个字节组(B '\ X00 \ X00 \ X00 \ X00 \ X07 \ X01 \ X01 \ X01 \ X00 \ X00 \ X00 \ X00 \ X00 \ n')为什么在n上结束了吗? –

+0

啊,我可以看到,这是因为打印将字节直接转换为字符或类似的东西? .join是将它们打印为十六进制的一种方式。仍然有趣的知道一些字节看起来确实的确切原因,并且随机n在那里? –