注目キーワード
  1. Photoshop
  2. Python
  3. Raspberry Pi
  4. Arduino

ラズパイでBMX055の使い方と地磁気などのセンサ値を取得してみた

ここでは「Raspberry Pi:ラズパイ」で「BMX055」を使う方法や各センサ値を取る方法を紹介します。

 

この記事を読むことで

BMX055の使い方-基礎

BMX055で加速度、角速度、地磁気値を取得

BMX055を動かすPythonプログラム

を知ることができます。

 

このBMX055を購入した理由は

二足歩行ロボットの姿勢推定で使用したい

信頼できる場所(秋月)から購入できる

小型でI2C通信ができる

からになります。

 

皆さんもBMX055の使い方をマスターして、姿勢推定のために機体へ搭載してみてはいかがでしょうか。

それでは始めていきますね。

 

※ 更新情報

・2021/7月

マイコン⇄BMX055の誤記入を訂正しました。

python-smbusの誤字を訂正しました。

 

BMX055を使うための準備

まずhBMX055をラズパイで使うための準備をしていきます。

 

BMX055のはんだ付け

まず最初にBMX055のはんだ付けを行います。

付属のピンをはんだ付けした後、BMX055の取扱説明書の「電源とジャンパの関係表」からジャンパJP6~8のどのジャンパをはんだ付けするかを決めます。

 

 

BMX055_9軸センサモジュール:取扱説明書.pdf(秋月電子通商)

 

今回は電源に5V 、信号レベルに3.3Vを使用したいので

JP7をショート(はんだ付け)

します。

またJP7をショートしておけば、電源5Vでも使用できるので融通が利きますよね。

 

JP7のショート(はんだ付け)は下図のように行います。

bmx055-mag-1

左右の金箔部分が両方ともはんだで埋まればショートの完了です。

 

BMX055とラズパイの配線をする

続いて、BMX055とラズパイを配線します。

配線にはブレットボードとジャンパ線(メスtoオス)を使って配線します。

bmx055-mag-2_re

 

配線先のピンは以下の通りです。

ラズパイ ⇔ BMX055 配線

5 V ⇔ VCC

GND ⇔ GND

GPIO2:SDA ⇔ SDA

GPIO3:SCL ⇔ SCL

 

BMX055の向きに気を付けて配線を行いましょう。

またジャンパー線は断線しやすいので、使用する前に通電しているかの確認もしておきましょう。

 

ラズパイ側での準備

BMX055のはんだ付け、配線が終わったら、ラズパイ側の設定を行っていきます。

 

TeraTermなどでSSH接続をして

$ sudo raspi-config

コマンドを打ち込み、I2Cの設定を行います。

 

P5 I2C Enable/disable・・・

を<Select>してI2CのONにします。

bmx055-mag-3

 

I2Cの設定をONにできたら

$ sudo reboot

で再起動をかけましょう。

 

再起動後、「lsmod」でI2Cが利用できるかどうかを確認します。

$ lsmod
・・・
i2c_bcm2835

 

i2c_bcm※※※※と表示されていれば、I2CがONになっていると分かります。

bmx055-mag-4

 

I2CのONを確認できたら、実際にBMX055とラズパイをI2Cで接続・確認をします。

$ sudo i2cdetect -y 1

とコマンドを打ち込むと

 

bmx055-mag-6

上図のように各センサのアドレスが表示されます。

 

JP1~JP3をショート(はんだ付け)しなければ、

加速度0x19、ジャイロ0x69、地磁気0x13

となります。

 

BMX055を2つ以上使用する場合は、JP1~JP3の任意のジャンパをショートさせI2Cアドレスを変えて使用しましょう。

 

最後に、BMX055をI2Cで仕様するためのパッケージをインストールします。

$ sudo apt-get update

$ sudo apt-get install i2c-tools python-smbus libi2c-dev
・・・
続行しますか? [Y/n] y

と入力して、python-smbusをインストールします。

bmx055-mag-5

