2016-11-02 76 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在那裏? –