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モードの有効化ビット
- 4線式SPIモード
- SPI 3線モード
|
| Power Control | : | 電源制御
- サスペンドモード
- スリープモード
|
この特殊制御レジスタはサスペンドモードでもアクセスできます。
ソフトリセットは、両方のビット(レジスタ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 | : | 通常のセルフテスト制御
- 通常動作
- セルフテストモード
|
スケッチ内での設定値は
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状態マッピングの設定
- 無効化
- 有効化
|
| Int Pin En | : | INTピンでの割り込みステータスのマッピングの設定
- 無効化
- 有効化
|
| Channel(CH) Z | : | Z軸と抵抗測定の設定
- 有効化
- 無効化
|
| Channel(CH) Y | : | Y軸の設定
- 有効化
- 無効化
|
| Channel(CH) X | : | X軸の設定
- 有効化
- 無効化
|
| DR Polarity | : | データレディ(DRDY)ピンの極性選択
- active low
- active high
|
| Interrupt Latch | : | 割り込みラッチの選択
- 非ラッチ - 条件が満たされる限り割り込みピンはオン
- ラッチ - レジスタ0x4Aが読み取られるまで割り込みピンはオン
|
| Interrupt Polarity | : | 割り込みピンINT極性選択
- active low
- 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軸のセルフテスト結果フラグ
- セルフテストに失敗した場合
- セルフテストに成功した場合(デフォルト)
|
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軸のセルフテスト結果フラグ
- セルフテストに失敗した場合
- セルフテストに成功した場合(デフォルト)
|
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軸のセルフテスト結果フラグ
- セルフテストに失敗した場合
- セルフテストに成功した場合(デフォルト)
|
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)ステータスビット
- データの読み出しが完了した場合
- データの読み出しが未完了の場合
|
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(テスラ)?
ここで取得された値をそのまま使用する事はなさそうだけど、気になる。。
ホール抵抗の値も同様なんですけどね。
おまけ
色々疑問は残ったままではあるのすが、セルフテストについての解説。
通常のセルフテストの手順
- スリープモード(OpMode = “11”)に設定
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Mag);
Wire.write(0x4C); // Select Magレジスタを選択
Wire.write(0x06); // スリープモード, ODR = 10 Hz
Wire.endTransmission();
- セルフテストの有効化(Self Test = “1”)
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Mag);
Wire.write(0x4C); // Select Magレジスタを選択
Wire.write(0x01); // 通常モード, ODR = 10 Hz
Wire.endTransmission();
セルフテストの実行後、このビット(Self Test)は“0”に戻ります。
- セルフテスト結果フラグ(SelfTestX, SelfTestY, SelfTestZ)への反映
- セルフテストに失敗した場合
- セルフテストに成功した場合
拡張セルフテストの手順
拡張セルフテストは、Zチャネル信号パスの機能と感度の検証を行います。
- スリープモード(OpMode = “11”)に設定
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Mag);
Wire.write(0x4C); // Select Magレジスタを選択
Wire.write(0x06); // スリープモード, ODR = 10 Hz
Wire.endTransmission();
- 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();
- Z方向の繰り返しを任意のレベルに設定
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Mag);
Wire.write(0x52); // Select Magレジスタを選択
Wire.write(0x16); // No. of Repetitions for Z-Axis = 15
Wire.endTransmission();
- 正の拡張セルフテスト電流の有効化と強制モードの設定
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Mag);
Wire.write(0x4C); // Select Magレジスタを選択
Wire.write(0xC2); // 強制モード, ODR = 10 Hz
Wire.endTransmission();
- 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;
- 負の拡張セルフテスト電流の有効化と強制モードの設定
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Mag);
Wire.write(0x4C); // Select Magレジスタを選択
Wire.write(0x82); // 強制モード, ODR = 10 Hz
Wire.endTransmission();
- 5.と同じくz軸の磁界データとホール抵抗値の読み込み
- 拡張セルフテスト電流を無効にします
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Mag);
Wire.write(0x4C); // Select Magレジスタを選択
Wire.write(0x00); // 通常モード, ODR = 10 Hz
Wire.endTransmission();
- 2つの補正フィールド値の差を計算します
この差はマージンのある約200µTとなります。
- Soft Resetを実行します
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Mag);
Wire.write(0x4B); // Select Magレジスタを選択
Wire.write(0x83); // スリープモード, ODR = 10 Hz
Wire.endTransmission();
実際に試した限りでは、マージンがあるとは言え約200µTの差分からは大きく離れている値になっていました。何か間違えてるのかな?
まだまだ学ぶべき事が多そうな気配。
0 件のコメント:
コメントを投稿