2020年1月21日火曜日

AE-BMX055の地磁気センサーだけ使ってみた。

AE-BMX055とESP-WROOM-02の接続の続きです。
地磁気センサーのみに絞っての調査となっています。
加速度センサーは、"AE-BMX055の加速度センサーだけ使ってみた。"を参照。

下記のスケッチは、Arduinoサンプルプログラムの地磁気センサーの箇所のみを抜粋、I2Cアドレスを変更、編集したものです。
BMX055_MAGNETOMETER
#include <Wire.h>
// BMX055 磁気センサのI2Cアドレス
#define Addr_Mag  0x10  // (JP1,JP2,JP3 = Closeの時)

// センサーの値を保存するグローバル関数
int xMag  = 0;
int yMag  = 0;
int zMag  = 0;

void setup()
{
  // Wire(Arduino-I2C)の初期化
  Wire.begin();
  // デバック用シリアル通信は9600bps
  Serial.begin(9600);
  //BMX055 初期化
  //------------------------------------------------------------//
  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x4B);  // Magレジスタを選択
  Wire.write(0x83);  // Soft reset
  Wire.endTransmission();
  delay(100);
  //------------------------------------------------------------//
  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x4B);  //  Magレジスタを選択
  Wire.write(0x01);  // Soft reset
  Wire.endTransmission();
  delay(100);
  //------------------------------------------------------------//
  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x4C);  // Magレジスタを選択
  Wire.write(0x00);  // Normal Mode, ODR = 10 Hz
  Wire.endTransmission();
  //------------------------------------------------------------//
  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x4E);  // Magレジスタを選択
  Wire.write(0x84);  // X, Y, Z-Axis enabled
  Wire.endTransmission();
  //------------------------------------------------------------//
  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x51);  // Magレジスタを選択
  Wire.write(0x04);  // No. of Repetitions for X-Y Axis = 9
  Wire.endTransmission();
  //------------------------------------------------------------//
  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x52);  // Magレジスタを選択
  Wire.write(0x16);  // No. of Repetitions for Z-Axis = 15
  Wire.endTransmission();
}

void loop()
{
  //BMX055 磁気の読み取り
  int data[8];
  for (int i = 0; i < 8; i++)
  {
    Wire.beginTransmission(Addr_Mag);
    Wire.write((0x42 + i));         // データレジスタを選択
    Wire.endTransmission();
    Wire.requestFrom(Addr_Mag, 1);  // 1バイトのデータを要求する
    // 6バイトのデータを読み取る
    // xMag lsb, xMag msb, yMag lsb, yMag msb, zMag lsb, zMag msb
    if (Wire.available() == 1)
      data[i] = Wire.read();
  }
  // データを変換する
  xMag = ((data[1] <<8) | (data[0]>>3));
  if (xMag > 4095)  xMag -= 8192;
  yMag = ((data[3] <<8) | (data[2]>>3));
  if (yMag > 4095)  yMag -= 8192;
  zMag = ((data[5] <<8) | (data[4]>>3));
  if (zMag > 16383)  zMag -= 32768;
  Serial.println("--------------------------------------"); 
  Serial.print("Mag= ");
  Serial.print(xMag);
  Serial.print(",");
  Serial.print(yMag);
  Serial.print(",");
  Serial.print(zMag);
  Serial.println(""); 
  
  delay(1000);
}
以降では、スケッチ内で使用されているレジスタアドレスをピックアップ。

BMX055地磁気センサーの初期化

地磁気センサーを初期化するためのレジスタアドレスと設定値です。
詳細はデータシートを参照。

推奨プリセットは、以下のように既定されている。
プリセット Rep. X/Y nXY Rep. Z nZ 推奨 ODR [Hz] 強制モードでの 最大 ODR fmax,ODR [Hz] RMS ノイズ x/y/z [µT] 推奨ODRでの 平均消費電流 [mA]
低電力設定値 3 3 10 >300 1.0/1.0/1.4 0.17
通常設定値 9 15 10 100 0.6/0.6/0.6 0.5
拡張設定値 15 27 10 60 0.5/0.5/0.5 0.8
高精度設定値 47 83 20 20 0.3/0.3/0.3 4.9
以降での設定値は、これらの"通常設定値"を基準にしている。 //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x4B); // Select Magレジスタを選択 Wire.write(0x83); // Soft reset Wire.endTransmission(); delay(100); //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x4B); // Select Magレジスタを選択 Wire.write(0x01); // Soft reset Wire.endTransmission(); delay(100);

