Simple library for MAG3110 magenetometer as built into Avnet Wi-Go module

Dependencies:   MotionSensor

Dependents:   Wi-Go-MagnetometerTest EE202A_HW1_MH serialtoxively mbed_nanosec_timer ... more

Files at this revision

API Documentation at this revision

Comitter:
SomeRandomBloke
Date:
Fri May 09 18:01:36 2014 +0000
Parent:
6:f510561f6107
Parent:
5:f3abe901c33a
Child:
8:d13d9ccddff7
Commit message:
merged pull request fro calXY

Changed in this revision

MAG3110.cpp Show annotated file Show diff for this revision Revisions of this file
MAG3110.cpp.orig Show annotated file Show diff for this revision Revisions of this file
MAG3110.h Show annotated file Show diff for this revision Revisions of this file
--- a/MAG3110.cpp	Tue Dec 31 17:16:37 2013 +0000
+++ b/MAG3110.cpp	Fri May 09 18:01:36 2014 +0000
@@ -5,14 +5,16 @@
 /******************************************************************************
  * Constructors
  ******************************************************************************/
-MAG3110::MAG3110(PinName sda, PinName scl): _i2c(sda, scl),
-    _i2c_address(0x1D), _pc(NULL), _debug(false)
+MAG3110::MAG3110(PinName sda, PinName scl): _i2c(sda, scl), 
+    _i2c_address(0x1d), _pc(NULL), _debug(false)
+
 {
     begin();
 }
 
-MAG3110::MAG3110(PinName sda, PinName scl, Serial *pc): _i2c(sda, scl),
-    _i2c_address(0x1D), _pc(pc), _debug(true)
+MAG3110::MAG3110(PinName sda, PinName scl, Serial *pc): _i2c(sda, scl), 
+   _i2c_address(0x1d), _pc(pc), _debug(true)
+
 {
     begin();
 }
@@ -26,7 +28,7 @@
     _i2c.write(_i2c_address, cmd, 2);
 
     cmd[0] = MAG_CTRL_REG1;
-    cmd[1] = MAG_3110_SAMPLE80+MAG_3110_OVERSAMPLE2+MAG_3110_ACTIVE;
+    cmd[1] = MAG_3110_ACTIVE;
     _i2c.write(_i2c_address, cmd, 2);
 
     // No adjustment initially
@@ -40,27 +42,34 @@
     char cmd[1];
 
     cmd[0] = regAddr;
-    _i2c.write(_i2c_address, cmd, 1);
-
+    if(_i2c.write(_i2c_address, cmd, 1)) {
+        printf("MAG3110 write error\r\n");
+        _i2c.stop();
+        _i2c.start();
+        }
     cmd[0] = 0x00;
     _i2c.read(_i2c_address, cmd, 1);
     return (int)( cmd[0]);
 }
 
-
 // read a register per, pass first reg value, reading 2 bytes increments register
 // Reads MSB first then LSB
 int MAG3110::readVal(char regAddr)
 {
     char cmd[2];
-
+    int16_t t;
     cmd[0] = regAddr;
-    _i2c.write(_i2c_address, cmd, 1);
+    if(_i2c.write(_i2c_address, cmd, 1)) {
+        printf("MAG3110 write error\r\n");
+        _i2c.stop();
+        _i2c.start();
+        }
 
     cmd[0] = 0x00;
     cmd[1] = 0x00;
     _i2c.read(_i2c_address, cmd, 2);
-    return (int)( (cmd[1]|(cmd[0] << 8))); //concatenate the MSB and LSB
+    t = (cmd[0] * 256) + (unsigned short) cmd[1];
+    return ((int) t); //concatenate the MSB and LSB
 }
 
 
@@ -78,6 +87,24 @@
     *zVal = readVal(MAG_OUT_Z_MSB);
 }
 
+void MAG3110::ReadXYZ(float * mag)
+{
+    int x, y, z;
+    x = readVal(MAG_OUT_X_MSB);
+    y = readVal(MAG_OUT_Y_MSB);
+    z = readVal(MAG_OUT_Z_MSB);
+    mag[0] = (float) x / 10.0;
+    mag[1] = (float) y / 10.0;
+    mag[2] = (float) z / 10.0;
+    
+}
+
+void MAG3110::ReadXYZraw(int16_t * mag_raw)
+{
+    mag_raw[0] = readVal(MAG_OUT_X_MSB);
+    mag_raw[1] = readVal(MAG_OUT_Y_MSB);
+    mag_raw[2] = readVal(MAG_OUT_Z_MSB);
+}
 
 void MAG3110::setCalibration(int minX, int maxX, int minY, int maxY )
 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAG3110.cpp.orig	Fri May 09 18:01:36 2014 +0000
