José Claudio
/
ReadingMag_HMC5883L
Example of reading and magnetometer sensor (HMC5883L)
Revision 0:6bc5f85ca6fa, committed 2013-05-21
- 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
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