OwenDuffy.net 


Arduino Magnetometer - a tutorial

This tutorial shows how to explore an inexpensive HMC5883 3 axis magnetometer module with Arduino.

The magnetometer module can be purchased on eBay at very low cost (<$3), and is an ideal educational project for the budding Arduino practitioner.

It is an ideal low cost project for a first exploration of explore I2C, and the basis for a digital compass. This particular module breaks out DRDY which is useful for interrupt driven applications.

Fig 1:
 

Fig 1 shows the test setup:

Fig 2:
/*
An Arduino code example for interfacing with the HMC5883

by: Jordan McConnell
SparkFun Electronics
created on: 6/30/11
license: OSHW 1.0, http://freedomdefined.org/OSHW

Analog input 4 I2C SDA
Analog input 5 I2C SCL
*/

//Modified by Owen Duffy 2013/12/10 for Arduino 1.05 compatibility

#include <Wire.h> //I2C Arduino Library

#define address 0x1E //0011110b, I2C 7bit address of HMC5883

void setup(){
//Initialize Serial and I2C communications
Serial.begin(9600);
Wire.begin();

//Put the HMC5883 IC into the correct operating mode
Wire.beginTransmission(address); //open communication with HMC5883
Wire.write(0x02); //select mode register
Wire.write(0x00); //continuous measurement mode
Wire.endTransmission();
}

void loop(){

int x,y,z; //triple axis data

//Tell the HMC5883 where to begin reading data
Wire.beginTransmission(address);
Wire.write(0x03); //select register 3, X MSB register
Wire.endTransmission();


//Read data from each axis, 2 registers per axis
Wire.requestFrom(address, 6);
if(6<=Wire.available()){
x = Wire.read()<<8; //X msb
x |= Wire.read(); //X lsb
z = Wire.read()<<8; //Z msb
z |= Wire.read(); //Z lsb
y = Wire.read()<<8; //Y msb
y |= Wire.read(); //Y lsb
}

//Print out values of each axis
Serial.print("x: ");
Serial.print(x);
Serial.print(" y: ");
Serial.print(y);
Serial.print(" z: ");
Serial.println(z);

delay(250);
}

Fig 2 shows the example source code. The project uses v1.05 Arduino IDE. Arduino libraries to not maintain backwards compatibility and this code may not run in earlier versions. The project uses an example sketch from Sparkfun. The source code is modified for compatibility with Arduino v1.05 Wire library.

Fig 3:
 

Fig 3 shows the waveforms captured on the SCL and SDA pins, the I2C transaction to read the clock. Only the first bytes of the transaction are shown.

Fig 4:
IndexTimeHex
0-1.75 μsSTART
13.25 μs0x3c
293.75 μsACK
398.75 μs0x03
4190.00 μsACK
5210.00 μsSTOP
6220.00 μsSTART
7225.00 μs0x3d
8315.50 μsACK
9320.50 μs0x01
10410.25 μsACK
11415.25 μs0x63
12506.50 μsACK
13511.50 μs0x04
14602.75 μsACK
15607.75 μs0x31
16699.00 μsACK
17704.00 μs0x00
18795.25 μsACK
19800.25 μs0x63
20891.25 μsNACK
21912.75 μsSTOP

Fig 4 shows an analysis of the complete read transaction.

The student of I2C should be able to take the DS1307 data sheet and the dump in Fig 5 and verify the reading process.

Links

Changes

Version Date Description
1.01 07/12/2013 Initial.
1.02    
1.03    
1.04    
1.05    

 


© Copyright: Owen Duffy 1995, 2021. All rights reserved. Disclaimer.