Item code: 29133
What It Can Do
- Measures the earth’s magnetic field in three axes, with a 1–2 degree accuracy
- Provides individual readings for each axis, which may be used separately or together for 3D calculations
- Measures raw strength (gauss) of a nearby magnetic source
The 3-Axis Compass module measures magnetic fields in three directions – or axes, labeled X, Y, and Z. In its most simple form, the module can be used as a basic compass to find earth’s magnetic north.
The compass module can also sense the relative strength of a nearby magnetic source, such as those caused by magnets or electric fields. As the sensor detects magnetism in three dimensions, it can determine relative distance and direction to these sources.
The compass is commonly used with a multi-axis accelerometer, where the data from both sensors can provide useful information detailing speed and direction of travel. The Memsic 2125 Dual-axis Accelerometer and MMA7455 3-Axis Accelerometer Module are good companion accelerometers for the 3-Axis Gyroscope module
It may also be used with an accelerometer and 3-axis gyroscope to construct a 9-axis IMU (intertial measurement unit), common in unmanned aerial vehicles, such as drones and quadcopters.
Parts List
- 3-Axis Compass module
- BASIC Stamp HomeWork Board, Propeller BOE, Propeller QuickStart, or Arduino Uno microcontroller (with breadboard, as needed)
- 22 gauge solid conductor hookup wire
Basic Wiring
- Power Requirements: 2.7 to 6.5 VDC
- Communication Interface: I2C (up to 400 kHz)
- Dimensions: 0.725 x 0.650 in (1.8 x 1.7 cm)
Program KickStarts
The KickStart examples display raw data output for each of the three axes. Values are retrieved from the module using the I2C interface.
BASIC Stamp HomeWork Board
Download BASIC Stamp 2 code for the Compass Module
’ {$STAMP BS2} ’ {$PBASIC 2.5} SDA PIN 0 ’ SDA of compass to pin P0 SCL PIN 1 ’ SCL of compass to pin P1 WRITE_Data CON $3C ’ Requests Write operation READ_Data CON $3D ’ Requests Read operation MODE CON $02 ’ Mode setting register X_MSB CON $03 ’ X MSB data output register X VAR Word Y VAR Word Z VAR Word rawl VAR Word rawh VAR Word ’ Variables for I2C communications I2C_DATA VAR Byte I2C_LSB VAR Bit I2C_REG VAR Byte I2C_VAL VAR Byte PAUSE 100 ’ Power up delay I2C_REG = MODE ’ Set operating mode to continuous I2C_VAL = $0 GOSUB I2C_Write_Reg DO GOSUB GetRawReading ’ Get raw Compass reading DEBUG HOME, "X = ",11, SDEC x, CR ’ Print values DEBUG "Y = ",11, SDEC y, CR DEBUG "Z = ",11, SDEC z, CR DEBUG CR LOOP GetRawReading: PAUSE 400 ’ Wait for new data ’ Send request to X MSB register GOSUB I2C_Start I2C_DATA = WRITE_Data GOSUB I2C_Write I2C_DATA = X_MSB GOSUB I2C_Write GOSUB I2C_Stop ’Get data from register (6 bytes total, 2 bytes per axis) GOSUB I2C_Start I2C_DATA = READ_Data GOSUB I2C_Write ’ Get X GOSUB I2C_Read rawH = I2C_Data GOSUB I2C_ACK GOSUB I2C_Read rawL = I2C_Data GOSUB I2C_ACK X = (rawH << 8) | rawL ’ Get Z GOSUB I2C_Read rawH = I2C_Data GOSUB I2C_ACK GOSUB I2C_Read rawL = I2C_Data GOSUB I2C_ACK Z = (rawH << 8) | rawL ’ Get Y GOSUB I2C_Read rawH = I2C_Data GOSUB I2C_ACK GOSUB I2C_Read rawL = I2C_Data GOSUB I2C_NACK Y = (rawH << 8) | rawL GOSUB I2C_Stop RETURN ’---------I2C functions------------ ’ Set I2C_REG & I2C_VAL before calling this I2C_Write_Reg: GOSUB I2C_Start I2C_DATA = WRITE_DATA GOSUB I2C_Write I2C_DATA = I2C_REG GOSUB I2C_Write I2C_DATA = I2C_VAL GOSUB I2C_Write GOSUB I2C_Stop RETURN ’ Set I2C_REG before calling this, I2C_DATA will have result I2C_Read_Reg: GOSUB I2C_Start I2C_DATA = WRITE_DATA GOSUB I2C_Write I2C_DATA = I2C_REG GOSUB I2C_Write GOSUB I2C_Stop GOSUB I2C_Start I2C_DATA = READ_DATA GOSUB I2C_Write GOSUB I2C_Read GOSUB I2C_NACK GOSUB I2C_Stop RETURN I2C_Start: LOW SDA LOW SCL RETURN I2C_Stop: LOW SDA INPUT SCL INPUT SDA RETURN I2C_ACK: LOW SDA INPUT SCL LOW SCL INPUT SDA RETURN I2C_NACK: INPUT SDA INPUT SCL LOW SCL RETURN I2C_Read: SHIFTIN SDA, SCL, MSBPRE, [I2C_DATA] RETURN I2C_Write: I2C_LSB = I2C_DATA.BIT0 I2C_DATA = I2C_DATA / 2 SHIFTOUT SDA, SCL, MSBFIRST, [I2C_DATA7] IF I2C_LSB THEN INPUT SDA ELSE LOW SDA INPUT SCL LOW SCL INPUT SDA INPUT SCL LOW SCL RETURN
When this program is run, the BASIC Stamp Debug Terminal will automatically open.
Propeller BOE and Propeller QuickStart
Propeller BOE Wiring Diagram
Propeller QuickStart Wiring Diagram
Download Propeller Spin code for the Compass Module
OBJ pst : "FullDuplexSerial" ’ Comes with Propeller Tool CON _clkmode = xtal1 + pll16x _clkfreq = 80_000_000 datapin = 1 ’ SDA of compass to pin P1 clockPin = 0 ’ SCL of compass to pin P0 WRITE_DATA = $3C ’ Requests Write operation READ_DATA = $3D ’ Requests Read operation MODE = $02 ’ Mode setting register OUTPUT_X_MSB = $03 ’ X MSB data output register VAR long x long y long z PUB Main waitcnt(clkfreq/100_000 + cnt) ’ Power up delay pst.start(31, 30, 0, 115200) SetCont repeat SetPointer(OUTPUT_X_MSB) getRaw ’ Gather raw data from compass pst.tx(1) ShowVals PUB SetCont ’ Sets compass to continuous output mode start send(WRITE_DATA) send(MODE) send($00) stop PUB SetPointer(Register) ’ Start pointer at user specified register (OUT_X_MSB) start send(WRITE_DATA) send(Register) stop PUB GetRaw ’ Get raw data from continuous output start send(READ_DATA) x := ((receive(true) << 8) | receive(true)) z := ((receive(true) << 8) | receive(true)) y := ((receive(true) << 8) | receive(false)) stop ~~x ~~z ~~y x := x z := z y := y PUB ShowVals ’ Display XYZ compass values pst.str(string("X=")) pst.dec(x) pst.str(string(", Y=")) pst.dec(y) pst.str(string(", Z=")) pst.dec(z) pst.str(string(" ")) PRI send(value) value := ((!value) >< 8) repeat 8 dira[dataPin] := value dira[clockPin] := false dira[clockPin] := true value >>= 1 dira[dataPin] := false dira[clockPin] := false result := !(ina[dataPin]) dira[clockPin] := true dira[dataPin] := true PRI receive(aknowledge) dira[dataPin] := false repeat 8 result <<= 1 dira[clockPin] := false result |= ina[dataPin] dira[clockPin] := true dira[dataPin] := aknowledge dira[clockPin] := false dira[clockPin] := true dira[dataPin] := true PRI start outa[dataPin] := false outa[clockPin] := false dira[dataPin] := true dira[clockPin] := true PRI stop dira[clockPin] := false dira[dataPin] := false
To view the results of the demonstration, after uploading is complete run the Parallax Serial Terminal from the Run menu or press F12. Click the Enable button, and momentarily depress the Reset button on the Propeller QuickStart board to restart the program.
Arduino Uno
Download Arduino Code for the Compass Module
#include <Wire.h> #define Addr 0x1E // 7-bit address of HMC5883 compass void setup() { Serial.begin(9600); delay(100); // Power up delay Wire.begin(); // Set operating mode to continuous Wire.beginTransmission(Addr); Wire.write(byte(0x02)); Wire.write(byte(0x00)); Wire.endTransmission(); } void loop() { int x, y, z; // Initiate communications with compass Wire.beginTransmission(Addr); Wire.write(byte(0x03)); // Send request to X MSB register Wire.endTransmission(); Wire.requestFrom(Addr, 6); // Request 6 bytes; 2 bytes per axis if(Wire.available() <=6) { // If 6 bytes available x = Wire.read() << 8 | Wire.read(); z = Wire.read() << 8 | Wire.read(); y = Wire.read() << 8 | Wire.read(); } // Print raw values Serial.print("X="); Serial.print(x); Serial.print(", Y="); Serial.print(y); Serial.print(", Z="); Serial.println(z); delay(500); }
To view the results of the demonstration, after uploading is complete click the Serial Monitor icon in the Arduino IDE. This displays the Serial Monitor window. Momentarily depress the Reset button on the Arduino board to restart the sketch.
For More Information
- 3-Axis Compass (#29133) data sheet and application notes
- More information on magnetometers and other forms of digital compasses may be found on Wikipedia: Magnetometer
- Combine the 3-axis compass with the Memsic 2125 Dual-Axis Accelerometer, or MM7455 3-Axis Accelerometer
- Combine the 3-axis compass with the Parallax MMA7455 3-Axis Accelerometer Module and Gyroscope Module 3-Axis L3G4200D to create a 9-axis inertial momentum unit (IMU)