Working with the HMC6352 compass

The compass can be purchased at sparkfun

Image above shows the tiny compass sensor and on the right you can see the visualiser created in processing. The red dot describes the orientation of the compass, it is very accurate and sensitive to rotational movement and the sensors tiny size makes it very usable in wearable projects. The code below is for the compass (found on the arduino forum). I have adjusted only slightly so that it gives a figure over serial that is usable with processing which is right at the bottom of this page.

/**
compassHMC6352v02 10:06 14/01/2009
code grabbed from the arduino forum, some changes have been made but not to the nitty gritty
link: http://forum.sparkfun.com/viewtopic.php?t=6236
**/
#include -Wire.h- 
int HMC6352Address = 0x42; 
int slaveAddress;             // This is calculated in the setup() function 
byte headingData[2]; 
int i, headingValue; 

void setup() 
{ 
  slaveAddress = HMC6352Address >> 1;   // This results in 0x21 as the address to pass to TWI 
  Serial.begin(9600); 
  Wire.begin(); 
} 

void loop() 
{ 
  // Send a "A" command to the HMC6352 
  // This requests the current heading data 
  Wire.beginTransmission(slaveAddress); 
  Wire.send("A");              // The "Get Data" command 
  Wire.endTransmission(); 
  delay(10);                   // The HMC6352 needs at least a 70us (microsecond) delay 
                               // after this command.  Using 10ms just makes it safe  
  // Read the 2 heading bytes, MSB first 
  // The resulting 16bit word is the compass heading in 10th's of a degree 
  // For example: a heading of 1345 would be 134.5 degrees 
  Wire.requestFrom(slaveAddress, 2);        // Request the 2 byte heading (MSB comes first) 
  i = 0; 
  while(Wire.available() && i < 2) 
  {  
    headingData[i] = Wire.receive(); 
    i++; 
  } 
  headingValue = headingData[0]*256 + headingData[1];  // Put the MSB and LSB together 
  Serial.println(int (headingValue));     // The whole number part of the heading 
  delay(100); 
} 

Processing code which visualises the data from the compass (sent from above code).
/**
Code for reading in data from HMC6352 compass (or other)
and visualizing results. 
Pete Rogers 19/12/2008 12.15
**/

import processing.serial.*;

int lf = 10;                  // Linefeed in ASCII
int myWidth = 600;           // stage width
int myHeight = 600;          //stage height
String sensorString = null;   //string  holding raw data from arduino
int sensorInt = 0;            //number from sensor
Serial myPort;                // The serial port 

void setup() {
  size(myWidth, myHeight);    //set up the stage window   
  smooth();                   //make the visual quality high 
//lines below open and configure the serial port
  println(Serial.list()); 
  myPort = new Serial(this, Serial.list()[1], 9600); 
  myPort.clear();            
  sensorString = myPort.readStringUntil(lf); 
  sensorString = null;                       
}

void draw() {
      background(255); //repaints background
      drawCompassGraphics();
      drawCompassDot((sensorInt / 10));
      
}

void drawCompassDot(float rot){
      
      float r = radians(rot);
      translate(myWidth/2,myHeight/2);
      rotate(r);
      fill(255,0,80);
      ellipse(200,0,25,25);
      fill(255,70,180);
      noStroke();
      ellipse(200,0,14,14);      
}

/**
  draws static graphics
**/
void drawCompassGraphics(){
   for (int i = 0; i < 36; i = i + 3){
          stroke(0);
          strokeWeight(4);
          pushMatrix();
          translate(myWidth/2,myHeight/2);
          rotate(radians(i * 10));
          line(230,0,220,0);
          popMatrix(); 
      }
      fill(255);
      stroke(0);
      strokeWeight(4);
      ellipse(myWidth/2,myHeight/2,400,400);
      
}

//serialEvent function is triggered whenever there is data from the arduino
void serialEvent(Serial myPort){
       sensorString = myPort.readStringUntil(lf);
      if ( sensorString != null) {
             sensorString = trim( sensorString);
            sensorInt = int( sensorString);
    }
}