稼働中

マイクロビット(e_10)MMA8653 加速度センサー

MMA8653 (I2C) 加速度センサー

I2Cの事例にmicro:bitに実装されている加速度を使ってみました。(MMA8653FC 3-Axis, 10-bit Digital Accelerometer)
accelerometer.get_values()で得られる値とMMA8653のレジスタから読出した値、それぞれから角度算出してみました。

角度の計算

下の図のようにx軸方向に傾けた、だいたい45度の状態にして角度を算出してみます。
角度の図1 角度の図2

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接続デバイスのデータ読出しの練習になったと思います。