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.
Again for ease to use its easier to buy a module, here is one that I purchased
I also found this schematic online of a module
Connection
Linkit OnePin | MAG3110 Pin |
3v3 | VCC |
GND | GND |
SDA | SDA |
SCL | SCL |
Layout
Code
This example does not require any libraries
[codesyntax lang=”cpp”]
#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); // write 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); // write 0x01, active mode Wire.endTransmission(); // stop transmitting } void print_values(void) { Serial.print("x="); Serial.print(read_x()); Serial.print(","); Serial.print("y="); Serial.print(read_y()); Serial.print(","); Serial.print("z="); Serial.println(read_z()); } int mag_read_register(int reg) { int reg_val; Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E Wire.write(reg); // 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 write less than requested { reg_val = Wire.read(); // read the byte } return reg_val; } int mag_read_value(int msb_reg, int lsb_reg) { int val_low, val_high; //define the MSB and LSB val_high = mag_read_register(msb_reg); delayMicroseconds(2); //needs at least 1.3us free time between start and stop val_low = mag_read_register(lsb_reg); int out = (val_low|(val_high << 8)); //concatenate the MSB and LSB return out; } int read_x(void) { return mag_read_value(0x01, 0x02); } int read_y(void) { return mag_read_value(0x03, 0x04); } int read_z(void) { return mag_read_value(0x05, 0x06); }
[/codesyntax]
Testing
Open up the serial monitor
x=146,y=1045,z=1958
x=145,y=1043,z=1940
x=146,y=1044,z=1945
x=147,y=1046,z=1958
x=142,y=1041,z=1953
x=149,y=1044,z=1950
x=148,y=1041,z=1948
x=150,y=1049,z=1957
x=148,y=1042,z=1949
x=147,y=1044,z=1943
x=146,y=1042,z=1944
x=151,y=1042,z=1955
x=141,y=1042,z=1937