Ported to have same calls as L3G4200D lib so it can be substituted in HK10dof library ( which is being modified to use this and renamed IMU10DOF) platform NUCLEO-F401

WARNING: This project is not complete, but this library seems ok so far.

I have the module DFRobotics.com 10DOF MEMS IMU. I wanted a consise module for resolving direction and movement.

I found HK10DOF library (http://developer.mbed.org/users/pommzorz/code/HK10DOF/) with quaternions. But it used a different gyro. So I modified that code to use the same higher level calls but use the ITG3200 low level calls.

Files at this revision

API Documentation at this revision

Comitter:
svkatielee
Date:
Mon Nov 17 11:05:55 2014 +0000
Commit message:
Modified the L3G4200D gyro lib to be ITG3200 with the same calls so it can be substituted in HK10DOF MEMS library.

Changed in this revision

ITG3200.cpp Show annotated file Show diff for this revision Revisions of this file
ITG3200.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ITG3200.cpp	Mon Nov 17 11:05:55 2014 +0000
@@ -0,0 +1,191 @@
+/**
+ * Copyright (c) 2011 Pololu Corporation.  For more information, see
+ * 
+ * http://www.pololu.com/
+ * http://forum.pololu.com/
+ * 
+ * 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.
+ */
+ 
+#include "mbed.h"
+#include "ITG3200.h"
+#include <math.h>
+
+// Defines ////////////////////////////////////////////////////////////////
+
+// The Arduino two-wire interface uses a 7-bit number for the address, 
+// and sets the last bit correctly based on reads and writes
+// mbed I2C libraries take the 7-bit address shifted left 1 bit
+// #define GYR_ADDRESS (0xD2 >> 1)
+#define GYR_ADDRESS (0x68 << 1) //ITG3200
+
+// Public Methods //////////////////////////////////////////////////////////////
+
+// Constructor
+ITG3200::ITG3200(PinName sda, PinName scl):
+    _device(sda, scl)
+{
+    _device.frequency(50000);
+   
+    //Set FS_SEL to 0x03 for proper operation.
+    writeReg(SMPLRT_DIV_REG, 0x07);   // samplr rte 1000hz 7sample low pass filter
+    writeReg(DLPF_FS_REG, 0x03 << 3);
+   // writeReg(L3G4200D_CTRL_REG4, 0x20); // 2000 dps full scale default for ITG3200
+    writeReg(PWR_MGM_REG, 0x01); // CLK_SEL to x gyro
+
+    setGains(2.0,2.0,2.0);
+    setOffsets(0.0,0.0,0.0);
+
+}
+
+// Initialize gyro again
+void ITG3200::init(void)
+{
+	//Set FS_SEL to 0x03 for proper operation.
+    writeReg(SMPLRT_DIV_REG, 0x07);   // samplr rte 1000hz 7sample low pass filter
+    writeReg(DLPF_FS_REG, 0x03 << 3);
+   // writeReg(L3G4200D_CTRL_REG4, 0x20); // 2000 dps full scale default for ITG3200
+    writeReg(PWR_MGM_REG, 0x01); // CLK_SEL to x gyro
+
+    // initialize varaibles
+    setRevPolarity(false, false, false);
+    setGains(1.0,1.0,1.0);
+    setOffsets(0.0,0.0,0.0);
+}
+
+// read status registers of ITG3200
+void ITG3200::status(byte *s)
+{
+	s[0]=readReg(WHO_AM_I_REG);
+	s[1]=readReg(SMPLRT_DIV_REG);
+	s[2]=readReg(DLPF_FS_REG);
+	s[3]=readReg(PWR_MGM_REG);
+}
+
+// Writes a gyro register
+void ITG3200::writeReg(byte reg, byte value)
+{
+    data[0] = reg;
+    data[1] = value;
+    
+    _device.write(GYR_ADDRESS, data, 2);
+}
+
+// Reads a gyro register
+byte ITG3200::readReg(byte reg)
+{
+    byte value = 0;
+    
+    _device.write(GYR_ADDRESS, &reg, 1);
+    _device.read(GYR_ADDRESS, &value, 1);
+
+    return value;
+}
+
+void ITG3200::setGains(float _Xgain, float _Ygain, float _Zgain) {
+  gains[0] = _Xgain;
+  gains[1] = _Ygain;
+  gains[2] = _Zgain;
+}
+
+void ITG3200::setOffsets(int _Xoffset, int _Yoffset, int _Zoffset) {
+  offsets[0] = _Xoffset;
+  offsets[1] = _Yoffset;
+  offsets[2] = _Zoffset;
+}
+
+void ITG3200::setRevPolarity(bool _Xpol, bool _Ypol, bool _Zpol) {
+  polarities[0] = _Xpol ? -1 : 1;
+  polarities[1] = _Ypol ? -1 : 1;
+  polarities[2] = _Zpol ? -1 : 1;
+}
+
+
+void ITG3200::zeroCalibrate(unsigned int totSamples, unsigned int sampleDelayMS) {
+  int xyz[3]; 
+  float tmpOffsets[] = {0,0,0};
+
+  for (unsigned int i = 0;i < totSamples;i++){
+    wait_ms(sampleDelayMS);
+    read(xyz);
+    tmpOffsets[0] += xyz[0];
+    tmpOffsets[1] += xyz[1];
+    tmpOffsets[2] += xyz[2];  
+  }
+  setOffsets(-tmpOffsets[0] / totSamples, -tmpOffsets[1] / totSamples, -tmpOffsets[2] / totSamples);
+}
+
+
+// Reads the 3 gyro channels and stores them in vector g
+void ITG3200::read(int *g)
+{
+    // assert the MSB of the address to get the gyro 
+    // to do slave-transmit subaddress updating. (ITG default)
+    data[0] = GYRO_XOUT_H_REG;
+    _device.write(GYR_ADDRESS, data, 1); 
+
+//    Wire.requestFrom(GYR_ADDRESS, 6);
+//    while (Wire.available() < 6);
+
+    _device.read(GYR_ADDRESS, data, 6); 
+
+    uint8_t xha = data[0];
+    uint8_t xla = data[1];
+    uint8_t yha = data[2];
+    uint8_t yla = data[3];
+    uint8_t zha = data[4];
+    uint8_t zla = data[5];
+
+    g[0] = (short) (yha << 8 | yla);
+    g[1] = (short) (xha << 8 | xla);
+    g[2] = (short) (zha << 8 | zla);
+}
+
+void ITG3200::readRawCal(int *_GyroXYZ) {
+  read(_GyroXYZ);
+  _GyroXYZ[0] += offsets[0];
+  _GyroXYZ[1] += offsets[1];
+  _GyroXYZ[2] += offsets[2];
+}
+
+
+
+void ITG3200::read3(int x, int y, int z) {
+  int* r2;
+  //readings[0]=0;
+  //readings[1]=0;
+  //readings[2]=0;
+  read(r2);
+
+  x = r2[0];  
+  y = r2[1]; 
+  z = r2[2]; 
+}
+
+void ITG3200::readFin(float *_GyroXYZ){
+  int xyz[3];
+  
+  readRawCal(xyz); // x,y,z will contain calibrated integer values from the sensor
+  _GyroXYZ[0] =  (float)(xyz[0]) / (14.375 * polarities[0] * gains[0]);
+  _GyroXYZ[1] =  (float)(xyz[1]) / (14.375 * polarities[1] * gains[1]);
+  _GyroXYZ[2] =  (float)(xyz[2]) / (14.375 * polarities[2] * gains[2]);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ITG3200.h	Mon Nov 17 11:05:55 2014 +0000
@@ -0,0 +1,170 @@
+/**
+ * @author Larry Littlefield http://kb7kmo.blogspot.com
+ * lots of copping
+ * Ported from Pololu L3G4200D library for Arduino by
+ * @author Michael Shimniok http://bot-thoughts.com
+ * @author Uwe Gartmann
+ * @author Used ITG3200 library developed Aaron Berk as template
+ *
+ * @section LICENSE
+ *
+ * Copyright (c) 2010 ARM Limited
+ *
+ * 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.
+ *
+ * @section DESCRIPTION
+ *
+ * ITG-3200 triple axis, digital interface, gyroscope.
+ *
+ * Datasheet:
+ *
+ * http://invensense.com/mems/gyro/documents/PS-ITG-3200-00-01.4.pdf
+ */
+
+#ifndef ITG3200_H
+#define ITG3200_H
+
+/**
+ * Includes
+ */
+#include "mbed.h"
+
+/** Interface library for the ITG3200 3-axis gyro
+ *
+ * Ported from Pololu L3G4200D library for Arduino by
+ * Michael Shimniok http://bot-thoughts.com
+ * Then ported to ITG3200 by
+ * Larry Littlefield http://kb7kmo.blogspot.com
+ *
+ * testing target: NUCLEO-F401RE
+ * The reason for port is to make compatable calls so it can replace the 
+ * L3G4200D library in the renamed HK10DOK sensor library
+ * new lib name is IMU10DOF
+ * 
+ * @code
+ * #include "mbed.h"
+ * #include "ITG3200.h"
+ * ITG3200 gyro(p28, p27);
+ * ...
+ * int g[3];
+ * gyro.read(g);
+ * @endcode
+ */typedef char byte;
+/**
+ * Defines
+ */
+#define ITG3200_I2C_ADDRESS 0x68 //7-bit address.
+
+//-----------
+// Registers
+//-----------
+#define WHO_AM_I_REG    0x00
+#define SMPLRT_DIV_REG  0x15
+#define DLPF_FS_REG     0x16
+#define INT_CFG_REG     0x17
+#define INT_STATUS      0x1A
+#define TEMP_OUT_H_REG  0x1B
+#define TEMP_OUT_L_REG  0x1C
+#define GYRO_XOUT_H_REG 0x1D
+#define GYRO_XOUT_L_REG 0x1E
+#define GYRO_YOUT_H_REG 0x1F
+#define GYRO_YOUT_L_REG 0x20
+#define GYRO_ZOUT_H_REG 0x21
+#define GYRO_ZOUT_L_REG 0x22
+#define PWR_MGM_REG     0x3E
+
+//----------------------------
+// Low Pass Filter Bandwidths
+//----------------------------
+#define LPFBW_256HZ 0x00
+#define LPFBW_188HZ 0x01
+#define LPFBW_98HZ  0x02
+#define LPFBW_42HZ  0x03
+#define LPFBW_20HZ  0x04
+#define LPFBW_10HZ  0x05
+#define LPFBW_5HZ   0x06
+
+/**
+ * ITG-3200 triple axis digital gyroscope.
+ */
+
+class ITG3200
+{
+    public:
+        /** Create a new ITG3200 I2C interface
+         * @param sda is the pin for the I2C SDA line
+         * @param scl is the pin for the I2C SCL line
+         */
+        ITG3200(PinName sda, PinName scl);
+        
+        /** Read gyro values
+         * @param g Array containing x, y, and z gyro values
+         * @return g Array containing x, y, and z gyro values
+         */
+        void init(void);
+        
+        void status(byte *s); // read first 4 status registers of ITG3200 into passed array
+        
+        /** Read gyro values
+         * @param g Array containing x, y, and z gyro values
+         * modifies the g Array containing x, y, and z gyro values
+         */
+        void read(int *g);
+        
+        /** Read3 gyro values as integers
+         * @param int x, y, and z gyro values
+         * modifies the int x, y, and z gyro values
+         */
+        void read3(int x, int y, int z);
+        
+        /** Reads 
+         * @parm unsigned int totSamples with 
+         * @parm unsigned int sampleDelayMS
+         * then saves the calculated offsetsto private variables
+         */
+        void zeroCalibrate(unsigned int totSamples, unsigned int sampleDelayMS);
+        
+        /** calls read with an array pointer, adds offsets to modify the array
+         * x,y,z will contain calibrated integer values from the sensor
+         */
+        void readRawCal(int *_GyroXYZ);
+        
+        /** calls readRawCal multiplies gains to modify the array
+         */
+        void readFin(float *_GyroXYZ); // includes gain and offset
+        
+    private:
+        volatile float gains[3]; 
+        volatile int offsets[3];
+        volatile float polarities[3];
+        
+        void setGains(float _Xgain, float _Ygain, float _Zgain);
+        void setOffsets(int _Xoffset, int _Yoffset, int _Zoffset);
+        void setRevPolarity(bool _Xpol, bool _Ypol, bool _Zpol);  // true = Reversed  false = default
+    
+    
+        byte data[6];
+        int _rates[3];
+        I2C _device;
+        void writeReg(byte reg, byte value);
+        byte readReg(byte reg);
+        void enableDefault(void);
+};
+
+#endif /* ITG3200_H */