Help us understand the problem. What is going on with this article?

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

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には、他のセンサのサンプルコードもあるようです。

hiro-han
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした