LoginSignup
18
19

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-05-19

Raspberry Pi 3で、9軸センサ(BMX055)の値を取得する方法があまり見当たらなかったので、まとめてみました。
(2019/10/20) 誤り修正、参考リンク追加

環境

センサのはんだづけ

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

ラズパイで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

軸の向き

bmx055.png

動作確認

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.00098[g]です。
つまり、レジスタから読み取った値が1であったとすると、それは0.00098[g]を意味するため、0.00098をかける必要があります。
また、[m/s^2]で使いたいなら、さらに9.8をかける必要があります。

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.00098 = 1.01234 [g] = 9.920932 [m/s^2]

となります。

なお、取得する加速度のレンジや周期など、様々なパラメータが変更できます。
詳しくは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.00098
    y_acc = y_value * 0.00098
    z_acc = z_value * 0.00098

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

    i2c.close()


if __name__ == '__main__':
    bmx055()

参考

python以外のサンプルがこちらにありました。
こちらのGithubには、他のセンサのサンプルコードもあるようです。

18
19
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
19