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 件のコメント:
コメントを投稿