A quick adaptation of a library made for Arduino by Fabio Varesano Interface a Honeywell HMC58X3 magnetometer to a mbed via i2c.

Dependents:   FreeIMU FreeIMU

Fork of HMC58X3 by Aloïs Wolff

Revision:
2:c5ac16c88514
Parent:
1:72ecf7399250
Child:
3:1e0e0c47287a
--- a/HMC58X3.cpp	Mon Jun 24 19:44:55 2013 +0000
+++ b/HMC58X3.cpp	Sat Nov 02 17:23:23 2013 +0000
@@ -42,18 +42,7 @@
 /*!
     Counts/milli-gauss per gain for the self test bias current.
 */
-#if defined(ISHMC5843)
-const int counts_per_milligauss[8]= {
-    1620,
-    1300,
-    970,
-    780,
-    530,
-    460,
-    390,
-    280
-};
-#else // HMC5883L
+
 const int counts_per_milligauss[8]= {
     1370,
     1090,
@@ -64,12 +53,15 @@
     330,
     230
 };
-#endif
+
 
 
 
 /* PUBLIC METHODS */
 
+HMC58X3::HMC58X3():i2c(I2C_SDA,I2C_SCL){
+}
+
 //HMC58X3::HMC58X3(PinName sda, PinName scl): i2c(sda, scl)
 HMC58X3::HMC58X3(I2C i2c_):i2c(i2c_)
 {
@@ -85,7 +77,7 @@
 {
     // note that we don't initialize Wire here.
     // You'll have to do that in setup() in your Arduino program
-    wait_ms(5); // you need to wait at least 5ms after power on to initialize
+    wait_ms(10); // you need to wait at least 5ms after power on to initialize
     if (setmode) {
         setMode(0);
     }
@@ -160,11 +152,11 @@
 */
 bool HMC58X3::calibrate(unsigned char gain,unsigned int n_samples)
 {
-    int xyz[3];                     // 16 bit integer values for each axis.
-    long int xyz_total[3]= {0,0,0}; // 32 bit totals so they won't overflow.
+    int16_t xyz[3];                     // 16 bit integer values for each axis.
+    long xyz_total[3]= {0,0,0}; // 32 bit totals so they won't overflow.
     bool bret=true;                 // Function return value.  Will return false if the wrong identifier is returned, saturation is detected or response is out of range to self test bias.
     char id[3];                     // Three identification registers should return 'H43'.
-    long int low_limit, high_limit;
+    long low_limit, high_limit;
     /*
         Make sure we are talking to the correct device.
         Hard to believe Honeywell didn't change the identifier.
@@ -287,25 +279,26 @@
 void HMC58X3::writeReg(unsigned char reg, unsigned char val)
 {
     i2c.start();
+    i2c.write(HMC58X3_ADDR<<1);
     i2c.write(reg);        // send register address
     i2c.write(val);        // send value to write
     i2c.stop(); //end transmission
 }
 
 
-void HMC58X3::getValues(int *x,int *y,int *z)
+void HMC58X3::getValues(int16_t *x,int16_t *y,int16_t *z)
 {
     float fx,fy,fz;
     getValues(&fx,&fy,&fz);
-    *x= (int) (fx + 0.5);
-    *y= (int) (fy + 0.5);
-    *z= (int) (fz + 0.5);
+    *x= (int16_t) (fx + 0.5);
+    *y= (int16_t) (fy + 0.5);
+    *z= (int16_t) (fz + 0.5);
 }
 
 
 void HMC58X3::getValues(float *x,float *y,float *z)
 {
-    int xr,yr,zr;
+    int16_t xr,yr,zr;
 
     getRaw(&xr, &yr, &zr);
     *x= ((float) xr) / x_scale;
@@ -314,15 +307,15 @@
 }
 
 
-void HMC58X3::getRaw(int *x,int *y,int *z)
+void HMC58X3::getRaw(int16_t *x,int16_t *y,int16_t *z)
 {
 
     char cmd[2];
     char data[6];
     cmd[0] = 0x03;
 
-    i2c.write(I2C_ADDRESS, cmd, 1, true); // set the pointer to the start of x
-    i2c.read(I2C_ADDRESS, data, 6, false);
+    i2c.write(HMC58X3_ADDR<<1, cmd, 1, true); // set the pointer to the start of x
+    i2c.read((HMC58X3_ADDR<<1)+1, data, 6, false);
 
     // read out the 3 values, 2 bytes each.
     *x = int16_t(((unsigned char)data[0] << 8) | (unsigned char)data[1]);
@@ -354,8 +347,11 @@
 void HMC58X3::getID(char id[3])
 {
     i2c.start();
+    i2c.write(HMC58X3_ADDR<<1);
     i2c.write(HMC58X3_R_IDA);             // Will start reading registers starting from Identification Register A.
 
+    i2c.start();
+    i2c.write((HMC58X3_ADDR<<1)+1);
     id[0] = i2c.read(0);
     id[1] = i2c.read(0);
     id[2] = i2c.read(0);