02-11-2021 08:29 AM - edited 02-11-2021 08:29 AM
Hi everyone,
I am working with the BMX055 sensor and using I2C to communicate.
The data value of the accelerometer and gyroscope is correct but the raw data from the magnetometer is quite weird.
I tried to change the direction of the BMX055 sensor in few degrees but its output raw value did not change and. However, when I rotated it in 90 degrees or more the output value of the magnetometer is changed a lot.
Blue: x-axis
Green: y-axis
Red: z-axis
This my code to read the value of the accelerometer, gyroscope, and magnetometer.
#include<Wire.h>
// BMX055 加速度センサのI2Cアドレス
#define Addr_Accl 0x19 // (JP1,JP2,JP3 = Openの時)
// BMX055 ジャイロセンサのI2Cアドレス
#define Addr_Gyro 0x69 // (JP1,JP2,JP3 = Openの時)
// BMX055 磁気センサのI2Cアドレス
#define Addr_Mag 0x13 // (JP1,JP2,JP3 = Openの時)
// センサーの値を保存するグローバル関数
float xAccl = 0.00;
float yAccl = 0.00;
float zAccl = 0.00;
float xGyro = 0.00;
float yGyro = 0.00;
float zGyro = 0.00;
int xMag = 0;
int yMag = 0;
int zMag = 0;
void setup()
{
// Wire(Arduino-I2C)の初期化
Wire.begin();
// デバック用シリアル通信は9600bps
Serial.begin(9600);
//BMX055 初期化
BMX055_Init();
delay(100);
}
void loop()
{
Serial.println("--------------------------------------");
//BMX055 加速度の読み取り
BMX055_Accl();
//Serial.print("Accl= ");
Serial.println(xAccl);
//Serial.print(",");
Serial.println(yAccl);
//Serial.print(",");
Serial.println(zAccl);
//Serial.println("");
//BMX055 ジャイロの読み取り
BMX055_Gyro();
//Serial.print("Gyro= ");
Serial.println(xGyro);
//Serial.print(",");
Serial.println(yGyro);
//Serial.print(",");
Serial.println(zGyro);
//Serial.println("");
//BMX055 磁気の読み取り
BMX055_Mag();
//Serial.print("Mag= ");
Serial.println(xMag);
//Serial.print(",");
Serial.println(yMag);
//Serial.print(",");
Serial.println(zMag);
//Serial.println("");
delay(10);
}
//=====================================================================================//
void BMX055_Init()
{
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Accl);
Wire.write(0x0F); // Select PMU_Range register
Wire.write(0x03); // Range = +/- 2g
Wire.endTransmission();
delay(100);
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Accl);
Wire.write(0x10); // Select PMU_BW register
Wire.write(0x08); // Bandwidth = 7.81 Hz
Wire.endTransmission();
delay(100);
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Accl);
Wire.write(0x11); // Select PMU_LPW register
Wire.write(0x00); // Normal mode, Sleep duration = 0.5ms
Wire.endTransmission();
delay(100);
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Gyro);
Wire.write(0x0F); // Select Range register
Wire.write(0x04); // Full scale = +/- 125 degree/s
Wire.endTransmission();
delay(100);
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Gyro);
Wire.write(0x10); // Select Bandwidth register
Wire.write(0x07); // ODR = 100 Hz
Wire.endTransmission();
delay(100);
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Gyro);
Wire.write(0x11); // Select LPM1 register
Wire.write(0x00); // Normal mode, Sleep duration = 2ms
Wire.endTransmission();
delay(100);
//------------------------------------------------------------//
//// Addr_Mag 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();
delay(100);
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Mag);
Wire.write(0x4C); // Select Mag register
Wire.write(0x00); // Normal Mode, ODR = 10 Hz
Wire.endTransmission();
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Mag);
Wire.write(0x4E); // Select Mag register
Wire.write(0x84); // X, Y, Z-Axis enabled
Wire.endTransmission();
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Mag);
Wire.write(0x51); // Select Mag register
Wire.write(0x04); // No. of Repetitions for X-Y Axis = 9
Wire.endTransmission();
//------------------------------------------------------------//
Wire.beginTransmission(Addr_Mag);
Wire.write(0x52); // Select Mag register
Wire.write(0x16); // No. of Repetitions for Z-Axis = 15
Wire.endTransmission();
}
//=====================================================================================//
void BMX055_Accl()
{
int data[6];
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();
}
// Convert the data to 12-bits
xAccl = ((data[1] * 256) + (data[0] & 0xF0)) / 16;
Serial.println("here");
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;
xAccl = xAccl * 0.0098; // renge +-2g
yAccl = yAccl * 0.0098; // renge +-2g
zAccl = zAccl * 0.0098; // renge +-2g
}
//=====================================================================================//
void BMX055_Gyro()
{
int data[6];
for (int i = 0; i < 6; i++)
{
Wire.beginTransmission(Addr_Gyro);
Wire.write((2 + i)); // Select data register
Wire.endTransmission();
Wire.requestFrom(Addr_Gyro, 1); // Request 1 byte of data
// Read 6 bytes of data
// xGyro lsb, xGyro msb, yGyro lsb, yGyro msb, zGyro lsb, zGyro msb
if (Wire.available() == 1)
data[i] = Wire.read();
}
// Convert the data
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;
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
}
//=====================================================================================//
void BMX055_Mag()
{
int data[8];
for (int i = 0; i < 8; i++)
{
Wire.beginTransmission(Addr_Mag);
Wire.write((0x42 + i)); // Select data register
Wire.endTransmission();
Wire.requestFrom(Addr_Mag, 1); // Request 1 byte of data
// Read 6 bytes of data
// xMag lsb, xMag msb, yMag lsb, yMag msb, zMag lsb, zMag msb
if (Wire.available() == 1)
data[i] = Wire.read();
}
// Convert the data
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;
}
My question is:
1> Is this the correct way(correct registers) to read the magnetometer data?
2> If my code is correct, what happens to my magnetometer raw data?
Thank you
02-19-2021 02:48 AM
Hi Sir:
Recommend you to read the offecial BMM150 api code to know how to get the magetometer data. I don't see you to use trim values after you read the mag data registers.
Please see the following link:
Hopefully, it can help you.