インストールの途中で「続行しますか?[Y/n]」と表示されたら「y」を入力してインストールを続行させます。

インストールが完了したら、ラズパイ側の準備は終了です。

 

BMX055から各センサ値を読み取る

BMX055を使用する準備ができたら、実際にラズパイ側でPythonプログラムを組んで、加速度、角速度、地磁気の値を取得してみましょう。

 

BMX055のセンサ値を読み取るには

まずはBMX055からセンサの値を読み取る方法を軽く確認します。

秋月電子通商のBMX055商品ページから、データシートをダウンロードします。

 

BMX055_PDF:データシート.pdf(秋月電子通商)

 

ダウンロードできたら、データシートの「Index of Contents」(見出し)からデータの出力部分を見つけて読み取り方法を読解します。

bmx055-mag-register

 

基本的にはデータシートを頼りにセンサ値を取得していきますが、Google検索、Githubでの検索等でBMX055データ取得プログラムを探すのもアリだと思います。

 

各センサ値を取得するプログラム

データを取得する方法はある程度分かりましたが、相当知識がないとプログラムを一から書くのは難しかったので、Qiita、Gitあたりのプログラムを可能な限り読みあさり、最適なプログラムを作成しました。

メインで参考にしたBMX055データ取得プログラムは下記の「参考したサイト」へ記載してあります。

では早速BMX055からデータを取得するプログラムを見てみましょう。

 

bmx055_test.py

# -*- coding: utf-8 -*-
from smbus import SMBus
import time
import math
import datetime
import csv

# I2C
ACCL_ADDR = 0x19
ACCL_R_ADDR = 0x02
GYRO_ADDR = 0x69
GYRO_R_ADDR = 0x02
MAG_ADDR = 0x13
MAG_R_ADDR = 0x42

i2c = SMBus(1)

def bmx_setup():
    # acc_data_setup : 加速度の値をセットアップ
    i2c.write_byte_data(ACCL_ADDR, 0x0F, 0x03)
    i2c.write_byte_data(ACCL_ADDR, 0x10, 0x08)
    i2c.write_byte_data(ACCL_ADDR, 0x11, 0x00)
    time.sleep(0.5)

    # gyr_data_setup : ジャイロ値をセットアップ
    i2c.write_byte_data(GYRO_ADDR, 0x0F, 0x04)
    i2c.write_byte_data(GYRO_ADDR, 0x10, 0x07)
    i2c.write_byte_data(GYRO_ADDR, 0x11, 0x00)
    time.sleep(0.5)

    # mag_data_setup : 地磁気値をセットアップ
    data = i2c.read_byte_data(MAG_ADDR, 0x4B)
    if(data == 0):
        i2c.write_byte_data(MAG_ADDR, 0x4B, 0x83)
        time.sleep(0.5)
    i2c.write_byte_data(MAG_ADDR, 0x4B, 0x01)
    i2c.write_byte_data(MAG_ADDR, 0x4C, 0x00)
    i2c.write_byte_data(MAG_ADDR, 0x4E, 0x84)
    i2c.write_byte_data(MAG_ADDR, 0x51, 0x04)
    i2c.write_byte_data(MAG_ADDR, 0x52, 0x16)
    time.sleep(0.5)

def acc_value():
    data = [0, 0, 0, 0, 0, 0]
    acc_data = [0.0, 0.0, 0.0]

    try:
        for i in range(6):
            data[i] = i2c.read_byte_data(ACCL_ADDR, ACCL_R_ADDR + i)

        for i in range(3):
            acc_data[i] = ((data[2*i + 1] * 256) + int(data[2*i] & 0xF0)) / 16
            if acc_data[i] > 2047:
                acc_data[i] -= 4096
            acc_data[i] *= 0.0098

    except IOError as e:
        print("I/O error({0}): {1}".format(e.errno, e.strerror))

    return acc_data