MAG Register (0x4B) Read/Write

レジスタ(0x4B)には、電源制御、ソフトリセット、SPIモード選択のための制御ビットが含まれています。
Bit 7 6 5 4 3 2 1 0
Content Soft Reset fixed SPI3En Soft Reset Power Control
Default Value 0 0 0 0 0 0 0 1 0x01
Soft Reset:ソフトリセットトリガービット
fixed:(0に固定)
SPI3En:SPI3モードの有効化ビット
  1. 4線式SPIモード
  2. SPI 3線モード
Power Control:電源制御
  1. サスペンドモード
  2. スリープモード
この特殊制御レジスタはサスペンドモードでもアクセスできます。 ソフトリセットは、両方のビット(レジスタ0x4Bのbit7とbit1)が“1”に設定されたときに実行されます。ソフトリセットは、常にデバイスをスリープモードにします。デバイスがサスペンドモード(bit0が“0”)の場合、ソフトリセットは無視され、デバイスはサスペンドモードのままになります。
Bit 7 6 5 4 3 2 1 0
Content Soft Reset fixed SPI3En Soft Reset Power Control
Soft Reset 1 0 0 0 0 0 1 1 0x83
ソフトリセットでは、完全なPOR(Power-On Reset)シーケンスが実行されませんが、レジスタ0x54より上位の“トリム”レジスタと電力制御レジスタ(0x4B)を除くすべてのレジスタがリセットされます。2つの"Soft Reset"ビットは、ソフトリセットが完了すると自動的に“0”にリセットされます。 完全なPORリセットを実行するには、デバイスをサスペンドモード(bit0を“0”)にしてからスリープモード(bit0を“1”)に戻します。 AE-BMX055ではSPI接続出来ないためSPIモード選択の"SPI3En"は“0”で固定。 スケッチ内での設定値は0x83に設定後0x01を再設定していますが、上記で知り得た内容を本にすると0x01は不要と思われます。 //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x4C); // Select Magレジスタを選択 Wire.write(0x00); // Normal Mode, ODR = 10 Hz Wire.endTransmission();

MAG Register (0x4C) Read/Write

レジスタ (0x4C) には、動作モード、出力データレート、およびセルフテスト用の制御ビットが含まれています。
Bit 7 6 5 4 3 2 1 0
Content Adv. ST Data rate Opmode Self Test
Default Value 0 0 0 0 0 1 1 0 0x06
Adv. ST:拡張セルフテスト
Adv.ST 構成
7 6
0 0 通常動作(セルフテストなし)
0 1 使用不可
1 0 負のオンチップ磁場生成
1 1 正のオンチップ磁場生成
Data rate:データレート制御
Data rate Output Data Rate
5 4 3
0 0 0 10Hz
0 0 1 2Hz
0 1 0 6Hz
0 1 1 8Hz
1 0 0 15Hz
1 0 1 20Hz
1 1 0 25Hz
1 1 1 30Hz
Opmode:動作モード制御
Opmode 磁力計の動作モード
2 1
0 0 通常モード
0 1 強制モード
1 0 使用不可
1 1 スリープモード
Self Test:通常のセルフテスト制御
  1. 通常動作
  2. セルフテストモード
スケッチ内での設定値は0x00 //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x4E); // Select Magレジスタを選択 Wire.write(0x84); // X, Y, Z-Axis enabled Wire.endTransmission();

MAG Register (0x4E) Read/Write

レジスタ (0x4E) には、制御ビット割り込み設定と軸有効化ビットが含まれています。磁気測定チャネルが無効になっている場合、最後に測定された磁気出力値はデータレジスタに残ります。Zチャンネルが無効になっている場合、抵抗測定も無効になり、抵抗出力値はゼロに設定されます。割り込みが無効になっている軸でトリガーするように設定されている場合、これらの割り込みは最後の測定値に基づいてアサートされます。
Bit 7 6 5 4 3 2 1 0
Content Data Ready Pin En Int Pin En CH Z CH Y CH X DR Polarity Int Latch Int Polarity
Default Value 0 0 0 0 0 1 1 1 0x07
Data Ready Pin En:DRDYピンでのData Ready状態マッピングの設定
  1. 無効化
  2. 有効化
