マイクロビット(e_10)MMA8653 加速度センサー
MMA8653 (I2C) 加速度センサー
I2Cの事例にmicro:bitに実装されている加速度を使ってみました。(MMA8653FC 3-Axis, 10-bit Digital Accelerometer)
accelerometer.get_values()で得られる値とMMA8653のレジスタから読出した値、それぞれから角度算出してみました。
角度の計算
下の図のようにx軸方向に傾けた、だいたい45度の状態にして角度を算出してみます。
tanΘ=x/z なので Θ=atan(x/z)で得られます。
MMA8653のレジスタは下の表のようになっています。
x,y,zのデータは0x01~0x06の6bytesにあります。各々MSBが8bitsとLSBの上位2bitで10bitのデータになります。
レジスタから読出し計算
手順的には以下のような感じです。
①レジストデータからの計算は、各レジスタからデータを読み出します。
②10bitsのデータにします。
③10bitsデータを符号付きビットの値に変換します。
④先の計算式で角度を求めます。
また、get_values()で得られるx,y,zも同様に先の計算式で角度を求めて比較してみます。
以下を参照下さい。
from microbit import *
import math
#符号付きビットの計算 ※3
def com2s(bits,value):
if 1 << bits-1 == 1 << bits-1 & value:
value = value - 2**bits
return value
# MMA8653 のアドレス ID=0x01D(29)
#print(i2c.scan())
addr=29
reg = i2c.read(addr, 7) # 0x00から7bytes読む(データのレジスタは0x01~0x06) ※1
sleep(100)
l_reg=list(reg) # リスト形式にする
#print(l_reg)
# 8 ビットデータを 10 ビットデータに
x_reg = l_reg[1]<<2 | l_reg[2]>>6 # X_outの10bit ※2
y_reg = l_reg[3]<<2 | l_reg[4]>>6 # Y_outの10bit
z_reg = l_reg[5]<<2 | l_reg[6]>>6 # Z_outの10bit
print('xyz_reg=',x_reg, y_reg, z_reg )
# 符号付きの計算をする 関数に送る
x_com = com2s(10, x_reg)
y_com = com2s(10, y_reg)
z_com = com2s(10, z_reg)
get_xyz=accelerometer.get_values()
#print('get_x,y,z=',get_xyz)
# reg data, get_value()
print('read_reg=',x_com, y_com, z_com ,'get_value=',get_xyz )
ath = math.atan(x_com/z_com)
bth = math.atan(get_xyz[0]/get_xyz[2])
adeg = math.degrees(ath) # レジスタから算出した角度
bdeg = math.degrees(bth) # get_valueから算出した角度
#reg_value >>adeg, get_value>>bdeg
print('reg >',adeg, 'get >',bdeg) # レジスタから算出した角度、get_valueから算出した角度を表示
※1
本来、レジスタ0x01を指定して6bytesをreadするのが良いと思うのですが、上手くできませんでした。
そのため0x00から7bytesをreadし、0x01から0x06までのデータを使用しました。
※2
MSBを左に2bitsシフトしてLSBの2bit追加位置を確保、LSBを右に6bitシフトさせ上位2bitだけにする。
その和で10bitになります。
※3
もし、valueの最上位ビットが’1’なら符号をマイナスにします。例えば4bitなら
0b1000(8)なら 8-2**4 = -8 (2**4=16)
0b1001(9)なら 9-2**4 = -7
・・
b01111(15)なら 15-2**4= -1
ように符号付きの計算をしました。もっといい方法がありそうですが・・。
実行結果
実行結果は以下のようになりました。
だいたい45度くらいで測定
>>> %Run 1020_8653_acc_deg_01b.py
xyz_reg= 837 1020 853
read_reg= -187 -4 -171 get_value= (752, 16, -704) # レジスタからの値とget_valueで数値は違う
reg > 47.559 get > -46.8882 # 数値は違うが計算角度はほぼ同じ 符号が逆に
少し角度を変えて再測定
>>> %Run 1020_8653_acc_deg_01b.py
xyz_reg= 795 1020 913
read_reg= -229 -4 -111 get_value= (912, 16, -464)
reg > 64.1397 get > -63.0343 # 計算角度はほぼ同じ 符号は逆
各x,y,zの個別のデータはレジスタからの値とget_valueの値と同じにはなりませんでした。
しかし、計算した角度はほぼ同じになりました。何故かしら符号は異なる結果になりました。
まとめ
micro:bitに実装されているI2C接続のMMA8653加速度センサー(3-Axis, 10-bit Digital Accelerometer)の直接的な使い方について記載しました。
直接MMA8653のレジスタからデータを読出しすることができました。ただしaccelerometer.get_value()の値とは異なりました。角度等は比率計算なので計算値は同じになりました。I2C接続デバイスのデータ読出しの練習になったと思います。