@@ -0,0 +1,118 @@
+
+#include "MAG3110.h"
+#include "mbed.h"
+
+/******************************************************************************
+ * Constructors
+ ******************************************************************************/
+MAG3110::MAG3110(PinName sda, PinName scl): _i2c(sda, scl),
+    _i2c_address(0x1D), _pc(NULL), _debug(false)
+{
+    begin();
+}
+
+MAG3110::MAG3110(PinName sda, PinName scl, Serial *pc): _i2c(sda, scl),
+    _i2c_address(0x1D), _pc(pc), _debug(true)
+{
+    begin();
+}
+
+void MAG3110::begin()
+{
+    char cmd[2];
+
+    cmd[0] = MAG_CTRL_REG2;
+    cmd[1] = 0x80;
+    _i2c.write(_i2c_address, cmd, 2);
+
+    cmd[0] = MAG_CTRL_REG1;
+    cmd[1] = MAG_3110_SAMPLE80+MAG_3110_OVERSAMPLE2+MAG_3110_ACTIVE;
+    _i2c.write(_i2c_address, cmd, 2);
+
+    // No adjustment initially
+    _avgX = 0;
+    _avgY = 0;
+}
+
+// Read a single byte form 8 bit register, return as int
+int MAG3110::readReg(char regAddr)
+{
+    char cmd[1];
+
+    cmd[0] = regAddr;
+    _i2c.write(_i2c_address, cmd, 1);
+
+    cmd[0] = 0x00;
+    _i2c.read(_i2c_address, cmd, 1);
+    return (int)( cmd[0]);
+}
+
+
+// read a register per, pass first reg value, reading 2 bytes increments register
+// Reads MSB first then LSB
+int MAG3110::readVal(char regAddr)
+{
+    char cmd[2];
+
+    cmd[0] = regAddr;
+    _i2c.write(_i2c_address, cmd, 1);
+
+    cmd[0] = 0x00;
+    cmd[1] = 0x00;
+    _i2c.read(_i2c_address, cmd, 2);
+    return (int)( (cmd[1]|(cmd[0] << 8))); //concatenate the MSB and LSB
+}
+
+
+float MAG3110::getHeading()
+{
+    int xVal = readVal(MAG_OUT_X_MSB);
+    int yVal = readVal(MAG_OUT_Y_MSB);
+    return (atan2((double)(yVal - _avgY),(double)(xVal - _avgX)))*180/PI;
+}
+
+void MAG3110::getValues(int *xVal, int *yVal, int *zVal)
+{
+    *xVal = readVal(MAG_OUT_X_MSB);
+    *yVal = readVal(MAG_OUT_Y_MSB);
+    *zVal = readVal(MAG_OUT_Z_MSB);
+}
+
+
+void MAG3110::setCalibration(int minX, int maxX, int minY, int maxY )
+{
+    _avgX=(maxX+minX)/2;
+    _avgY=(maxY+minY)/2;
+}
+
+
+
+void MAG3110::calXY(PinName pin, int activeValue )
+{
+    DigitalIn calPin(pin);
+    int tempXmax, tempXmin, tempYmax, tempYmin, newX, newY;
+
+
+    // Wait for Button Press and Release before beginning calibration
+    while(calPin != activeValue) {}
+    while(calPin == activeValue) {}
+
+
+    // Read initial values of magnetomoter - read it here to create a slight delay for calPin to settle
+    tempXmax = tempXmin = readVal(MAG_OUT_X_MSB);
+    tempYmax = tempYmin = readVal(MAG_OUT_Y_MSB);
+
+    // Update min and max values until calPin asserted again
+    while(calPin != activeValue) {
+        newX = readVal(MAG_OUT_X_MSB);
+        newY = readVal(MAG_OUT_Y_MSB);
+        if (newX > tempXmax) tempXmax = newX;
+        if (newX < tempXmin) tempXmin = newX;
+        if (newY > tempYmax) tempYmax = newY;
+        if (newY < tempYmin) tempYmin = newY;
+    }
+
+    setCalibration( tempXmin, tempXmax, tempYmin, tempYmax );
+
+}
+
--- a/MAG3110.h	Tue Dec 31 17:16:37 2013 +0000
+++ b/MAG3110.h	Fri May 09 18:01:36 2014 +0000
@@ -117,6 +117,19 @@
      * @return heading in degrees
      */
     float getHeading();
+    
+    /**
+     * Perform a read on the X, Y and Z values, converted to microteslas.
+     * @paran mag Pointer to the 3 element array whare the results will be placed
+     */
+    void ReadXYZ(float * mag);
+    
+    /**
+     * Perform a read on the raw X, Y and Z values.
+     * @paran mag Pointer to the 3 element array whare the results will be placed
+     */
+    void ReadXYZraw(int16_t * mag_raw);
+    
     /**
      * Perform a read on the X, Y and Z values.
      * @param xVal Pointer to X value
@@ -145,6 +158,7 @@
     Serial *_pc;
     bool _debug;
     int _avgX, _avgY;
+    int x, y, z;
 
 };
 #endif