Int Pin En:INTピンでの割り込みステータスのマッピングの設定
  1. 無効化
  2. 有効化
Channel(CH) Z:Z軸と抵抗測定の設定
  1. 有効化
  2. 無効化
Channel(CH) Y:Y軸の設定
  1. 有効化
  2. 無効化
Channel(CH) X:X軸の設定
  1. 有効化
  2. 無効化
DR Polarity:データレディ(DRDY)ピンの極性選択
  1. active low
  2. active high
Interrupt Latch:割り込みラッチの選択
  1. 非ラッチ - 条件が満たされる限り割り込みピンはオン
  2. ラッチ - レジスタ0x4Aが読み取られるまで割り込みピンはオン
Interrupt Polarity:割り込みピンINT極性選択
  1. active low
  2. active high
スケッチ内での設定値は0x84。 この値による設定は、
Bit 7 6 5 4 3 2 1 0
Content Data Ready Pin En Int Pin En CH Z CH Y CH X DR Polarity Int Latch Int Polarity
Default Value 1 0 0 0 0 1 0 0 0x84
となるので、初期値からの変化は、Int Pin Enの有効化、Interrupt Latchの非ラッチ、Interrupt Polarityをactive lowとなります。 //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x51); // Select Magレジスタを選択 Wire.write(0x04); // No. of Repetitions for X-Y Axis = 9 Wire.endTransmission();

MAG Register (0x51) Read/Write

レジスタ (0x51) には、x / y軸の反復回数が含まれています。
Bit 7 6 5 4 3 2 1 0
Content REPXY
Default Value 0 0 0 0 0 0 0 0 0x00
繰り返しの実行回数nXYは、レジスタ0x51のBit 7~0をb7~b0として、次のように符号なしレジスタ値からnXY = 1+2xREPXYとして計算できます: nXY = 1+2(b7x27+b6x26+b5x25+b4x24+b3x23+b2x22+b1x21+b0x20) nXY = 1+2(REPXY)
REPXY:レジスタの値に応じたx / y軸の反復回数
REPXY 反復回数
7 6 5 4 3 2 1 0 HEX
0 0 0 0 0 0 0 0 0x00 1
0 0 0 0 0 0 0 1 0x01 3
0 0 0 0 0 0 1 0 0x02 5
0 0 0 0 0 0 1 1 0x03 7
1 1 1 1 1 1 0 1 0xFD 507
1 1 1 1 1 1 1 0 0xFE 509
1 1 1 1 1 1 1 1 0xFF 511
スケッチ内での設定値は0x04 //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x52); // Select Magレジスタを選択 Wire.write(0x16); // No. of Repetitions for Z-Axis = 15 Wire.endTransmission();

MAG Register (0x52) Read/Write

レジスタ (0x51) には、z軸の反復回数が含まれています。
Bit 7 6 5 4 3 2 1 0
Content REPZ
Default Value 0 0 0 0 0 0 0 0 0x00
繰り返しの実行回数nZは、レジスタ0x52のBit 7~0をb7~b0として、次のように符号なしレジスタ値からnZ = 1+REPZとして計算できます: nZ = 1+(b7x27+b6x26+b5x25+b4x24+b3x23+b2x22+b1x21+b0x20) nZ = 1+REPZ
REPZ:レジスタの値に応じたz軸のの反復回数
REPZ 反復回数
7 6 5 4 3 2 1 0 HEX
0 0 0 0 0 0 0 0 0x00 1
0 0 0 0 0 0 0 1 0x01 2
0 0 0 0 0 0 1 0 0x02 3
0 0 0 0 0 0 1 1 0x03 4
1 1 1 1 1 1 0 1 0xFD 254
1 1 1 1 1 1 1 0 0xFE 255
1 1 1 1 1 1 1 1 0xFF 256
スケッチ内での設定値は0x16。 ただし、この設定値では反復回数が23となってしまいます。Z-Axis = 15が通常設定値なので、0x0Eが本来の設定値だと思われます。

BMX055地磁気センサーの値の読み込み

