ここでは「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をショートしておけば、電源5Vでも使用できるので融通が利きますよね。
JP7のショート(はんだ付け)は下図のように行います。
左右の金箔部分が両方ともはんだで埋まればショートの完了です。
BMX055とラズパイの配線をする
続いて、BMX055とラズパイを配線します。
配線にはブレットボードとジャンパ線(メスtoオス)を使って配線します。
配線先のピンは以下の通りです。
ラズパイ ⇔ BMX055 配線
5 V ⇔ VCC
GND ⇔ GND
GPIO2:SDA ⇔ SDA
GPIO3:SCL ⇔ SCL
BMX055の向きに気を付けて配線を行いましょう。
またジャンパー線は断線しやすいので、使用する前に通電しているかの確認もしておきましょう。
ラズパイ側での準備
BMX055のはんだ付け、配線が終わったら、ラズパイ側の設定を行っていきます。
TeraTermなどでSSH接続をして
コマンドを打ち込み、I2Cの設定を行います。
を<Select>してI2CのONにします。
I2Cの設定をONにできたら
で再起動をかけましょう。
再起動後、「lsmod」でI2Cが利用できるかどうかを確認します。
・・・
i2c_bcm2835
i2c_bcm※※※※と表示されていれば、I2CがONになっていると分かります。
I2CのONを確認できたら、実際にBMX055とラズパイをI2Cで接続・確認をします。
とコマンドを打ち込むと
上図のように各センサのアドレスが表示されます。
JP1~JP3をショート(はんだ付け)しなければ、
となります。
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をインストールします。
インストールの途中で「続行しますか?[Y/n]」と表示されたら「y」を入力してインストールを続行させます。
インストールが完了したら、ラズパイ側の準備は終了です。
BMX055から各センサ値を読み取る
BMX055を使用する準備ができたら、実際にラズパイ側でPythonプログラムを組んで、加速度、角速度、地磁気の値を取得してみましょう。
BMX055のセンサ値を読み取るには
まずはBMX055からセンサの値を読み取る方法を軽く確認します。
秋月電子通商のBMX055商品ページから、データシートをダウンロードします。
ダウンロードできたら、データシートの「Index of Contents」(見出し)からデータの出力部分を見つけて読み取り方法を読解します。
基本的にはデータシートを頼りにセンサ値を取得していきますが、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]])
プログラム内では
できるようにしています。
プログラムを実行してみると、加速度Acc、角速度Gyro、地磁気Magの値がしっかりと出力されていることが確認できます。
BMX055の地磁気センサ値を確認
またBMX055の使い方を調べていて
という問題に衝突しましたが、さすがGitHub。
普通に地磁気取得プログラムがあったので、一部改良してプログラムに組み込みました。
Z軸を回転させると、地磁気の値(Mag_X、Mag_Y)が変化していることが確認できます。
また、地磁気の値がどれほどの精度か確認するため、BMX055をZ軸回りに一回転させて実験を行いました。
横軸をMag_X、縦軸をMag_Yとして一回転した様子を確認してみると
多少誤差はあるものの、しっかりと一回転したときの地磁気値を取得できていることが分かりました。
これで姿勢推定を行う準備ができましたね!
BMX055で値を取得するときに、お役に立てれば幸いです。
お疲れ様でした。
参考にしたサイト
Qiita:Raspberry Pi3で9軸センサ(BMX055)を使う
Github:BMX055-raspberry bmx055.py
取得したセンサ値から姿勢角(Roll、Pitch、Yaw角)を取得する方法は、こちらの記事の続きとなる下記記事をご覧ください。