2016-08-10 4 views
0

現在、RS485経由で電気メーターに接続しようとしています。 これまでのところかなりうまくいきましたが、メーターがRS485回線に書き戻している内容を読むのに問題があることを除けば、16進バイトの正しい解釈が浮動小数点に変換されます

私はDocklightと製造元の内部プログラマで読むことができるので、電気計器のデータは正しいことを知っています。

私の唯一の問題は、私が戻ってくる16進バイトの変換です。私は

>>> b'\x01\x03\x04Ce/\xec\xe2' 

を受け付けております

これは、8または9進バイトである必要があります。 は、私はこの問題は、それが、私ので、非16進数で、さらにそれを変換することはできませんwhereever Pythonは「ASCII」でそれを解釈することであるように思わ

>>> b'\x01\x03\x04\x43\x67\x81\xEC\x43\x68' 

のようなものを受け取ることを期待しています。 そして、私は反対側から見たときに私が手にエラーが

>>> binascii.Error: Non-hexadecimal digit found` 

同等です。 私は

だから私が言うことができるどのようにそれを印刷するとき

>>> bytearray(b'\x01\x03J8\x00\x02S\xde') 

として表示され

>>> data=bytearray([0x01,0x03,0x4A,0x38,0x00,0x02,0x53,0xDE]) 

を送信していますのpython-3、私は8進バイトではなく、いくつかを見てみたいです彼が自動的に作った解釈?私は、一度あなたがどこを探したらいいのか分かりにくい何かに行方不明と信じています。

バイト4,5,6,7をfloatに変換したいとします。しかし、それは私に16進数ではない数字を表示しているので、私はそれを行うことはできません。

+1

なぜこれらのバイトは16進数で必要ですか?コードをデバッグしようとしていて、バイトの内容を16進数で知りたいのですか、またはこのデータをプログラムのユーザーに表示する必要がありますか?ここではデバッグ情報を見ていますが、エンドユーザーフレンドリーな表現ではありません。 –

+0

これらのバイトを整数に変換したい場合は、 'int.from_bytes'メソッドを見てください。 –

+0

16進数字を浮動小数点に変換する予定はありますか?通常、バイト値を使用します。これらの値はまだすべてです。 –

答えて

1

C,eおよび/もバイトです。彼らはASCII文字ですので、\x.. 16進数のエスケープで表示する必要はありません。

\x..の16進エスケープをデコードする必要はありません。これは、Pythonがbytesオブジェクトのデバッグ表現をどのように提供するかを示しています。各バイトは、エスケープシーケンスまたは印刷可能なASCII文字として表示されます。

同じこの例のように、あなたの何かに起こる:

>>> b'\x01\x03\x04\x43\x67\x81\xEC\x43\x68' 
b'\x01\x03\x04Cg\x81\xecCh' 

まったく同じ値だが、\x68はASCII文字hある、など

出力はデフォルトrepr()出力されますbytesオブジェクトです。変更することはできません。異なる出力が必要な場合は、独自のコードを記述する必要があります。

次の例のように、binascii.hexlify()機能付き六角としてのすべてのバイトを表示することができます:

>>> import binascii 
>>> binascii.hexlify(b'\x01\x03\x04\x43\x67\x81\xEC\x43\x68') 
b'010304436781ec4368' 

今、あなたは、六角文字bytes文字列を持っています。

>>> ''.join(r'\x{:02x}'.format(byte) for byte in b'\x01\x03\x04\x43\x67\x81\xEC\x43\x68') 

'\ X01 \ X03 \ X04 \ X43 \ X67 \ X81 \ XEC \ X43 \ X68'

:個々のバイトが先頭に\xリテラルテキストでHexに変換したり、あなたはstr.join()機能を使用することができます
>>> print(''.join(r'\x{:02x}'.format(byte) for byte in b'\x01\x03\x04\x43\x67\x81\xEC\x43\x68')) 
\x01\x03\x04\x43\x67\x81\xec\x43\x68 

これは、\,xと16進数の文字を含むstrオブジェクトです。

これはすべての値を表示するです。値は変更されませんでした。バイトはすべて表示されますが、表示されます。あなたはfloat型に4つのバイトを変換する必要がある場合は、単にこれらの4つのバイトを変換:

struct.unpack('f', yourbytes[4:]) # 4 bytes for C float in native order 

これは、直接バイトを使用するようにstruct moduleを使用しています。いいえ16進表現は必要ありません:

>>> import struct 
>>> struct.unpack('f', b'\x01\x03\x04Ce/\xec\xe2'[:4]) 
(132.01173400878906,) 
1

あなたはデータから数値を取得するためにstruct.unpack()を使用することができます。ここに方法があります:

In [171]: import struct 

In [190]: b2 
Out[190]: b'\x01\x03J8\x00\x02S\xde' 

In [191]: struct.unpack('B'*len(b2), b2) 
Out[191]: (1, 3, 74, 56, 0, 2, 83, 222) 

In [192]: [*map(hex, struct.unpack('B'*len(b2), b2))] 
Out[192]: ['0x1', '0x3', '0x4a', '0x38', '0x0', '0x2', '0x53', '0xde'] 
関連する問題