地磁気センサーから磁束密度を取得するためのレジスタアドレスを確認します。
詳細はデータシートを参照。
  //BMX055 加速度の読み取り
  int data[8];
  for (int i = 0; i < 8; i++)
  {
    Wire.beginTransmission(Addr_Mag);
    Wire.write((0x42 + i));         // データレジスタを選択
    Wire.endTransmission();
    Wire.requestFrom(Addr_Mag, 1);  // 1バイトのデータを要求する
    // 6バイトのデータを読み取る
    // xMag lsb, xMag msb, yMag lsb, yMag msb, zMag lsb, zMag msb
    if (Wire.available() == 1)
      data[i] = Wire.read();
  }

MAG Register (0x42) Read Only

レジスタ(0x42)には、x軸磁界データのLSB部分とx軸のセルフテスト結果フラグが格納されています。
Bit 7 6 5 4 3 2 1 0
Content DATAX_lsb fixed Self TestX
DATAX_lsb:X軸磁界データ13ビットの下位5ビット(2の補数形式)
fixed:(0に固定)
SelfTestX:X軸のセルフテスト結果フラグ
  1. セルフテストに失敗した場合
  2. セルフテストに成功した場合(デフォルト)

MAG Register (0x43) Read Only

レジスタ (0x43) には、x軸磁界データのMSB部分が含まれています。
Bit 7 6 5 4 3 2 1 0
Content DATAX_msb
DATAX_msb:X軸磁界データ13ビットの上位8ビット(2の補数形式)

MAG Register (0x44) Read Only

レジスタ(0x44)には、y軸磁界データのLSB部分とy軸のセルフテスト結果フラグが格納されています。
Bit 7 6 5 4 3 2 1 0
Content DATAY_lsb fixed Self TestY
DATAY_lsb:Y軸磁界データ13ビットの下位5ビット(2の補数形式)
fixed:(0に固定)
SelfTestY:Y軸のセルフテスト結果フラグ
  1. セルフテストに失敗した場合
  2. セルフテストに成功した場合(デフォルト)

MAG Register (0x45) Read Only

レジスタ (0x44) には、y軸磁界データのMSB部分が含まれています。
Bit 7 6 5 4 3 2 1 0
Content DATAY_msb
DATAY_msb:Y軸磁界データ13ビットの上位8ビット(2の補数形式)

MAG Register (0x46) Read Only

レジスタ (0x46) には、z軸の磁界データのLSB部分とz軸のセルフテスト結果フラグが含まれています。
Bit 7 6 5 4 3 2 1 0
Content DATAZ_lsb Self TestZ
DATAZ_lsb:Z軸磁界データ15ビットの下位7ビット(2の補数形式)
SelfTestZ:Z軸のセルフテスト結果フラグ
  1. セルフテストに失敗した場合
  2. セルフテストに成功した場合(デフォルト)

MAG Register (0x47) Read Only

レジスタ (0x47) には、z軸磁界データのMSB部分が含まれています。
Bit 7 6 5 4 3 2 1 0
Content DATAZ_msb
DATAZ_msb:Z軸磁界データ15ビットの上位8ビット(2の補数形式)

MAG Register (0x48) Read Only

レジスタ (0x48) には、ホール抵抗のLSB部分とData Ready (DRDY) ステータスビットが含まれています。
Bit 7 6 5 4 3 2 1 0
Content RHALL_lsb fixed Data Ready Status
RHALL_lsb:ホール抵抗14ビットの下位6ビット
fixed:(0に固定)
Data Ready Status:Data Ready (DRDY)ステータスビット
  1. データの読み出しが完了した場合
  2. データの読み出しが未完了の場合

MAG Register (0x49) Read Only

レジスタ (0x49) には、ホール抵抗のMSB部分が含まれています。
Bit 7 6 5 4 3 2 1 0
Content RHALL_msb
RHALL_msb:ホール抵抗14ビットの上位8ビット

取得した値の処理

スケッチの中での処理を個別に記載して確認。
以降では、xMag、yMag、zMagを"Mag"。data[1]、data[3]、data[5]をDATA_msb、data[0]、data[2]、data[4]をDATA_lsbにまとめて表記しています。
  // データを変換する
  Mag = ((DATA_msb <<8) | (DATA_lsb >>3));
