3軸磁気センサーLIS3MDの検討

2018年3月3日 - 未分類

3軸で磁気を測定できるLIS3MDの検討をしてみました。これは、カメラを動かすと、どの方向を見ているのか分からなくなるので、地磁気で方位を取得しようと考えたからです。何故、3軸も必要なのか、最初は分からなかったのですが、3軸加速度センサーと組み合わせて使う場合に3軸必要になる訳です。普通に、水平に置いて使う分には、2軸で十分でしょう。

LIS3MDは、I2CでRaspberry Pi Model3に接続しました。アドレスは0x1Eでした。

磁気センサーは、最初に、キャリブレーションが必要です。センサーを水平状態で一回り回転させます。回転中の出力値を記録すると、XYグラフができます。理想状態では、原点中心の完全な円になるはずですが、実際には、周辺の磁気に影響されるので円にはなりません。原点からずれた楕円になります。

先ずは、Z値が大きく外れた部分を削除し、X,Yの平均値を差し引きます。

原点に寄ってきました。ここから、楕円フィティングします。

Pythonのscipyを使えば、様々な関数をフィティングできます。

見事にフィッティングできています。楕円近似のpythonソースコードです。python3でmatplotをインストールするのに、ちょっと手間取りかもしれません。

後は、モーターで回転させて、自動的にキャリブレーションを取れるようにしたいと思います。上手く行けば、カメラが撮影している方角が記録できます。

#!/usr/bin/python3
import numpy as np
from scipy import odr
from scipy import optimize
from matplotlib.patches import Ellipse
import matplotlib.pyplot as plt
from scipy.stats import norm

def f(B, x):
    return ((x[0]/B[0])**2+(x[1]/B[1])**2-1.)

#Least squares method with scipy.optimize
def fit_func(parameter,xy):
    a = parameter[0]
    b = parameter[1]
    c = parameter[2]
    residual = (a*xy[0]+b*xy[1]+c)
    return residual

def f(B, x):
    return ((x[0]/B[0])**2+(x[1]/B[1])**2-1.)

if __name__ == '__main__':
    file_id = 'magdir.csv'
    file_path = './'

    rfile = file_path + file_id
    data = np.loadtxt(rfile, comments='#' ,delimiter=',')

    x_csv = data[:,0]
    y_csv = data[:,1]

    # sub average
    x_ave=np.average(x_csv)
    y_ave=np.average(y_csv)
    x_csv = x_csv-x_ave
    y_csv = y_csv-y_ave

    xy = np.array([x_csv, y_csv])

    #mdr = odr.Model(f, implicit=True)
    mdr = odr.Model(g, implicit=True)
    mydata = odr.Data(xy,y=1)
    #myodr = odr.ODR(mydata, mdr, beta0=[1., 2.])
    myodr = odr.ODR(mydata, mdr, beta0=[1., 2.,3.,4.])
    myoutput = myodr.run()
    myoutput.pprint()

    ax = plt.subplot(111, aspect='equal')
    plt.scatter(x_csv, y_csv) # raw data with randomness

    ell = Ellipse(xy=(0., 0.), width=2.*myoutput.beta[0], height=2.*myoutput.beta[1], angle=0.0)
    ell.set_facecolor('none')
    ell.set_edgecolor('black')
    ax.add_artist(ell) # fitted curve
    plt.grid()
    plt.show()
    plt.show()

その後、8BYJ-48 Stepper Motorというステッピングモーターでセンサーを回転させて再測定しました。8BYJ-48 Stepper Motorは、安価なステッピングモーターです。RaspberryPiで4層の回転パルスを出して制御します。回転速度は、非常にゆっくりとしています。

低価格だが、不良品も多く含まれていて、制御基板のLEDが点灯しないのは普通のことだと思わなければならない。モーターの磁気の影響を受けるので、アルミパイプでモーターから100mm離して測定。

さすがに、手で回すよりもきれいなデータがとれました。Z軸方向のブレも少ないようです。

楕円でフィティングしました。見事な真円になりましたね。

 

Translate »