0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MachiKaniaで6軸重力加速度センサーモジュール (BMI160)を使う

Posted at

はじめに

先日購入した電子工作ステーションで購入したラズパイ福袋2026に入っていた6軸重力加速度センサーモジュール (BMI160)をMachiKania type PをインストールしたRaspberry Pi Pico 2 Wに接続して加速度などを測定できたでのその方法をまとめました。今回もChatGPTに相談しながら試しました。

検証環境

今回は下記のハードウェア、ソフトウェアで検証しました。

ハードウェア

下記のハードウェアを使用しました。

ソフトウェア

  • MachiKania type P 1.6.1.0 KM-1511

接続

6軸重力加速度センサーモジュールとRaspberry Pi Pico 2 WをI2C通信で使用できるように次の表に示すように接続しました。

モジュールのSA0ピンをGNDに接続することでモジュールのスレーブアドレスが0x68にしています。なお、このピンを解放するとアドレスは0x69になります。

モジュール Pico 2W(物理)
3V3 3v3(36)
GND GND(38)
SCL GP7(10)
SDA GP6(9)
SA0 GND(38)

表に記載のない品は未接続です。

実態配線図を以下に示します。

BMI160_ブレッドボード.png

BMI160

BMI160はBosch Sensortecが開発した3軸の加速度センサと3軸のジャイロセンサを組み合わせた慣性計測ユニットです。製品紹介ページに示された仕様は次のとおりです。

  • 電源:DC3.2V~5V
  • 消費電流:<1mA
  • 通信モード:I2C/SPI
  • AD16ビットコンバータ、16ビットデータ出力
  • ジャイロ範囲:±125、±250、±500、±1000、±2000°/s
  • 加速範囲:±2、±4、±8、±16g
  • ピン間隔:2.54mm
  • 動作温度:-40℃~85℃

BMI160の初期化シーケンス

BMI160の初期化は次の手順で実行します。

  1. チップIDの確認
    CHIP_ID(0x00)レジスタのデータを取得し、その値が0xD1と一致するかを確認する。
  2. ソフトリセット
    CMD(0x7E)レジスタにデータ0xB6を書き込み、設定をデフォルト状態あるいはNVMに保存された値にします
  3. 加速度センサーの設定
    • ACC_CONF(0x40)レジスタにアンダーサンプリンク、帯域幅、出力データレートを設定します
    • ACC_RANGE(0x41)レジスタに加速度計の重力加速範囲を設定します
  4. ジャイロセンサーの設定
    • GYR_CONF(0x42)レジスタに出力データレータと帯域幅を設定します
    • GYR_RANGE(0x43)レジスタに角速度測定範囲を設定します
  5. PMU(電力管理ユニット)をノーマルモードにする。
    CMD(0x7E)レジスタにデータ0x110x15を書き込み、加速度センサーとジャイロセンサーを測定可能な状態にします

ACC_CONF(0x40)レジスタの内容

加速度計の設定用ACC_CONFレジスタの構成は次のとおりです。

名前 Register(0x40)ACC_CONF
Bit 7 6 5 4 3 2 1 0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Rest Value 0 0 1 0 1 0 0 0
Content acc_us acc_bwp acc_odr
  • acc_us:アンダーサンプリングのパラメータでノーマルモードは0b0に、ローパワーモードにするには’0b1にします。
  • acc_bwp:加速度計の帯域幅の設定でノーマルモードのときは0b010にします。
  • acc_odr:$100/2^{8-acc\_odr}$で得られるHz単位の出力データレートを定義します。acc_odrの値は0b0001〜0b1100の範囲です。0b1000が100Hzになります。

ACC_RANGE(0x41)レジスタの内容

加速度計の範囲設定用ACC_RANGEレジスタの構成は次のとおりです。

名前 Register(0x41)ACC_RANGE
Bit 7 6 5 4 3 2 1 0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Rest Value 0 0 0 0 0 0 1 1
Content Reserved acc_range<3:0>

acc_range<3:0>の値は次の4つから選びます。それ以外の値は±2gレンジに設定されます。

レンジ
0b0011 ±2g
0b0101 ±4g
0b1000 ±8g
0b1100 ±16g

GYR_CONF(0x42)レジスタの内容

ジャイロスコープの設定用GYR_CONFレジスタの構成は次のとおりです。

名前 Register(0x42)GYR_CONF
Bit 7 6 5 4 3 2 1 0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Rest Value 0 0 1 0 1 0 0 0
Content Reserved gyr_bwp gyr_odr
  • gyr_odr:$100/2^{8-gyr\_odr}$で得られるHz単位の出力データレートを定義します。gyr_odrの値は0b0110〜0b1101の範囲です。0b1000が100Hzになります。
  • gyr_bwp:ジャイロスコープの帯域幅係数は、センサーデータのローパスフィルターの3dBカットオフ周波数を定義します。

