9軸センサーモージュールBMX055の使い方、サンプルソース解説

 秋月から9軸センサーモジュール(BMX055)を入手しようとしたら、現在在庫切れとなっていました。販売ページにデータシートとサンプルソースがアップされていたため、物は無いけどとりあえず予習ということで中身を確認してみました。覚書ついでにサンプルソースコードの中身を解説です。

▼この製品です。ここからサンプルソースコードとかダウンロードできます(2022年/2月)▼

このモジュールはI2Cでマイコンなどと通信しますが、ここではI2C通信方法の詳細は割愛します。。

▼I2C通信方法はこちら▼

スポンサーリンク

セットアップ部分

 まずはセットアップ部分からです。ソースを抜粋しながら見ていきます。

加速度センサーの初期設定

 最初に加速度センサーの初期設定です。ここでは測定レンジ、帯域幅、スリープモード(パワーモード)の設定を行っています。

  Wire.beginTransmission(Addr_Accl);
  Wire.write(0x0F);   // Select PMU_Range register
  Wire.write(0x03);   // Range = +/- 2g
  Wire.endTransmission();

▲加速度の測定レンジを設定してます。加速度センサーのアドレス[Addr_Accl]は「0x19」。レンジ設定するレジスタアドレスは「0x0F」。続けて設定値は「0x03」(±2G)となってます。スケールレンジは以下の値から設定可能。

2進数16進数加速度測定レンジ
0011b0x03±2G
0101b0x05±4G
1000b0x08±8G
1100b0x0C±16G
加速度センサーのレンジ設定

▼次に帯域幅(Bandwidth)の設定部分▼

  Wire.beginTransmission(Addr_Accl);
  Wire.write(0x10);  // Select PMU_BW register
  Wire.write(0x08);  // Bandwidth = 7.81 Hz
  Wire.endTransmission();

 ここで帯域幅の設定してます。レジスタアドレスは「0x10」。設定値「0x08」(7.81Hz)となってます。帯域幅は以下値から設定可能。

2進数16進数帯域幅
01000b0x087.81Hz
01001b0x0915.63Hz
01010b0x0A31.25Hz
01011b0x0B62.5Hz
01100b0x0C125Hz
01101b0x0D250Hz
01110b0x0E500Hz
01111b0x0F1000Hz

▼最後にパワーモードの設定▼

  Wire.beginTransmission(Addr_Accl);
  Wire.write(0x11);  // Select PMU_LPW register
  Wire.write(0x00);  // Normal mode, Sleep duration = 0.5ms
  Wire.endTransmission();
  delay(100);

 加速度センサーのパワーモードを設定してます。「0x11」レジスタアドレスで、スリープやサスペンドの設定ができます。がデータシート見たのですが細かいところはよくわからなかったです。

 加速度センサーの設定は以上。続いてジャイロセンサーの設定です。

スポンサーリンク

ジャイロセンサーの初期設定

 ジャイロセンサーのデバイスアドレスは「0x69」となってます。基本、加速センサーと同様な項目(レンジ、帯域幅、スリープモード)を設定している箇所です。

▼まずは測定レンジの設定部分▼

  Wire.beginTransmission(Addr_Gyro);
  Wire.write(0x0F);  // Select Range register
  Wire.write(0x04);  // Full scale = +/- 125 degree/s
  Wire.endTransmission();

 ここでジャイロのレンジ設定。アドレスは「0x0F」。設定値は「0x04」(±125deg/s)となってます。ジャイロのスケールレンジは以下から設定可能。

2進数16進数測定レンジ
000b0x00±2000deg/s
001b0x01±1000deg/s
010b0x02±500deg/s
011b0x03±250deg/s
100b0x04±125deg/s

▼続いて出力レートの設定部分▼

  Wire.beginTransmission(Addr_Gyro);
  Wire.write(0x10);  // Select Bandwidth register
  Wire.write(0x07);  // ODR = 100 Hz
  Wire.endTransmission();

 レジスタアドレスは「0x10」で設定値は「0x07」(100Hz)です。ここもいくつかの値(以下)から選択することが可能です。

2進数16進数出力レート帯域幅
0111b0x07100Hz32Hz
0110b0x06200Hz64Hz
0101b0x05100Hz12Hz
0100b0x04200Hz23Hz
0011b0x03400Hz47Hz
0010b0x021000Hz116Hz
0001b0x012000Hz230Hz
0000b0x002000Hz無し

▼最後にパワーモードの設定▼

  Wire.beginTransmission(Addr_Gyro);
  Wire.write(0x11);  // Select LPM1 register
  Wire.write(0x00);  // Normal mode, Sleep duration = 2ms
  Wire.endTransmission();

 加速度センサーと同様(NormalMode)の設定がされてます。

 最後に地磁気センサーの設定です。

