Categories

Demo: HMC6352 digital compass breakout board

Posted on Monday, February 1st, 2010 in Bus Pirate, demonstrations by Ian

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.

This entry was posted on Monday, February 1st, 2010 at 11:17 am and is filed under Bus Pirate, demonstrations. You can follow any responses to this entry through the RSS 2.0 feed. You can skip to the end and leave a response. Pinging is currently not allowed.

10 Responses to “Demo: HMC6352 digital compass breakout board”

  1. Rubi says:

    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. Ian says:

    No, I just tried it indoors, but it seemed correct.

  3. Rob says:

    I just used it indoors at well, and its amazingly accurate

  4. tushar says:

    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

    • tushar says:

      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

      • Chirag says:

        @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..

      • Ian says:

        14K sounds too big, try 2K.

  5. Chirag says:

    @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..

    • Chirag says:

      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++);
      }
      }
      }

  6. Chirag says:

    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 Reply

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

Recent Comments

  • lostengineer: hahaha an entire article just saying to heat-shrink your wires or glue them if they might move around a lot. When did common sense die?
  • readybrek: They're tasty tasty very very tasty... they're very tasty.
  • hli: Sunday++
  • Chamod: Check on your buddy. Make sure they don't forget their lunchbox.
  • Kurt: But February made me shiver With every paper I'd deliver Bad news on the doorstep I couldn't take one more step