まず、上位ビット"DATA_msb"の処理。
(DATA_msb <<8)
左に8ビットシフトしています。
つまり、
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Content blank DATA_msb
の状態を、左に8ビットずらして、
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Content DATA_msb blank
とした事を指します。 同様に、下位ビット"DATA_lsb"の (DATA_lsb >>3) は、右に3ビットシフトを意味し、
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Content blank DATA_lsb fixed Self Test
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Content blank DATA_lsb
の様に再配置した状態となります。 最後にOR演算子で、以下2つを演算します。
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Content DATA_msb blank
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Content blank DATA_lsb
これにより、
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Content DATA_msb blank DATA_lsb
のように2つの数値が1つにまとめられます。 が、DATA_msbとDATA_lsbの間にblankが入り込んでます。 間違ってますよね???。。。恐らく、
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Content blank DATA_msb DATA_lsb
にするには、 // データを変換する Mag = ((DATA_msb <<8) | DATA_lsb) >>3); が正しいと思われます。 更に言うと、X / Yは13ビットですが、Zは15ビットなので、
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Content blank DATA_msb DATA_lsb
にするには、 // データを変換する Mag = ((DATA_msb <<8) | DATA_lsb) >>1); と、しないと正確な値が取得出来ません。 ここまで取得した値は2の補数となるので、符号を付けるために以下の条件判定を行っています。 if (xMag > 4095) xMag -= 8192; if (yMag > 4095) yMag -= 8192; if (zMag > 16383) zMag -= 32768; xMag、yMagでは12ビットの最大値(4095)以上であれば13ビットの上限数(8192)で減算し、zMagでは14ビットの最大値(16383)以上であれば15ビットの上限数(32768)で減算する事で正負の符号が割り当てられるようになっています。

"ここまで"のまとめ

"ここまで"色々と問題点も確認しつつ進めてきましたが、修正していない状態でスケッチを実際に動作させてみます。
--------------------------------------
Mag= 56579,56857,32279
--------------------------------------
Mag= 56580,56861,32279
--------------------------------------
Mag= 56578,56858,32279
--------------------------------------
Mag= 56579,56860,32279
--------------------------------------
Mag= 56577,56861,32280


結果として不適切な値が返ってきます。
次に、ここまで知り得た情報を元にしてスケッチを修正してみます。
BMX055_MAGNETOMETER
#include <Wire.h>
// BMX055 磁気センサのI2Cアドレス
#define Addr_Mag  0x10  // (JP1,JP2,JP3 = Closeの時)

// センサーの値を保存するグローバル関数
int Mag[4];

void setup()
{
  // Wire(Arduino-I2C)の初期化
  Wire.begin();
  // デバック用シリアル通信は9600bps
  Serial.begin(9600);
  //BMX055 初期化
  //------------------------------------------------------------//
  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x4B);  // Magレジスタを選択
  Wire.write(0x83);  // Soft reset
  Wire.endTransmission();
  delay(100);
  //------------------------------------------------------------//
  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x4C);  // Magレジスタを選択
  Wire.write(0x00);  // Normal Mode, ODR = 10 Hz
  Wire.endTransmission();
  //------------------------------------------------------------//
  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x4E);  // Magレジスタを選択
  Wire.write(0x84);  // X, Y, Z-Axis enabled
  Wire.endTransmission();
  //------------------------------------------------------------//
  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x51);  // Magレジスタを選択
  Wire.write(0x04);  // No. of Repetitions for X-Y Axis = 9
  Wire.endTransmission();
  //------------------------------------------------------------//
  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x52);  // Magレジスタを選択
  Wire.write(0x0E);  // No. of Repetitions for Z-Axis = 15
  Wire.endTransmission();
}
void loop()
{
  //BMX055 磁気の読み取り
  short int data[8];
  Wire.beginTransmission(Addr_Mag);
  Wire.write(0x42);                     // データレジスタを選択
  Wire.endTransmission();
  Wire.requestFrom(Addr_Mag, 8, false); // 8バイトのデータを要求する
  for (int i = 0; i < 8; i++)
    data[i] = Wire.read();
  // データを変換する
  bitWrite(data[0], 15, bitRead(data[1], 7));
  Mag[0] = ((data[1] <<8) | data[0]) >>3;
  //if (Mag[0] > 4095)  Mag[0] -= 8192;
  bitWrite(data[2], 15, bitRead(data[3], 7));
  Mag[1] = ((data[3] <<8) | data[2]) >>3;
  //if (Mag[1] > 4095)  Mag[1] -= 8192;
  bitWrite(data[4], 15, bitRead(data[5], 7));
  Mag[2] = ((data[5] <<8) | data[4]) >>1;
  //if (Mag[2] > 16383) Mag[2] -= 32768;
  Mag[3] = ((data[7] <<8) | data[6]) >>2;
  Serial.println("--------------------------------------"); 
  Serial.print("Mag= ");
  Serial.print(Mag[0]);
  Serial.print(",");
  Serial.print(Mag[1]);
  Serial.print(",");
  Serial.print(Mag[2]);
  Serial.print(",");
  Serial.print(Mag[3]);
  Serial.println(); 
  delay(100);
}
実行してみると、
--------------------------------------
Mag= -93,1,-194,6280
--------------------------------------
Mag= -94,0,-198,6279
--------------------------------------
Mag= -94,2,-193,6280
--------------------------------------
Mag= -94,0,-193,6278
--------------------------------------
Mag= -93,1,-194,6277