GYR_RANGE(0x43)レジスタの内容

ジャイロスコープの角速度測定範囲の設定用GYR_RANGEレジスタの構成は次のとおりです。

名前 Register(0x43)GYR_RANGE
Bit 7 6 5 4 3 2 1 0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Rest Value 0 0 0 0 0 0 0 0
Content Reserved gyr_range<2:0>

gyr_range<2:0>は角速度の範囲と解像度で次の表の値になります。

range[2:0] フルスケール 解像度
000 ±2000°/s 16.4 LSB/°/s ⇔ 61.0 m°/s/LSB
001 ±1000°/s 32.8 LSB/°/s ⇔ 30.5 m°/s/LSB
010 ±500°/s 65.6 LSB/°/s ⇔ 15.3 m°/s/LSB
011 ±250°/s 131.2 LSB/°/s ⇔ 7.6 m°/s/LSB
100 ±125°/s 262.4 LSB/°/s ⇔ 3.8 m°/s/LSB
101,110,111 予約済み

初期化プログラム

上記を参考にBMI160を次のように初期化します。

  • 電力管理:ノーマルモード
  • 出力データレート:100Hz
  • 加速度測定範囲:±4g
  • 角速度の範囲:±2000°/s

BMI160の初期化サブルーチンを以下に示します。

REM ------------------------------------
REM BMI160 
LABEL BMI160INIT
VAR R,P
  REM CHIP_ID(0x00) check: should be 0xD1
  R=I2CREAD(ADDR,0x00)
  IF R!=0xD1 THEN RETURN 0

  REM Soft reset
  I2CWRITE ADDR,0x7E,0xB6
  DELAYMS 100

  REM Configure ODR/BW
  REM ODR=100Hz,BWP=2
  I2CWRITE ADDR,0x40,0x28
  I2CWRITE ADDR,0x42,0x28

  REM Range
  REM ACC:0x05->4g
  REM GYR:0x00->2000dps
  I2CWRITE ADDR,0x41,0x05
  I2CWRITE ADDR,0x43,0x00

  REM Acc Power mode->normal
  I2cwrite ADDR,0x7E,0x11
  DELAYMS 5

  REM Gyr Power mode->normal
  I2CWRITE ADDR,0x7E,0x15
  DELAYMS 100
  
RETURN 1

BMI160からのデータ読み出し

BMI160で計測されたデータはレジスタアドレス0x04から0x17(DATA_0からDATA_19)までに連続して格納されます。このレジスタに格納されるデータの先頭の0x04から0x0Bまでの8バイトはBMI160と接続した外部磁気センサの地磁気とホール抵抗のデータが格納されます。0x0Cから0x17の12バイトにはBMI160のジャイロセンサー、加速度センサーのデータが格納されてます。今回はBMI160のジャイロセンサーと加速度センサーのデータ12バイトを読み取ります。

データは次の表に示すようにLSB、MSBの順に格納されています。

レジスタ データ
0x0C GYR_X<7:0>(LSB)
0x0D GYR_X<15:8>(MSB)
0x0E GYR_Y<7:0>(LSB)
0x0F GYR_Y<15:8>(MSB)
0x10 GYR_Z<7:0>(LSB)
0x11 GYR_Z<15:8>(MSB)
0x12 ACC_X<7:0>(LSB)
0x13 ACC_X<15:8>(MSB)
0x14 ACC_Y<7:0>(LSB)
0x15 ACC_Y<15:8>(MSB)
0x16 ACC_Z<7:0>(LSB)
0x17 ACC_Z<15:8>(MSB)

データ読み出しプログラム

レジスタ0x0Cから12バイトを連続して読み取り、バッファに格納します。格納したデータをもとに角加速度と加速度の値を計算します。下記にそのコードを示します。サブルーチンS16は2つの引数から符号付きのデータを作ります。

レジスタ0x0Cから12バイト分のデータをバッファDに読み込み、先頭から2バイトずつ読み取り角速度と加速度を計算します。

REM ====================================
REM Read 6-axis
LABEL BMI160READ
  I2CREADDATA ADDR,D,12,0x0C

  GX=GOSUB(S16,PEEK(D+ 0),PEEK(D+ 1))
  GY=GOSUB(S16,PEEK(D+ 2),PEEK(D+ 3))
  GZ=GOSUB(S16,PEEK(D+ 4),PEEK(D+ 5))
  AX=GOSUB(S16,PEEK(D+ 6),PEEK(D+ 7))
  AY=GOSUB(S16,PEEK(D+ 8),PEEK(D+ 9))
  AZ=GOSUB(S16,PEEK(D+10),PEEK(D+11))

  GXD#=FLOAT#(GX)/16.4
  GYD#=FLOAT#(GY)/16.4
  GZD#=FLOAT#(GZ)/16.4
  AXG#=FLOAT#(AX)/8192
  AYG#=FLOAT#(AY)/8292
  AZG#=FLOAT#(AZ)/8293

