Edited at

Rasperry Pi 3で9軸センサ(BMX055)を使う

Raspberry Pi 3で、9軸センサ(BMX055)の値を取得する方法があまり見当たらなかったので、まとめてみました。


環境


センサのはんだづけ

ジャンパの設定とピンヘッダを取り付けるため、はんだづけをします。


ラズパイでI2Cを使う設定

この内容は他にも多くの方が記事を書いているので、詳しくは書きません。


I2Cインタフェースの有効化

$ sudo raspy-config

表示された画面で、3 Interfacing Options -> P4 I2C と選択したら、

Would you like the ARM I2C interface to be enabled?と尋ねられるので、

yes を選択し終了します。

その後、再起動します。

再起動後、以下のコマンドを入力しi2c_bcm2708i2c_devがあることを確認します。

$ lsmod

...
i2c_bcm2708
...
i2c_dev
...


ライブラリ、ツールのインストール

$ sudo apt-get update

$ sudo apt-get install i2c-tools python-smbus libi2c-dev


回路の作成

私はセンサの電源に5Vを使うことにしたため、以下のように接続しました。

電源を3.3Vにする場合はもう1本、線を追加する必要があると思います(未確認)。

左側がラズパイのGPIOピン、右がセンサです。

GPIO 1 (5V) -> VCC

GPIO 3 (SDA) -> SDA
GPIO 5 (SCL) -> SCL
GPIO 9 (GLD) -> GLD


軸の向き


動作確認

i2cdetectコマンドで確認します。コマンドの詳細はこちらです。

$ sudo i2cdetect -y 1

0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- 13 -- -- -- -- -- 19 -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- 69 -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

加速度、ジャイロ、磁気のアドレスはそれぞれ、0x19、0x69、0x13なので(※)正しく認識できています。

(※ジャンパピンの設定で変わります)


値の取得


ツールによる取得

どのアドレスにアクセスしたら何のデータが取得できるか、はBOSCHが公開しているBMX055のデータシートを見ればわかるのですが、

慣れていないとなかなか読み解くのが難しいです。簡単にですが説明します。

例えばz方向の加速度であれば、以下のように取得します。

加速度の値は12bitであり、レジスタアドレス0x06と0x07に分割して格納されています。

0x06の4~7bit目に加速度の下位4bitが、0x07に上位8bitが格納されています。

そのため、0x07の値と、0x06の4~7bit目の値を組み合わせる必要があります。

また、0x06には、0bit目には新しいデータかどうかを示すフラグが格納されています。

加速度の値は12bitですが、符号付き整数なので先頭の1bitは正負の符号です。

よって値域は -2048~2047 となります。

先頭bitが1のとき、2の補数を計算して負数にしてもいいのですが、

値が2048以上の場合は4096を引いて負の値に変換するほうが簡単です。

ここまでで求めた値はまだ物理値ではありません。

例えば、ここまでで求めた値が1であったからといって、加速度は1[m/s]ではありません。

レジスタアドレス0x0Fには値のレンジ設定が格納されており、デフォルト値は0x03なので

取得できる値のレンジは+/- 2gでLSBは0.0098[m/s]です。

つまり、レジスタから読み取った値が1であったとすると、それは0.0098[m/s]を意味するので、0.0098をかける必要があります。

i2cgetコマンドでセンサの値を取得し、物理値に変換してみます。

$ sudo i2cget -y 1 0x19 0x06

0x91
$ sudo i2cget -y 1 0x19 0x07
0x40

0x06の値は0x91なので、0bit目は1なので新しいデータであることがわかります。

0x06の4~7bit目と0x07の値を組み合わせると加速度の値は

0x409 = 0d1033

1033 x 0.0098 = 10.1234 [m/s]

となります。

なお、取得する加速度のレンジや周期など、様々なパラメータが変更できます。

詳しくはBMX055のデータシートを見てください。


python プログラム

python3で加速度を取得するプログラムです。

smbusのapiはこちらから参照できます。


bmx055.py

#!/usr/bin/python3

# -*- coding: utf-8 -*-

import smbus
import time

ACC_ADDRESS = 0x19
ACC_REGISTER_ADDRESS = 0x02

def bmx055():
# initialize
i2c = smbus.SMBus(1)

## 指定したレジスタアドレスから、2byte分取得する
x_lsb = i2c.read_byte_data(ACC_ADDRESS, ACC_REGISTER_ADDRESS)
x_msb = i2c.read_byte_data(ACC_ADDRESS, ACC_REGISTER_ADDRESS+1)
y_lsb = i2c.read_byte_data(ACC_ADDRESS, ACC_REGISTER_ADDRESS+2)
y_msb = i2c.read_byte_data(ACC_ADDRESS, ACC_REGISTER_ADDRESS+3)
z_lsb = i2c.read_byte_data(ACC_ADDRESS, ACC_REGISTER_ADDRESS+4)
z_msb = i2c.read_byte_data(ACC_ADDRESS, ACC_REGISTER_ADDRESS+5)

x_value = (x_msb * 16) + ((x_lsb & 0xF0) / 16)
x_value = x_value if x_value < 2048 else x_value - 4096
y_value = (y_msb * 16) + ((y_lsb & 0xF0) / 16)
y_value = y_value if y_value < 2048 else y_value - 4096
z_value = (z_msb * 16) + ((z_lsb & 0xF0) / 16)
z_value = z_value if z_value < 2048 else z_value - 4096

x_acc = x_value * 0.0098
y_acc = y_value * 0.0098
z_acc = z_value * 0.0098

print ("[%f, %f, %f]" % (x_acc, y_acc, z_acc))

i2c.close()

if __name__ == '__main__':
bmx055()