大した話ではないけど半日詰まったのでメモ。
I2Cなんかから1バイト×2(Hbit、Lbit)のような形でデータを受け取って数値に変換するときの注意点。
例:
Hbyte : 11101110
Lbyte : 00011111
→2つあわせて 1110111000011111 を作ってから数値に変換する。Hの方を左に8bitシフトしたり256を掛けたりしてから足す(あるいはHとLのorをとる)
特にこのあたりでは問題は無いが、2の補数を取って負の値を出したいときpythonでは正常に処理できない場合がある。
例:
H : 10000000
L : 11001100
あわせて 1000000011001100(符号付10進数で-32564) となる。この値をそのままpythonで扱うとpythonの中では32972として扱われる(符号なし扱いのため)。何bitの符号付整数か(どのビットが1だと負扱いなのか)がpythonに認識できないので当然こうなるといえばこうなる。しかしpythonに例えばこのビット列は16ビット符号付整数として扱ってね、とやる方法もちょっとわからなかったので普通にxorを使って2の補数を算出する処理を実装する。これで何ビット整数として扱わせるかもこちらで指定できる。
(プログラムのイメージ)
if H & 0b1000000=0b10000000: ←Hバイトの頭が1(負数)だったら。ここの数値の桁数でビットを指定している。
val= (H <<8) | L ←HとLを合体 1000000011001100
val_inv=val ^ 0b1111111111111111 ←「^」はxor(pythonでは累乗は**なので注意)16bitの全部1の値とxorをとってすべてのビットを反転する。
val_inv = val_inv+1 ←1足して2の補数にする。この時点で正しい値の絶対値になっている
out =val_inv*(-1) ←マイナスをつける
以上。これで上の例だと outが-32564になる。
面倒だけどこれをやらないとpythonでは符号付出力のI2Cセンサがまともに使えないので地味に重要。
0 件のコメント:
コメントを投稿