先ほどと違ってかなり"それらしい"値が返ってきました。
単位はμT(テスラ)?
ここで取得された値をそのまま使用する事はなさそうだけど、気になる。。
ホール抵抗の値も同様なんですけどね。

おまけ

色々疑問は残ったままではあるのすが、セルフテストについての解説。

通常のセルフテストの手順

  1. スリープモード(OpMode = “11”)に設定 //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x4C); // Select Magレジスタを選択 Wire.write(0x06); // スリープモード, ODR = 10 Hz Wire.endTransmission();
  2. セルフテストの有効化(Self Test = “1”) //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x4C); // Select Magレジスタを選択 Wire.write(0x01); // 通常モード, ODR = 10 Hz Wire.endTransmission(); セルフテストの実行後、このビット(Self Test)は“0”に戻ります。
  3. セルフテスト結果フラグ(SelfTestX, SelfTestY, SelfTestZ)への反映
    1. セルフテストに失敗した場合
    2. セルフテストに成功した場合

拡張セルフテストの手順

拡張セルフテストは、Zチャネル信号パスの機能と感度の検証を行います。
  1. スリープモード(OpMode = “11”)に設定 //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x4C); // Select Magレジスタを選択 Wire.write(0x06); // スリープモード, ODR = 10 Hz Wire.endTransmission();
  2. X、Y軸を無効化 0x4Eの初期値0x07にbit4:CH Y/bit3:CH Xを"1"にした値0x1Fを設定。 //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x4E); // Select Magレジスタを選択 Wire.write(0x1F); // only Z-Axis enabled Wire.endTransmission();
  3. Z方向の繰り返しを任意のレベルに設定 //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x52); // Select Magレジスタを選択 Wire.write(0x16); // No. of Repetitions for Z-Axis = 15 Wire.endTransmission();
  4. 正の拡張セルフテスト電流の有効化と強制モードの設定 //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x4C); // Select Magレジスタを選択 Wire.write(0xC2); // 強制モード, ODR = 10 Hz Wire.endTransmission();
  5. z軸の磁界データとホール抵抗値の読み込み float MagZ; short int data[4]; Wire.beginTransmission(Addr_Mag); Wire.write(0x46); // データレジスタを選択 Wire.endTransmission(); Wire.requestFrom(Addr_Mag, 8, false); // 4バイトのデータを要求する for (int i = 0; i < 4; i++) data[i] = Wire.read(); // データを変換する bitWrite(data[0], 15, bitRead(data[1], 7)); MagZ = ((data[1] <<8) | data[0]) >>1;
  6. 負の拡張セルフテスト電流の有効化と強制モードの設定 //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x4C); // Select Magレジスタを選択 Wire.write(0x82); // 強制モード, ODR = 10 Hz Wire.endTransmission();
  7. 5.と同じくz軸の磁界データとホール抵抗値の読み込み
  8. 拡張セルフテスト電流を無効にします //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x4C); // Select Magレジスタを選択 Wire.write(0x00); // 通常モード, ODR = 10 Hz Wire.endTransmission();
  9. 2つの補正フィールド値の差を計算します この差はマージンのある約200µTとなります。
  10. Soft Resetを実行します //------------------------------------------------------------// Wire.beginTransmission(Addr_Mag); Wire.write(0x4B); // Select Magレジスタを選択 Wire.write(0x83); // スリープモード, ODR = 10 Hz Wire.endTransmission();
実際に試した限りでは、マージンがあるとは言え約200µTの差分からは大きく離れている値になっていました。何か間違えてるのかな? まだまだ学ぶべき事が多そうな気配。

0 件のコメント:

コメントを投稿