RETURN 1

REM ====================================
REM Convert signed 16bit
LABEL S16
USEVAR LSB,MSB
VAR LSB,MSB,V
  LSB=ARGS(1)
  MSB=ARGS(2)
  V=LSB+MSB*256
  IF V>32767 THEN V=V-65536
RETURN V

プログラム全体

プログラム全体を以下に示します。

BMI160T.BAS
REM ====================================
REM BME160
USEVAR ADDR
USEVAR GX,GY,GZ
USEVAR AX,AY,AZ
USEVAR GXD,GYD,GZD
USEVAR AXG,AYG,AZG

ADDR=0x68
DIM D(12/4)
CLS
I2C
PRINT "Start BME160"

IF GOSUB(BMI160INIT)=0 THEN
  PRINT "Initialize failed"
  END
ENDIF

PRINT "Init OK"

DO
  IF GOSUB(BMI160READ)=1 THEN
    CURSOR 0,3
    PRINT "ACC[g]   X: ";SPRINTF$("%+8.5f",AXG#)
    PRINT "         Y: ";SPRINTF$("%+8.5f",AYG#)
    PRINT "         Z: ";SPRINTF$("%+8.5f",AZG#)
    PRINT "GYR[dps] X: ";SPRINTF$("%+10.5f",GXD#)
    PRINT "         Y: ";SPRINTF$("%+10.5f",GYD#)
    PRINT "         Z: ";SPRINTF$("%+10.5f",GZD#)
  ELSE
    PRINT "Read failed"
    CONTINUE
  ENDIF

  DELAYMS 50

  IF INKEY()!=0 THEN BREAK
LOOP

END

REM ====================================
REM Initialize
REM
LABEL BMI160INIT
VAR R,P
  REM CHIP_ID(0x00) check: should be 0xD1
  R=I2CREAD(ADDR,0x00)
  IF R!=0xD1 THEN RETURN 0

  REM Soft reset
  I2CWRITE ADDR,0x7E,0xB6
  DELAYMS 100

  REM Configure ODR/BW
  REM ODR=100Hz,BWP-2
  I2CWRITE ADDR,0x40,0x28
  I2CWRITE ADDR,0x42,0x28

  REM Range
  REM ACC:0x05->4g
  REM GYR:0x00->2000dps
  I2CWRITE ADDR,0x41,0x05
  I2CWRITE ADDR,0x43,0x00

  REM Power mode->normal
  I2CWRITE ADDR,0x7E,0x11
  DELAYMS 5

  I2CWRITE ADDR,0x7E,0x15
  DELAYMS 100
RETURN 1

REM ====================================
REM Read 6-axis
LABEL BMI160READ
  I2CREADDATA ADDR,D,12,0x0C

  GX=GOSUB(S16,PEEK(D+ 0),PEEK(D+ 1))
  GY=GOSUB(S16,PEEK(D+ 2),PEEK(D+ 3))
  GZ=GOSUB(S16,PEEK(D+ 4),PEEK(D+ 5))
  AX=GOSUB(S16,PEEK(D+ 6),PEEK(D+ 7))
  AY=GOSUB(S16,PEEK(D+ 8),PEEK(D+ 9))
  AZ=GOSUB(S16,PEEK(D+10),PEEK(D+11))

  GXD#=FLOAT#(GX)/16.4
  GYD#=FLOAT#(GY)/16.4
  GZD#=FLOAT#(GZ)/16.4
  AXG#=FLOAT#(AX)/8192
  AYG#=FLOAT#(AY)/8292
  AZG#=FLOAT#(AZ)/8293

RETURN 1

REM ====================================
REM Convert signed 16bit
LABEL S16
USEVAR LSB,MSB
VAR LSB,MSB,V
  LSB=ARGS(1)
  MSB=ARGS(2)
  V=LSB+MSB*256
  IF V>32767 THEN V=V-65536
RETURN V

実行結果

上記のプログラムで加速度、角速度を測定できました。

IMG_3304.jpeg

さいごに

MachiKaniaでBMI160を使って加速度、角速度を測定できるようになりました。今回もChatGPTの力を借り、その結果をもとにBMI160の初期化方法などを確認しました。ChatGPTの力を借りなくてもできるようになりたいですね。

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?