Example of reading and magnetometer sensor (HMC5883L)

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
jose_claudiojr
Date:
Tue May 21 13:48:10 2013 +0000
Commit message:
Example of reading and magnetometer sensor (HMC5883L)

Changed in this revision

HMC5883L.cpp Show annotated file Show diff for this revision Revisions of this file
HMC5883L.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 6bc5f85ca6fa HMC5883L.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HMC5883L.cpp	Tue May 21 13:48:10 2013 +0000
@@ -0,0 +1,133 @@
+#include "HMC5883L.h"
+
+HMC5883L::HMC5883L(PinName sda, PinName scl): i2c(sda, scl)
+{
+    //100KHz, as specified by the datasheet.
+    char rx;
+
+    
+    i2c.frequency(100000);
+    //Testar depois com 400KHz
+    //==========================================================================================================
+    // Read chip_id
+    //==========================================================================================================
+    rx = Read(HMC5883L_IDENT_A);
+    if (rx != 0x48)//ID do chip
+        printf("\ninvalid chip id %d\r\n", rx); 
+     
+    //==========================================================================================================
+    // Let's set the Configuration Register A
+    //==========================================================================================================
+    // This register set's the number of samples averaged per measurement output, the rate at which data is written
+    // to all three data output registers and the measurement flow of the device.
+    // -------------------------------------------------------
+    // |CRA7 CRA6   CRA5   CRA4   CRA3   CRA2   CRA1   CRA0  |
+    // |(1)  MA1(1) MA0(1) DO2(1) DO1(0) DO0(0) MS1(0) MS0(0)| -> This is the default value
+    // -------------------------------------------------------
+    // CRA7 -> we have to clear this bit for correct operation                                      (0)
+    // CRA6 to CRA5 -> Let's select the maximum number of samples averaged per measurement output   (11)
+    // CRA4 to CRA2 -> Also let's select the maximum data output rate                               (110)
+    // CRA1 to CRA0 -> The measurement flow is defined to normal                                    (00)
+    // -------------------------------------------------------
+    // |CRA7 CRA6   CRA5   CRA4   CRA3   CRA2   CRA1   CRA0  |
+    // |(0)  MA1(1) MA0(1) DO2(1) DO1(1) DO0(0) MS1(0) MS0(0)| -> This is the new value, 0x78 in hex
+    // -------------------------------------------------------
+    //Write(HMC5883L_CONFIG_A,0x78);
+    //Write(HMC5883L_CONFIG_A,0x70);
+        
+    //==========================================================================================================
+    // The Configuration Register B is set to 0010 0000 by default, this is a +/- 1.3 Ga sensor field range and
+    // the gain of LSB/gauss is 1090. This is the maximum value, so let's leave it like that.
+    //==========================================================================================================
+    //Datasheet page 13. I will explain later
+    //Write(HMC5883L_CONFIG_B,0x20);
+    //Write(HMC5883L_CONFIG_B,0xA0);
+  
+    //==========================================================================================================
+    // Let's set the Mode Register
+    //==========================================================================================================
+    // This register set's the operation mode, from continuous-measurements mode, single-measurement mode and idle mode.
+    // We will set to Continuouse-measurement mode, so the device continuously performs measurements and places the
+    // result in the data register
+    // ---------------------------------------------
+    // |MR7  MR6  MR5  MR4  MR3  MR2  MR1    MR0   |  -> This is the new value, 0x78 in hex, we are going to change
+    // |(1)  (0)  (0)  (0)  (0)  (0)  MD1(0) MD0(1)|     the MD1 and MD0 to 00 and clear the MR7 for correct operation.
+    // ---------------------------------------------     The final value is 0000 0000 (0x00).
+    Write(HMC5883L_MODE,0x00);
+}
+
+
+void HMC5883L::Write(char reg_address, char data)
+{
+    char tx[2];
+    tx[0]=reg_address;
+    tx[1]=data;
+
+    i2c.write(HMC5883L_I2C_WRITE,tx,2);
+}
+
+char HMC5883L::Read(char data)
+{
+    char tx = data;
+    char rx;
+
+    i2c.write(HMC5883L_I2C_WRITE, &tx, 1);
+    i2c.read(HMC5883L_I2C_READ, &rx, 1);
+    return rx;
+}
+
+void HMC5883L::MultiByteRead(char address, char* output, int size) 
+{
+    i2c.write(HMC5883L_I2C_WRITE, &address, 1);      //tell it where to read from
+    i2c.read(HMC5883L_I2C_READ, output, size);     //tell it where to store the data read
+}
+
+float HMC5883L::getMx()
+{
+    //return (x * m_Scale);
+    char lsb_byte = 0;
+    signed short msb_byte;
+
+    lsb_byte = Read(HMC5883L_X_MSB);
+    msb_byte = lsb_byte << 8;
+    msb_byte |= Read(HMC5883L_X_LSB);
+    return (float)msb_byte;
+    /*
+    char tx[1];
+    char rx[2];
+
+
+    tx[0]=HMC5883L_X_MSB;
+    i2c.write(HMC5883L_I2C_READ,tx,1);
+    i2c.read(HMC5883L_I2C_READ,rx,2);
+    return ((int)rx[0]<<8|(int)rx[1]);
+    */
+
+}
+
+float HMC5883L::getMy()
+{
+    //return (y * m_Scale);
+
+    char lsb_byte = 0;
+    signed short msb_byte;
+
+    lsb_byte = Read(HMC5883L_Y_MSB);
+    msb_byte = lsb_byte << 8;
+    msb_byte |= Read(HMC5883L_Y_LSB);
+    return (float)msb_byte;
+}
+
+
+float HMC5883L::getMz()
+{
+    //return (z * m_Scale);
+    
+    char lsb_byte = 0;
+    signed short msb_byte;
+
+    lsb_byte = Read(HMC5883L_Z_MSB);
+    msb_byte = lsb_byte << 8;
+    msb_byte |= Read(HMC5883L_Z_LSB);
+    return (float)msb_byte;
+ }
\ No newline at end of file
diff -r 000000000000 -r 6bc5f85ca6fa HMC5883L.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HMC5883L.h	Tue May 21 13:48:10 2013 +0000
@@ -0,0 +1,41 @@
+#ifndef HMC5883L_H
+#define HMC5883L_H
+
+#include "mbed.h"
+
+#define HMC5883L_IDENT_A        0x0A // In this case the identification register A is used to identify the devide. ASCII value H
+#define HMC5883L_I2C            0x1E // 7-bit address. 0x3C write, 0x3D read.
+#define HMC5883L_I2C_WRITE      0x3C // Same as (& 0xFE), ensure that the MSB bit is being set to zero (RW=0 -> Writing)
+#define HMC5883L_I2C_READ       0x3D // Same as (| 0x01), ensure that the MSB bit is being set to one  (RW=1 -> Reading)
+
+#define HMC5883L_CONFIG_A       0x00
+#define HMC5883L_CONFIG_B       0x01
+#define HMC5883L_MODE           0x02
+#define HMC5883L_STATUS         0x09
+
+#define HMC5883L_X_MSB          0x03
+#define HMC5883L_X_LSB          0x04
+#define HMC5883L_Z_MSB          0x05
+#define HMC5883L_Z_LSB          0x06
+#define HMC5883L_Y_MSB          0x07
+#define HMC5883L_Y_LSB          0x08
+
+
+class HMC5883L 
+{
+
+public:
+
+    HMC5883L(PinName sda, PinName scl);
+    float getMx();
+    float getMy();
+    float getMz();
+private:
+    void Write(char reg_address, char data);
+    char Read(char data);
+    void MultiByteRead(char address, char* output, int size); 
+    I2C i2c;
+    
+};
+
+#endif /* HMC5883L_H */
\ No newline at end of file
diff -r 000000000000 -r 6bc5f85ca6fa main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue May 21 13:48:10 2013 +0000
@@ -0,0 +1,69 @@
+#include "mbed.h"
+#include "HMC5883L.h"
+
+#include <math.h>
+
+#define SDA      p9
+#define SCL      p10
+#define PI       3.14159265
+
+int main()
+{      
+    float x, y, z, heading;
+    /*
+    float m_x, m_y, m_z;
+    */
+    printf("Inicializing...\r\n");
+    HMC5883L hmc5883l(SDA, SCL);
+    //HMC5883L *hmc5883l = new HMC5883L(SDA, SCL);
+    printf("OK...\r\n");
+    /*
+    for (int i = 0 ; i < 100 ; i++)
+    {
+        x += hmc5883l.getMx()/100;
+        y += hmc5883l.getMy()/100;
+        z += hmc5883l.getMz()/100;
+        wait_ms(100);
+    }
+    
+
+    m_x = x/2;
+    m_y = y/2;
+    m_z = z/2;
+    */
+    wait(1);
+
+    while(1) 
+    { 
+        /*
+        x = m_x - hmc5883l.getMx()*0.92;
+        y = m_y - hmc5883l.getMy()*0.92;
+        z = m_z - hmc5883l.getMz()*0.92;
+        */
+        x = hmc5883l.getMx();
+        y = hmc5883l.getMy();
+        z = hmc5883l.getMz();
+        
+        heading = atan2(y, x);
+        if(heading < 0) 
+            heading += 2*PI;
+        if(heading > 2*PI) 
+            heading -= 2*PI;
+        
+        heading = heading * 180 / PI;
+        
+        // Correct for when signs are reversed.
+        //if(heading < 0) 
+        //    heading += 2*PI;
+        //if(heading > 2*PI) 
+        //    heading -= 2*PI;
+       
+        //while(heading < 0) heading += 360;
+        //while(heading > 360) heading -= 360;
+
+
+        printf("x: %f \t\ty: %f \t\t z: %f \t\t heading: %f \t\r\n", x, y, z, heading);
+        wait_ms(200);
+
+    }
+}
diff -r 000000000000 -r 6bc5f85ca6fa mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue May 21 13:48:10 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/5e5da4a5990b
\ No newline at end of file