地磁気センサーの初期設定

 地磁気センサーのアドレスは「0x13」となります。基本は加速度やジャイロと同じような初期設定項目ですが若干違うところがあります。

 //------------------------------------------------------------//
  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x4B);  // Select Mag register
  Wire.write(0x83);  // Soft reset
  Wire.endTransmission();
  delay(100);
  //------------------------------------------------------------//
  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x4B);  // Select Mag register
  Wire.write(0x01);  // Soft reset
  Wire.endTransmission();

 まず最初にソフトリセットを掛けてそのあと、パワーコントロールbitを「1」にしてます。ここはおまじないと思ってこう記述するもんだと覚えましょう。

▼出力レート設定▼

  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x4C);  // Select Mag register
  Wire.write(0x00);  // Normal Mode, ODR = 10 Hz

 地磁気センサーの出力レート設定は「0X4C」アドレスとなります。ここでは「0x00」(10Hz)で設定されてます。出力レートは以下の値から選択可能。

2進数16進数レート
000b0x0010Hz(デフォルト)
001b0x012Hz
010b0x026Hz
011b0x038Hz
100b0x0415Hz
101b0x0520Hz
110b0x0625Hz
111b0x0730Hz

 あと地磁気センサーにレピティションの設定とかの記述があるのですが中身の細かいところはよくわからないです。。。

 次にセンサー値を読み出す部分です。

スポンサーリンク

センサー値の取得

 ここからは加速度、ジャイロ、地磁気のセンサー値の取得部分になります。読み込んだ値をbit値から物理量に変換している部分です。

加速度センサー値の取得&変換

  for (int i = 0; i < 6; i++)
  {
    Wire.beginTransmission(Addr_Accl);
    Wire.write((2 + i));// Select data register
    Wire.endTransmission();
    Wire.requestFrom(Addr_Accl, 1);// Request 1 byte of data
    // Read 6 bytes of data
    // xAccl lsb, xAccl msb, yAccl lsb, yAccl msb, zAccl lsb, zAccl msb
    if (Wire.available() == 1)
      data[i] = Wire.read();
  }

 ここで加速度をビット値で読みだしてます。加速度値はアドレス「0x02」から6byte分で格納されてます。各軸、2byteずつ、計6byte分です。読みだした値をdata[]に順に格納してます。

  xAccl = ((data[1] * 256) + (data[0] & 0xF0)) / 16;
  if (xAccl > 2047)  xAccl -= 4096;
  yAccl = ((data[3] * 256) + (data[2] & 0xF0)) / 16;
  if (yAccl > 2047)  yAccl -= 4096;
  zAccl = ((data[5] * 256) + (data[4] & 0xF0)) / 16;
  if (zAccl > 2047)  zAccl -= 4096;

 ここで読み出した値を各軸ごとに振り分けてます。最初に各軸値の2byte分を結合して、16bit ⇒ 12bitデータへマスク。で次に正負の符号付き値にしてます。これを3軸分(3回)繰り返してます。個人的にはあまり好きな記述ではないです。

  xAccl = xAccl * 0.0098; // range = +/-2g
  yAccl = yAccl * 0.0098; // range = +/-2g
  zAccl = zAccl * 0.0098; // range = +/-2g

 加速度値をbit値 ⇒ 物理量(G)に変換してます。正確には設定レンジが±2Gなので2/4096でLSBは0.00097656…となります。次にジャイロセンサーの読み取り部分です。

スポンサーリンク

ジャイロセンサー値の取得&変換

読み取り部分は加速度センサーと同じなので割愛。結合するところから微妙に違います。

  xGyro = (data[1] * 256) + data[0];
  if (xGyro > 32767)  xGyro -= 65536;
  yGyro = (data[3] * 256) + data[2];
  if (yGyro > 32767)  yGyro -= 65536;
  zGyro = (data[5] * 256) + data[4];
  if (zGyro > 32767)  zGyro -= 65536;

 ジャイロ値を各軸ごとに振り分けてるところです。ジャイロは加速度センサーと違い16bit値なので、結合して、正負値に変えてるだけです。

  xGyro = xGyro * 0.0038; //  Full scale = +/- 125 degree/s
  yGyro = yGyro * 0.0038; //  Full scale = +/- 125 degree/s
  zGyro = zGyro * 0.0038; //  Full scale = +/- 125 degree/s

 ここでbit値から物理量(deg/s)へ変換してます。250/65536でLSBは0.00381469…。。最後に地磁気センサーの値読み取りです。

地磁気センサー値の取得

 最後に地磁気センサー値の取得です。

  xMag = ((data[1] <<5) | (data[0]>>3));
  if (xMag > 4095)  xMag -= 8192;
  yMag = ((data[3] <<5) | (data[2]>>3));
  if (yMag > 4095)  yMag -= 8192;
  zMag = ((data[5] <<7) | (data[4]>>1));
  if (zMag > 16383)  zMag -= 32768;

 ここで読み取った値を各軸値に結合してます。地磁気は13bit値のようです。物理量には変換してなくbit値のまま。

 ソース内容はだいたいこんなところです。サンプルソースは単純に取得した値を物理量に変換してそれをシリアル出力しているだけ。取得した値(ジャイロ、加速度、地磁気)をつかって姿勢角度算出したり、ドリフト補正したりするのは自分でやる必要がありそうです。

コメント