Microbit and MAG3110 magnetic sensor example

The MAG3110 is a small, low-power digital 3D magnetic sensor with a wide dynamic range to allow operation in PCBs with high extraneous magnetic fields. The MAG3110:

  • Measures the components of the local magnetic field, the sum of the geomagnetic field and the magnetic field created by components on the circuit board
  • Can be used in conjunction with a 3-axis accelerometer so that orientation-independent accurate compass heading information may be achieved
  • Features a standard I²C serial interface and is capable of measuring local magnetic fields up to 10 Gauss with output data rates up to 80 Hz

 

Features

Layout

 

microbit and MAG3110

microbit and MAG3110

 

Code

 

#include <Wire.h>
#define MAG_ADDR 0x0E //7-bit address for the MAG3110, doesn't change
 
void setup()
{
  Wire.begin(); // join i2c bus (address optional for master)
  Serial.begin(9600); // start serial for output
  config(); // turn the MAG3110 on
}
 
void loop()
{
  print_values();
  delay(500);
}
 
void config(void)
{
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x11); // cntrl register2
  Wire.write(0x80); // send 0x80, enable auto resets
  Wire.endTransmission(); // stop transmitting
  delay(15);
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x10); // cntrl register1
  Wire.write(1); // send 0x01, active mode
  Wire.endTransmission(); // stop transmitting
}
 
void print_values(void)
{
  Serial.print("x=");
  Serial.print(readx());
  Serial.print(",");
  Serial.print("y=");
  Serial.print(ready());
  Serial.print(",");
  Serial.print("z=");
  Serial.println(readz());
}
 
int readx(void)
{
  int xl, xh; //define the MSB and LSB
 
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x01); // x MSB reg
  Wire.endTransmission(); // stop transmitting
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
 
  while(Wire.available()) // slave may send less than requested
  {
    xh = Wire.read(); // receive the byte
  }
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x02); // x LSB reg
  Wire.endTransmission(); // stop transmitting
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
 
  while(Wire.available()) // slave may send less than requested
  {
    xl = Wire.read(); // receive the byte
  }
  int xout = (xl|(xh << 8)); //concatenate the MSB and LSB
  return xout;
}
 
int ready(void)
{
  int yl, yh; //define the MSB and LSB
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x03); // y MSB reg
  Wire.endTransmission(); // stop transmitting
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
 
  while(Wire.available()) // slave may send less than requested
  {
    yh = Wire.read(); // receive the byte
  }
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x04); // y LSB reg
  Wire.endTransmission(); // stop transmitting
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
 
  while(Wire.available()) // slave may send less than requested
  {
    yl = Wire.read(); // receive the byte
  }
  int yout = (yl|(yh << 8)); //concatenate the MSB and LSB
  return yout;
}
 
int readz(void)
{
  int zl, zh; //define the MSB and LSB
 
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x05); // z MSB reg
  Wire.endTransmission(); // stop transmitting
 
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
 
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
 
  while(Wire.available()) // slave may send less than requested
  {
    zh = Wire.read(); // receive the byte
  }
 
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
 
  Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E
  Wire.write(0x06); // z LSB reg
  Wire.endTransmission(); // stop transmitting
  delayMicroseconds(2); //needs at least 1.3us free time between start and stop
  Wire.requestFrom(MAG_ADDR, 1); // request 1 byte
 
  while(Wire.available()) // slave may send less than requested
  {
   zl = Wire.read(); // receive the byte
  }
  int zout = (zl|(zh << 8)); //concatenate the MSB and LSB
  return zout;
}

 

Output

Open the serial monitor window

x=126,y=1552,z=72
x=256,y=1552,z=19
x=259,y=15,z=67
x=124,y=1544,z=67
x=128,y=1545,z=64
x=124,y=1544,z=68
x=0,y=1953,z=513
x=50,y=2082,z=88
x=81,y=1698,z=612
x=186,y=1961,z=65056
x=0,y=1188,z=13
x=258,y=1286,z=65041
x=112,y=1536,z=65113

 

Links

MAG3110 Triple 3 Axis Magnetometer Breakout Electronic Compass Sensor Module For Arduino

Use the micro:bit magnetometer with the Arduino IDE

Freescale’s MAG3110 is a small, low-power, digital 3-axis magnetometer. The device can be used in conjunction with a 3-axis accelerometer to realize an orientation independent electronic compass that can provide accurate heading information. It features a standard I2C serial interface output and smart embedded functions.

The MAG3110 is capable of measuring magnetic fields with an output data rate (ODR) up to 80 Hz; these output data rates correspond to sample intervals from 12.5 ms to several seconds. The MAG3110 is available in a plastic DFN package and it is guaranteed to operate over the extended temperature range of -40°C to +85°C.

You have a micro:bit so you already have one on the board

 

Code

You need to import the Sparkfun library for the MAG3110 to run this example – https://github.com/sparkfun/SparkFun_MAG3110_Breakout_Board_Arduino_Library/archive/master.zip

 

#include <SparkFun_MAG3110.h>
 
MAG3110 mag = MAG3110();
 
void setup() 
{
  Serial.begin(9600);
  mag.initialize(); //Initializes the mag sensor
  mag.start();      //Puts the sensor in active mode
}
 
void loop() {
 
  int x, y, z;
  //Only read data when it's ready
  if(mag.dataReady()) 
  {
    //Read the data
    mag.readMag(&x, &y, &z);
 
    Serial.print("X: ");
    Serial.print(x);
    Serial.print(", Y: ");
    Serial.print(y);
    Serial.print(", Z: ");
    Serial.println(z);
 
    Serial.println("--------");
    delay(1000);
  }
}

 

Testing

Open the serial monitor and move your micro:bit through the various axis, you should see something like this

 

X: 218, Y: 65109, Z: 65274
——–
X: 71, Y: 64965, Z: 49
——–
X: 598, Y: 65036, Z: 248
——–
X: 423, Y: 65338, Z: 564
——–
X: 348, Y: 61, Z: 565
——–
X: 413, Y: 65532, Z: 576
——–
X: 502, Y: 65024, Z: 65352