QMC5883L(stm32f767zi)

Dependencies:   HMC5883L

Dependents:   IMU_fusion_9DOF

Fork of HMC5883L by Baser Kandehir

Files at this revision

API Documentation at this revision

Comitter:
sarahbest
Date:
Wed Jul 19 07:58:23 2017 +0000
Parent:
2:bbc9ad18fd3e
Commit message:
qmc5883 output 4 variables: mag 3,temp.; the temperature is negative, which has something wrong

Changed in this revision

HMC5883L.cpp Show diff for this revision Revisions of this file
HMC5883L.h Show diff for this revision Revisions of this file
HMC5883L.lib Show annotated file Show diff for this revision Revisions of this file
QMC5883L.cpp Show annotated file Show diff for this revision Revisions of this file
QMC5883L.h Show annotated file Show diff for this revision Revisions of this file
--- a/HMC5883L.cpp	Wed Aug 05 13:16:12 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/*   HMC5883L Digital Compass Library
-*
-*    @author: Baser Kandehir 
-*    @date: August 5, 2015
-*    @license: MIT license
-*     
-*   Copyright (c) 2015, Baser Kandehir, baser.kandehir@ieee.metu.edu.tr
-*
-*   Permission is hereby granted, free of charge, to any person obtaining a copy
-*   of this software and associated documentation files (the "Software"), to deal
-*   in the Software without restriction, including without limitation the rights
-*   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-*   copies of the Software, and to permit persons to whom the Software is
-*   furnished to do so, subject to the following conditions:
-*
-*   The above copyright notice and this permission notice shall be included in
-*   all copies or substantial portions of the Software.
-*
-*   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-*   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-*   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-*   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-*   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-*   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-*   THE SOFTWARE.
-*
-*/
-
-// Some part of the code is adapted from Adafruit HMC5883 library
-
-#include "HMC5883L.h"
-
-/* NUCLEO F411RE board */
-static I2C i2c(D14, D15);         // setup i2c (SDA,SCL)  
-
-static float Gauss_LSB_XY = 1100.0F; // Varies with gain
-static float Gauss_LSB_Z =  980.0F;  // Varies with gain
- 
-void HMC5883L::setMagGain(MagGain gain)
-{
-    writeByte(HMC5883L_ADDRESS, CONFIG_B, (int8_t)gain);    
-    
-    switch(gain)
-    {
-        case MagGain_13:
-            Gauss_LSB_XY = 1100;
-            Gauss_LSB_Z  = 980;
-            break;
-        case MagGain_19:
-            Gauss_LSB_XY = 855;
-            Gauss_LSB_Z  = 760;
-            break;
-        case MagGain_25:
-            Gauss_LSB_XY = 670;
-            Gauss_LSB_Z  = 600;
-            break;
-        case MagGain_40:
-            Gauss_LSB_XY = 450;
-            Gauss_LSB_Z  = 400;
-            break;
-        case MagGain_47:
-            Gauss_LSB_XY = 400;
-            Gauss_LSB_Z  = 255;
-            break;
-        case MagGain_56:
-            Gauss_LSB_XY = 330;
-            Gauss_LSB_Z  = 295;
-            break;
-        case MagGain_81:
-            Gauss_LSB_XY = 230;
-            Gauss_LSB_Z  = 205;
-            break;
-    }  
-}
-
-void HMC5883L::writeByte(uint8_t address, uint8_t regAddress, uint8_t data)
-{
-    char data_write[2];
-    data_write[0]=regAddress;           // I2C sends MSB first. Namely  >>|regAddress|>>|data|
-    data_write[1]=data;
-    i2c.write(address,data_write,2,0);  // i2c.write(int address, char* data, int length, bool repeated=false);  
-}
-
-char HMC5883L::readByte(uint8_t address, uint8_t regAddress)
-{
-    char data_read[1];                   // will store the register data    
-    char data_write[1];
-    data_write[0]=regAddress;
-    i2c.write(address,data_write,1,1);   // repeated = true
-    i2c.read(address,data_read,1,0);     // read the data and stop
-    return data_read[0];
-} 
-
-void HMC5883L::readBytes(uint8_t address, uint8_t regAddress, uint8_t byteNum, uint8_t* dest)
-{
-    char data[10],data_write[1];  
-    data_write[0]=regAddress;      
-    i2c.write(address,data_write,1,1);
-    i2c.read(address,data,byteNum,0);
-    for(int i=0;i<byteNum;i++)          // equate the addresses
-        dest[i]=data[i];
-}
-
-void HMC5883L::init()
-{
-    writeByte(HMC5883L_ADDRESS, CONFIG_A, 0x78);  // Number of samples averaged: 8, Data output rate: 75 Hz
-    writeByte(HMC5883L_ADDRESS, MODE,     0x00);  // Continuous-Measurement Mode
-    setMagGain(MagGain_13);
-    wait_ms(10);
-}
-
-void HMC5883L::readMagData(float* dest)
-{
-    uint8_t rawData[6]; // x,y,z mag data
-    
-    /* Read six raw data registers sequentially and write them into data array */
-    readBytes(HMC5883L_ADDRESS, OUT_X_MSB, 6, &rawData[0]); 
-    
-    /* Turn the MSB LSB into signed 16-bit value */
-    dest[0] = (int16_t)(((int16_t)rawData[0]<<8) | rawData[1]);  // MAG_XOUT
-    dest[2] = (int16_t)(((int16_t)rawData[2]<<8) | rawData[3]);  // MAG_ZOUT
-    dest[1] = (int16_t)(((int16_t)rawData[4]<<8) | rawData[5]);  // MAG_YOUT 
-    
-    /* Convert raw data to magnetic field values in microtesla */
-     dest[0] = dest[0] / Gauss_LSB_XY * GAUSS_TO_MICROTESLA;
-     dest[1] = dest[1] / Gauss_LSB_XY * GAUSS_TO_MICROTESLA;
-     dest[2] = dest[2] / Gauss_LSB_Z  * GAUSS_TO_MICROTESLA;
-}
-
-double HMC5883L::getHeading()
-{
-    float magData[3];
-    readMagData(magData);
-    
-    /* Calculate the heading while Z axis of the module is pointing up */
-    double heading = atan2(magData[1], magData[0]);
-    
-    // After calculating heading declination angle should be added to heading which is the error of the magnetic field in specific location.
-    // declinationAngle can be found here http://www.magnetic-declination.com/
-    // For Ankara (my location) declinationAngle is ~5.5 degrees (0.096 radians)
-    float declinationAngle = 0.096;
-    heading += declinationAngle;
-    
-    // Correct for when signs are reversed.
-    if(heading < 0)
-        heading += 2*PI;
-    
-    // Check for wrap due to addition of declination.
-    if(heading > 2*PI)
-        heading -= 2*PI;
-    
-    /* Convert radian to degrees */
-    heading = heading * 180 / PI;  
-    
-    return heading;    
-}
--- a/HMC5883L.h	Wed Aug 05 13:16:12 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*     
-*   Copyright (c) 2015, Baser Kandehir, baser.kandehir@ieee.metu.edu.tr
-*
-*   Permission is hereby granted, free of charge, to any person obtaining a copy
-*   of this software and associated documentation files (the "Software"), to deal
-*   in the Software without restriction, including without limitation the rights
-*   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-*   copies of the Software, and to permit persons to whom the Software is
-*   furnished to do so, subject to the following conditions:
-*
-*   The above copyright notice and this permission notice shall be included in
-*   all copies or substantial portions of the Software.
-*
-*   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-*   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-*   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-*   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-*   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-*   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-*   THE SOFTWARE.
-*
-*/
-
-// Some part of the code is adapted from Adafruit HMC5883 library
-
-#ifndef HMC5883L_H
-#define HMC5883L_H
-
-#include "mbed.h"
-#include "math.h"
-#include "ledControl.h"
-
-#define PI 3.14159265359 
-#define GAUSS_TO_MICROTESLA 100
-#define HMC5883L_ADDRESS 0x3C
-
-/* Register Definitions */
-#define CONFIG_A     0x00
-#define CONFIG_B     0x01
-#define MODE         0x02
-#define OUT_X_MSB    0x03
-#define OUT_X_LSB    0x04
-#define OUT_Z_MSB    0x05
-#define OUT_Z_LSB    0x06
-#define OUT_Y_MSB    0x07
-#define OUT_Y_LSB    0x08
-#define STATUS       0x09
-#define ID_A         0x0A
-#define ID_B         0x0B
-#define ID_C         0x0C
-
-/* Magnetometer Gain Settings */
-enum MagGain
-{
-    MagGain_088 =  0x00,      // +/- 0.88 Ga
-    MagGain_13  =  0x20,      // +/- 1.3  Ga
-    MagGain_19  =  0x40,      // +/- 1.9  Ga
-    MagGain_25  =  0x60,      // +/- 2.5  Ga
-    MagGain_40  =  0x80,      // +/- 4.0  Ga
-    MagGain_47  =  0xA0,      // +/- 4.7  Ga
-    MagGain_56  =  0xC0,      // +/- 5.6  Ga
-    MagGain_81  =  0xE0       // +/- 8.1  Ga
-};
-
-class HMC5883L
-{
-    public:
-        void init();
-        double getHeading();
-        void readMagData(float* dest);  
-    private:
-        void setMagGain(MagGain gain);
-        void writeByte(uint8_t address, uint8_t regAddress, uint8_t data);
-        char readByte(uint8_t address, uint8_t regAddress);
-        void readBytes(uint8_t address, uint8_t regAddress, uint8_t byteNum, uint8_t* dest);
-};
-
-#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HMC5883L.lib	Wed Jul 19 07:58:23 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/BaserK/code/HMC5883L/#bbc9ad18fd3e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QMC5883L.cpp	Wed Jul 19 07:58:23 2017 +0000
@@ -0,0 +1,203 @@
+/*   QMC5883L Digital Compass Library
+*
+*    @author: Baser Kandehir 
+*    @date: August 5, 2015
+*    @license: MIT license
+*     
+*   Copyright (c) 2015, Baser Kandehir, baser.kandehir@ieee.metu.edu.tr
+*
+*   Permission is hereby granted, free of charge, to any person obtaining a copy
+*   of this software and associated documentation files (the "Software"), to deal
+*   in the Software without restriction, including without limitation the rights
+*   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+*   copies of the Software, and to permit persons to whom the Software is
+*   furnished to do so, subject to the following conditions:
+*
+*   The above copyright notice and this permission notice shall be included in
+*   all copies or substantial portions of the Software.
+*
+*   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+*   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+*   THE SOFTWARE.
+*
+*/
+
+// Some part of the code is adapted from Adafruit HMC5883 library
+
+#include "QMC5883L.h"
+
+/* NUCLEO F411RE board */
+static I2C QMC5883L_i2c(D2, D4);         // setup i2c (SDA,SCL)  
+float mRes; // Varies with gain
+ 
+float QMC5883L::setMagRange(MagScale Mscale)
+{   
+    switch(Mscale)
+    {
+        case MagScale_2G:
+            mRes = 1.0/12000;  //LSB/G
+            break;
+        case MagScale_8G:
+            mRes = 1.0/3000;
+            break;
+    } 
+    return mRes;
+}
+
+//void QMC5883L::writeByte(uint8_t address, uint8_t regAddress, uint8_t data)
+//{
+//    char data_write[2];
+//    data_write[0]=regAddress;           // I2C sends MSB first. Namely  >>|regAddress|>>|data|
+//    data_write[1]=data;
+//    i2c.write(address,data_write,2,0);  // i2c.write(int address, char* data, int length, bool repeated=false);  
+//}
+
+//char QMC5883L::readByte(uint8_t address, uint8_t regAddress)
+//{
+//    char data_read[1];                   // will store the register data    
+//    char data_write[1];
+//    data_write[0]=regAddress;
+//    i2c.write(address,data_write,1,1);   // repeated = true
+//    i2c.read(address,data_read,1,0);     // read the data and stop
+//    return data_read[0];
+//} 
+
+//void QMC5883L::readBytes(uint8_t address, uint8_t regAddress, uint8_t byteNum, uint8_t* dest)
+//{
+//    char data[10],data_write[1];  
+//    data_write[0]=regAddress;      
+//    i2c.write(address,data_write,1,1);
+//    i2c.read(address,data,byteNum,0);
+//    for(int i=0;i<byteNum;i++)          // equate the addresses
+//        dest[i]=data[i];
+//}
+
+void QMC5883L_WriteByte(uint8_t QMC5883L_reg, uint8_t QMC5883L_data)
+{
+    char data_out[2];
+    data_out[0]=QMC5883L_reg;
+    data_out[1]=QMC5883L_data;
+    QMC5883L_i2c.write(QMC5883L_ADDRESS, data_out, 2, 0);
+}
+
+uint8_t QMC5883L_ReadByte(uint8_t QMC5883L_reg)
+{
+    char data_out[1], data_in[1];
+    data_out[0] = QMC5883L_reg;
+    QMC5883L_i2c.write(QMC5883L_ADDRESS, data_out, 1, 1);
+    QMC5883L_i2c.read(QMC5883L_ADDRESS, data_in, 1, 0);
+    return (data_in[0]);
+}
+
+void QMC5883L::ChipID()
+{
+    uint8_t ChipID = QMC5883L_ReadByte(CHIP_ID);   // Should return 0x68
+    pc.printf("I AM QMC5883: 0x%x \r\n",ChipID);
+    
+//    if(whoAmI==0x12)//0x68)
+//    {
+//        pc.printf("ICM20602 is online... \r\n");  
+////        led2=1;
+////        ledToggle(2);
+//    }
+//    else
+//    {
+//        pc.printf("Could not connect to ICM20602 \r\nCheck the connections... \r\n");  
+////        toggler1.attach(&toggle_led1,0.1);     // toggles led1 every 100 ms
+//    } 
+//pc.printf("I AM 0x%x \r\n",QMC5883L_ADDRESS);    
+}
+
+void QMC5883L::init()
+{   
+    setMagRange(MagScale_8G);
+    QMC5883L_WriteByte(CONTROL_A, 0x0D | MagScale_8G);  // Range: 8G, ODR: 200 Hz, mode:Continuous-Measurement
+    QMC5883L_WriteByte(SET_RESET, 0x01);
+    //QMC5883L_WriteByte(STATUS, 0x01);
+    //QMC5883L_WriteByte(0X20, 0x40);
+//    QMC5883L_WriteByte(0X21, 0x01);
+    wait_ms(10);
+}
+
+int16_t QMC5883L::getMagXvalue()
+{
+    uint8_t LoByte, HiByte;
+    LoByte = QMC5883L_ReadByte(OUT_X_LSB); // read Accelerometer X_Low  value
+    HiByte = QMC5883L_ReadByte(OUT_X_MSB); // read Accelerometer X_High value
+    return((HiByte<<8) | LoByte);
+//    pc1.printf("accx:%d,%d\r\n",HiByte,LoByte);  // send data to matlab
+}
+
+int16_t QMC5883L::getMagYvalue()
+{
+    uint8_t LoByte, HiByte;
+    LoByte = QMC5883L_ReadByte(OUT_Y_LSB); // read Accelerometer X_Low  value
+    HiByte = QMC5883L_ReadByte(OUT_Y_MSB); // read Accelerometer X_High value
+    return ((HiByte<<8) | LoByte);
+}
+
+int16_t QMC5883L::getMagZvalue()
+{
+    uint8_t LoByte, HiByte;
+    LoByte = QMC5883L_ReadByte(OUT_Z_LSB); // read Accelerometer X_Low  value
+    HiByte = QMC5883L_ReadByte(OUT_Z_MSB); // read Accelerometer X_High value
+    return ((HiByte<<8) | LoByte);
+}
+
+int16_t QMC5883L::getMagTemp()
+{
+    uint8_t LoByte, HiByte;
+    LoByte = QMC5883L_ReadByte(TEMP_LSB); // read Accelerometer X_Low  value
+    HiByte = QMC5883L_ReadByte(TEMP_MSB); // read Accelerometer X_High value
+    return ((HiByte<<8) | LoByte);
+}
+
+//void QMC5883L::readMagData(float* dest)
+//{
+//    uint8_t rawData[6]; // x,y,z mag data
+//    
+//    /* Read six raw data registers sequentially and write them into data array */
+//    readBytes(QMC5883L_ADDRESS, OUT_X_MSB, 6, &rawData[0]); 
+//    
+//    /* Turn the MSB LSB into signed 16-bit value */
+//    dest[0] = (int16_t)(((int16_t)rawData[0]<<8) | rawData[1]);  // MAG_XOUT
+//    dest[2] = (int16_t)(((int16_t)rawData[2]<<8) | rawData[3]);  // MAG_ZOUT
+//    dest[1] = (int16_t)(((int16_t)rawData[4]<<8) | rawData[5]);  // MAG_YOUT 
+//    
+//    /* Convert raw data to magnetic field values in microtesla */
+//     dest[0] = dest[0] / Gauss_LSB_XY * GAUSS_TO_MICROTESLA;
+//     dest[1] = dest[1] / Gauss_LSB_XY * GAUSS_TO_MICROTESLA;
+//     dest[2] = dest[2] / Gauss_LSB_Z  * GAUSS_TO_MICROTESLA;
+//}
+
+//double QMC5883L::getHeading()
+//{
+//    float magData[3];
+//    readMagData(magData);
+//    
+//    /* Calculate the heading while Z axis of the module is pointing up */
+//    double heading = atan2(magData[1], magData[0]);
+//    
+//    // After calculating heading declination angle should be added to heading which is the error of the magnetic field in specific location.
+//    // declinationAngle can be found here http://www.magnetic-declination.com/
+//    // For Ankara (my location) declinationAngle is ~5.5 degrees (0.096 radians)
+//    float declinationAngle = 0.096;
+//    heading += declinationAngle;
+//    
+//    // Correct for when signs are reversed.
+//    if(heading < 0)
+//        heading += 2*PI;
+//    
+//    // Check for wrap due to addition of declination.
+//    if(heading > 2*PI)
+//        heading -= 2*PI;
+//    
+//    /* Convert radian to degrees */
+//    heading = heading * 180 / PI;  
+//    
+//    return heading;    
+//}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QMC5883L.h	Wed Jul 19 07:58:23 2017 +0000
@@ -0,0 +1,80 @@
+/*     
+*   Copyright (c) 2015, Baser Kandehir, baser.kandehir@ieee.metu.edu.tr
+*
+*   Permission is hereby granted, free of charge, to any person obtaining a copy
+*   of this software and associated documentation files (the "Software"), to deal
+*   in the Software without restriction, including without limitation the rights
+*   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+*   copies of the Software, and to permit persons to whom the Software is
+*   furnished to do so, subject to the following conditions:
+*
+*   The above copyright notice and this permission notice shall be included in
+*   all copies or substantial portions of the Software.
+*
+*   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+*   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+*   THE SOFTWARE.
+*
+*/
+
+// Some part of the code is adapted from Adafruit HMC5883 library
+
+#ifndef QMC5883L_H
+#define QMC5883L_H
+
+#include "mbed.h"
+#include "math.h"
+#include "ledControl.h"
+
+#define PI 3.14159265359 
+#define GAUSS_TO_MICROTESLA 100
+#define QMC5883L_ADDRESS 0x1A//0x18//
+
+/* Register Definitions */
+#define OUT_X_LSB    0x00
+#define OUT_X_MSB    0x01
+#define OUT_Y_LSB    0x02
+#define OUT_Y_MSB    0x03
+#define OUT_Z_LSB    0x04
+#define OUT_Z_MSB    0x05
+#define STATUS       0x06
+#define TEMP_LSB     0x07
+#define TEMP_MSB     0x08
+#define CONTROL_A    0x09
+#define CONTROL_B    0x0A
+#define SET_RESET    0x0B
+#define CHIP_ID      0x0D
+
+extern float mRes;
+/* Magnetometer Gain Settings */
+enum MagScale
+{
+    MagScale_2G =  0x00,      // +/- 2 Ga
+    MagScale_8G  = 0x10,     // +/- 8 Ga
+};
+
+class QMC5883L
+{
+    public:
+        void    init();
+        double  getHeading();
+        void    readMagData(float* dest);  
+        int16_t getMagXvalue();
+        int16_t getMagYvalue();
+        int16_t getMagZvalue();
+        int16_t getMagTemp();
+        void    ChipID();
+    private:
+        float setMagRange(MagScale Mscale);
+//        uint8_t QMC5883L_ReadByte(uint8_t QMC5883L_reg);
+//        void QMC5883L_WriteByte(uint8_t QMC5883L_reg, uint8_t QMC5883L_data);
+//        void readBytes(uint8_t address, uint8_t regAddress, uint8_t byteNum, uint8_t* dest);
+};
+
+#endif
+
+extern Serial pc;
\ No newline at end of file