Demo: HMC6352 digital compass breakout board

This is an old version, see the latest version on the documentation wiki.

The HMC6352 is a simple compass chip with an I2C interface. If your next unmanned vehicle needs a compass, check out this chip. It has multiple operating modes that balance power use and update frequency. Continuous acquisition provides rapid heading updates, while query acquisitions save power by only measuring only when it’s needed.

Thanks to SparkFun for sending this part to demo. If you don’t want to solder the 24pin lead-less chip yourself, you can get it on a breakout board at SparkFun.

Demo: is a weekly series that demonstrates devices with the Bus Pirate. Come back next Monday for another all new demo.

You can preorder assembled Bus Pirate hardware at Seeed Studio for $30, including worldwide shipping.


Device: Honeywell Magnetic Sensor (HMC6352) on breakout board ($34.95).
Bus: I2C (pull-up resistors required).
Power requirements: 2.7-5.2 volts.
References: datasheet, SparkFun breakout board.
Complete Bus Pirate session log for this demonstration.

Bus Pirate HMC6352
MOSI SDA
CLOCK SCL
+3.3volts out VCC
GND GND
Vpullup VCC

We connected the Bus Pirate to the breakout board as shown in the table above. The compass is powered by the Bus Pirate’s on-board 3.3volt supply. I2C is a high-impedance bus that requires pull-up resistors, so we used the on-board pull-up resistors with the Vpu pin connected to the 3.3volt power supply.

Bus Pirate setup

Press ‘m’ for the mode menu and choose I2C. Configure the I2C library for any speed.

At the I2C prompt, enable the power supplies (W) and on-board pull-up resistors (menu p). Get a voltage report (v) to verify that the power supplies are active and that the Vpullup pin is connected to the 3.3volt supply.

Interfacing the chip

I2C>(1) <<<I2C address scan macro
Searching 7bit I2C address space.
Found devices at:
0x42(0x21 W) 0x43(0x21 R)
I2C>

I2C devices respond to a read and write address. The I2C address for the HMC6352 is on page 3 of the datasheet. We used the Bus Pirate I2C address search macro as a shortcut. This devices responds to 0x42 and 0x43.

Unlike most I2C devices, the HMC6352 I2C address can be modified by writing a new value to the internal EEPROM. Read more about this feature under I2C slave address on page 7 of the datasheet.

I2C>[0x42 0x41]
I2C START BIT
WRITE: 0x42 ACK <<<HMC6352 write address
WRITE: 0x41 ACK <<<‘A’, acquire compass heading
I2C STOP BIT
I2C>

The HMC6352 has a lot of advanced features like calibration, power-saving sleep features, and continuous reading modes. We’re going to demonstrate the bare minimum requirements to get a single compass measurement from the chip.

Start the I2C transaction with a start bit ([). Send the write address (0x42) and ‘A’ to start a heading acquisition. End the I2C transaction with a stop bit (]).

I2C>[0x43 rr]
I2C START BIT
WRITE: 0x43 ACK <<<HMC6352 read address
READ: 0x0B ACK  <<< compass heading MSB
READ: 0x7F NACK <<<compass heading LSB
I2C STOP BIT
I2C>

Read two bytes back to get the heading.  The fist byte is the most significant 8bits of the heading, the second byte is the least significant 8bits. The heading is given in 0.1degree resolution.

0x0b7f is 2943 in decimal, divide by ten to find the degree heading of 294.3degrees (WNW).

I2C>[0x42 0x41]
I2C START BIT
WRITE: 0x42 ACK <<<HMC6352 write address
WRITE: 0x41 ACK<<<‘A’, acquire compass heading
I2C STOP BIT
I2C>[0x43 rr]
I2C START BIT
WRITE: 0x43 ACK <<<HMC6352 read address
READ: 0x00 ACK <<< compass heading MSB
READ: 0x5A NACK <<< compass heading LSB
I2C STOP BIT
I2C>

We rotate the compass and try it again. This time we get 0x005A (90 decimal), divide by ten to find a heading of 9degrees (North).

Taking it further

Check the Bus Pirate manual for a complete list of chip demonstrations. Requests are always appreciated.

Join the Conversation

10 Comments

  1. Cool, I think I have to try this chip.
    Did you compare indoor use to outdoor usage ?
    Most digital compass solutions work very poor indoor.

    Cheers
    Rubi

  2. hello……m interfcing hmc6352 wid p89v51rd2….m following d sequence of instructions given by u…..but out of the 2 bytes m getting the frst byte successfully…bt nt the 2nd one…….my SDA pin is continuously high after the first byte………help me out

    1. Hello Tushar!
      I am also interfacing HMC6352 with 8051. I am able to write the ‘A’ command and receive the acknowledegment but I haven’t able to recieve the data and our all the bytes are continously low.

      Have you been able to receive both the bytes and can you help me to get the data?

      Tushar
      New Delhi

      1. @Tushar..
        Hmm, am not able to get acknowledgement at all .. am using HMC6352 wid 5V and 14k pullup.. Am not sure whether pull-up value is correct, could you please mail me the pull up and code used..! Plz.. really stuck at this from 2 weeks..

  3. @Ian: Thanks for your guidance.. i ll try that asap…

    Code:
    #include
    #include
    bit data_bit;
    void main()
    {
    int i,j;
    unsigned char byte1,byte2;
    TMOD=0x20;
    TH1=0xFD;
    SCON=0x50;
    TR1=1;
    while(1)
    {
    I2C_start();
    data_bit=I2C_write(‘A’);
    if(data_bit)
    {
    SBUF=’e’;
    while(TI==0);
    TI=0 ;
    I2C_stop();
    }
    else
    {
    byte1=I2C_read();
    I2C_clock();
    byte2=I2C_read();
    I2C_clock();
    I2C_stop();
    SBUF=byte1;
    while(TI==0);
    TI=0 ;
    SBUF=byte2;
    while(TI==0);
    TI=0;
    }
    for(j=0;j<100;j++)
    {
    for(i=0;i<1235;i++);
    }
    }
    }

    and i2c.h can be found at
    http://p89v51-sdcc.googlecode.com/svn/trunk/p89v51-sdcc/I2C/i2c.h

    could you please cross-check the code..

    1. Sorry… the code used is:
      #include
      #include
      bit data_bit;
      void main()
      {
      int i,j;
      unsigned char byte1,byte2;
      TMOD=0x20;
      TH1=0xFD;
      SCON=0x50;
      TR1=1;
      while(1)
      {
      I2C_start();
      data_bit=I2C_write(0x42);
      if(data_bit)
      {
      SBUF=’e’;
      while(TI==0);
      TI=0 ;
      I2C_stop();
      }
      else
      {
      data_bit=I2C_write(‘A’);
      I2C_stop();
      I2C_start();
      data_bit=I2C_write(0x43);
      byte1=I2C_read();
      I2C_clock();
      byte2=I2C_read();
      I2C_clock();
      I2C_stop();
      SBUF=byte1;
      while(TI==0);
      TI=0 ;
      SBUF=byte2;
      while(TI==0);
      TI=0;
      }
      for(j=0;j<100;j++)
      {
      for(i=0;i<1235;i++);
      }
      }
      }

  4. I suppose that the code i mentioned is giving correct first reading but it only worked for few minutes, and is not working now, i used pull up of 14k with 8051 i.e 5V …. just noticed that when IC is connected to the pull-up circuit the equivalent resistance between Vcc and SDA / SCL lines fall to 7.5 ohms.. is it normal , can any one help in debugging..
    Thanks..

Leave a comment

Leave a Reply to Rubi Cancel reply

Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail. You can also subscribe without commenting.