def gyro_value():
    data = [0, 0, 0, 0, 0, 0]
    gyro_data = [0.0, 0.0, 0.0]

    try:
        for i in range(6):
            data[i] = i2c.read_byte_data(GYRO_ADDR, GYRO_R_ADDR + i)

        for i in range(3):
            gyro_data[i] = (data[2*i + 1] * 256) + data[2*i]
            if gyro_data[i] > 32767:
                gyro_data[i] -= 65536
            gyro_data[i] *= 0.0038

    except IOError as e:
        print("I/O error({0}): {1}".format(e.errno, e.strerror))

    return gyro_data

def mag_value():
    data = [0, 0, 0, 0, 0, 0, 0, 0]
    mag_data = [0.0, 0.0, 0.0]

    try:
        for i in range(8):
            data[i] = i2c.read_byte_data(MAG_ADDR, MAG_R_ADDR + i)

        for i in range(3):
            if i != 2:
                mag_data[i] = ((data[2*i + 1] * 256) + (data[2*i] & 0xF8)) / 8
                if mag_data[i] > 4095:
                    mag_data[i] -= 8192
            else:
                mag_data[i] = ((data[2*i + 1] * 256) + (data[2*i] & 0xFE)) / 2
                if mag_data[i] > 16383:
                    mag_data[i] -= 32768

    except IOError as e:
        print("I/O error({0}): {1}".format(e.errno, e.strerror))

    return mag_data

if __name__ == "__main__":

    bmx_setup()
    time.sleep(0.1)

    now_time = datetime.datetime.now()
    filename = 'test_' + now_time.strftime('%Y%m%d_%H%M%S') + '.csv'
    # ファイル,1行目(カラム)の作成
    with open(filename, 'a') as f:
        writer = csv.writer(f)
        writer.writerow(['Mag_x', 'Mag_y', 'Mag_z'])

    while True:
        acc = acc_value()
        gyro= gyro_value()
        mag = mag_value()

        print("Accl -> x:{}, y:{}, z: {}".format(acc[0], acc[1], acc[2]))
        print("Gyro -> x:{}, y:{}, z: {}".format(gyro[0], gyro[1], gyro[2]))
        print("Mag -> x:{}, y:{}, z: {}".format(mag[0], mag[1], mag[2]))
        print("\n")
        time.sleep(0.1)

        with open(filename, 'a', newline="") as f:
            writer = csv.writer(f)
            writer.writerow([mag[0], mag[1], mag[2]])

 

プログラム内では

地磁気の値をCSV出力

できるようにしています。

プログラムを実行してみると、加速度Acc、角速度Gyro、地磁気Magの値がしっかりと出力されていることが確認できます。

 

bmx055-agmdata

 

BMX055の地磁気センサ値を確認

またBMX055の使い方を調べていて

taku
地磁気の値を取るプログラムが見つからない

という問題に衝突しましたが、さすがGitHub。

普通に地磁気取得プログラムがあったので、一部改良してプログラムに組み込みました。

 

Z軸を回転させると、地磁気の値(Mag_X、Mag_Y)が変化していることが確認できます。

bmx055-mag-7

 

また、地磁気の値がどれほどの精度か確認するため、BMX055をZ軸回りに一回転させて実験を行いました。

横軸をMag_X、縦軸をMag_Yとして一回転した様子を確認してみると

bmx055-magdata

多少誤差はあるものの、しっかりと一回転したときの地磁気値を取得できていることが分かりました。

 

これで姿勢推定を行う準備ができましたね!

BMX055で値を取得するときに、お役に立てれば幸いです。

お疲れ様でした。

 

参考にしたサイト

Qiita:Raspberry Pi3で9軸センサ(BMX055)を使う

 

Github:BMX055-raspberry bmx055.py

 

取得したセンサ値から姿勢角(Roll、Pitch、Yaw角)を取得する方法は、こちらの記事の続きとなる下記記事をご覧ください。

ラズパイとBMX055で加速度・地磁気からオイラー角を算出・検証してみた

bmx055-howtouse-mag-thumbnail
学びに関する情報をチェック!