2017-01-30 4 views
0

特定のプロトコルを使用してCANBUS経由で送信するメッセージを作成するコードを作成しています。このようなメッセージのデータフィールドのフォーマット例である:8bitエンコーディングでバイナリをbytearrayに変換する

[FROM_ADDRESS(1バイト)] [control_byte(1バイト)] [識別子(3バイト)] [長さ(3バイト)]

データフィールドはリストまたはbytearrayとしてフォーマットする必要があります。私のコードは、現在、以下のことを行います。

次のようにのdataFormatが定義されている
data = dataFormat((from_address << 56)|(control_byte << 48)|(identifier << 24)|(length)) 

def dataFormat(num): 
    intermediary = BitArray(bin(num)) 
    return bytearray(intermediary.bytes) 

これはFROM_ADDRESSは以下で説明することができます番号であるときを除いて、私はそれがしたい正確に何ん8ビットより大きい。これらのケースでは(余分なゼロは破棄されます)8で割り切れない文字長のバイナリを返し、そうintermediary.bytesは、変換があいまいであると文句を言いbin()

InterpretError: Cannot interpret as bytes unambiguously - not multiple of 8 bits. 

私は上記のコードでは何にも縛られないです - どのメソッドを使用して整数のシーケンスを取得し、バイト単位で正しいサイジングを使用してバイトアレーに変換すると非常に感謝します。

+0

これはタグ[tag:can]が必要なのは何ですか? – usr2564301

+0

@RadLexusこれはcanメッセージの一部です。手元の問題には特に関係ないと思います。 – oirectine

+0

CANコントローラのレジスタのメッセージ構造を使用してみませんか?識別子と長さはCANフレームの専用フィールドですが、他のものはデータフィールドに格納する必要があります。 – Lundin

答えて

2

あなたが望むのはbytearrayなら、簡単な選択肢はそこにまっすぐジャンプして直接ビルドすることです。このようなもの:

# Define some values: 
from_address = 14 
control_byte = 10 
identifier = 80 
length = 109 

# Create a bytearray with 8 spaces: 
message = bytearray(8) 

# Add from and control: 
message[0] = from_address 
message[1] = control_byte 

# Little endian dropping in of the identifier: 
message[2] = identifier & 255 
message[3] = (identifier >> 8) & 255 
message[4] = (identifier >> 16) & 255 

# Little endian dropping in of the length: 
message[5] = length & 255 
message[6] = (length >> 8) & 255 
message[7] = (length >> 16) & 255 

# Display bytes: 
for value in message: 
    print(value) 

Here's a working example of that

健康警告

は、上記のメッセージがlittle endianことが期待されていることを前提としています。また、Pythonでこれを行う方法で構築されているかもしれませんが、頻繁に使用する言語ではありません。

関連する問題