LSM6DS3 Library by sj

Fork of LSM6DS3 by Sherry Yang

Files at this revision

API Documentation at this revision

Comitter:
oreo329
Date:
Tue May 02 17:30:18 2017 +0000
Parent:
2:ed14e6196255
Commit message:
fixed accelerometer & gyro begin errors(both odr, scale); ; now its working at diff odrs &scales;

Changed in this revision

LSM6DS3.cpp Show diff for this revision Revisions of this file
LSM6DS3.h Show diff for this revision Revisions of this file
LSM6DS3_sj.cpp Show annotated file Show diff for this revision Revisions of this file
LSM6DS3_sj.h Show annotated file Show diff for this revision Revisions of this file
--- a/LSM6DS3.cpp	Tue Jun 21 20:51:25 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,386 +0,0 @@
-#include "LSM6DS3.h"
-
-LSM6DS3::LSM6DS3(PinName sda, PinName scl, uint8_t xgAddr) : i2c(sda, scl)
-{
-    // xgAddress will store the 7-bit I2C address, if using I2C.
-    xgAddress = xgAddr;
-}
-
-uint16_t LSM6DS3::begin(gyro_scale gScl, accel_scale aScl,  
-                        gyro_odr gODR, accel_odr aODR)
-{
-    // Store the given scales in class variables. These scale variables
-    // are used throughout to calculate the actual g's, DPS,and Gs's.
-    gScale = gScl;
-    aScale = aScl;
-    
-    // Once we have the scale values, we can calculate the resolution
-    // of each sensor. That's what these functions are for. One for each sensor
-    calcgRes(); // Calculate DPS / ADC tick, stored in gRes variable
-    calcaRes(); // Calculate g / ADC tick, stored in aRes variable
-    
-    
-    // To verify communication, we can read from the WHO_AM_I register of
-    // each device. Store those in a variable so we can return them.
-    // The start of the addresses we want to read from
-    char cmd[2] = {
-        WHO_AM_I_REG,
-        0
-    };
-
-    // Write the address we are going to read from and don't end the transaction
-    i2c.write(xgAddress, cmd, 1, true);
-    // Read in all the 8 bits of data
-    i2c.read(xgAddress, cmd+1, 1);
-    uint8_t xgTest = cmd[1];                    // Read the accel/gyro WHO_AM_I
-        
-    // Gyro initialization stuff:
-    initGyro(); // This will "turn on" the gyro. Setting up interrupts, etc.
-    setGyroODR(gODR); // Set the gyro output data rate and bandwidth.
-    setGyroScale(gScale); // Set the gyro range
-    
-    // Accelerometer initialization stuff:
-    initAccel(); // "Turn on" all axes of the accel. Set up interrupts, etc.
-    setAccelODR(aODR); // Set the accel data rate.
-    setAccelScale(aScale); // Set the accel range.
-    
-    // Interrupt initialization stuff;
-    initIntr();
-    
-    // Once everything is initialized, return the WHO_AM_I registers we read:
-    return xgTest;
-}
-
-void LSM6DS3::initGyro()
-{
-    char cmd[4] = {
-        CTRL2_G,
-        gScale | G_ODR_104,
-        0,          // Default data out and int out
-        0           // Default power mode and high pass settings
-    };
-
-    // Write the data to the gyro control registers
-    i2c.write(xgAddress, cmd, 4);
-}
-
-void LSM6DS3::initAccel()
-{
-    char cmd[4] = {
-        CTRL1_XL,
-        0x38,       // Enable all axis and don't decimate data in out Registers
-        (A_ODR_104 << 5) | (aScale << 3) | (A_BW_AUTO_SCALE),   // 119 Hz ODR, set scale, and auto BW
-        0           // Default resolution mode and filtering settings
-    };
-
-    // Write the data to the accel control registers
-    i2c.write(xgAddress, cmd, 4);
-}
-
-void LSM6DS3::initIntr()
-{
-    char cmd[2];
-    
-    cmd[0] = TAP_CFG;
-    cmd[1] = 0x0E;
-    i2c.write(xgAddress, cmd, 2);
-    cmd[0] = TAP_THS_6D;
-    cmd[1] = 0x03;
-    i2c.write(xgAddress, cmd, 2);
-    cmd[0] = INT_DUR2;
-    cmd[1] = 0x7F;
-    i2c.write(xgAddress, cmd, 2);
-    cmd[0] = WAKE_UP_THS;
-    cmd[1] = 0x80;
-    i2c.write(xgAddress, cmd, 2);
-    cmd[0] = MD1_CFG;
-    cmd[1] = 0x48;
-    i2c.write(xgAddress, cmd, 2);
-}
-
-void LSM6DS3::readAccel()
-{
-    // The data we are going to read from the accel
-    char data[6];
-
-    // Set addresses
-    char subAddressXL = OUTX_L_XL;
-    char subAddressXH = OUTX_H_XL;
-    char subAddressYL = OUTY_L_XL;
-    char subAddressYH = OUTY_H_XL;
-    char subAddressZL = OUTZ_L_XL;
-    char subAddressZH = OUTZ_H_XL;
-
-    // Write the address we are going to read from and don't end the transaction
-    i2c.write(xgAddress, &subAddressXL, 1, true);
-    // Read in register containing the axes data and alocated to the correct index
-    i2c.read(xgAddress, data, 1);
-    
-    i2c.write(xgAddress, &subAddressXH, 1, true);
-    i2c.read(xgAddress, (data + 1), 1);
-    i2c.write(xgAddress, &subAddressYL, 1, true);
-    i2c.read(xgAddress, (data + 2), 1);
-    i2c.write(xgAddress, &subAddressYH, 1, true);
-    i2c.read(xgAddress, (data + 3), 1);
-    i2c.write(xgAddress, &subAddressZL, 1, true);
-    i2c.read(xgAddress, (data + 4), 1);
-    i2c.write(xgAddress, &subAddressZH, 1, true);
-    i2c.read(xgAddress, (data + 5), 1);
-
-    // Reassemble the data and convert to g
-    ax_raw = data[0] | (data[1] << 8);
-    ay_raw = data[2] | (data[3] << 8);
-    az_raw = data[4] | (data[5] << 8);
-    ax = ax_raw * aRes;
-    ay = ay_raw * aRes;
-    az = az_raw * aRes;
-}
-
-void LSM6DS3::readIntr()
-{
-    char data[1];
-    char subAddress = TAP_SRC;
-
-    i2c.write(xgAddress, &subAddress, 1, true);
-    i2c.read(xgAddress, data, 1);
-
-    intr = (float)data[0];
-}
-
-void LSM6DS3::readTemp()
-{
-    // The data we are going to read from the temp
-    char data[2];
-
-    // Set addresses
-    char subAddressL = OUT_TEMP_L;
-    char subAddressH = OUT_TEMP_H;
-
-    // Write the address we are going to read from and don't end the transaction
-    i2c.write(xgAddress, &subAddressL, 1, true);
-    // Read in register containing the temperature data and alocated to the correct index
-    i2c.read(xgAddress, data, 1);
-    
-    i2c.write(xgAddress, &subAddressH, 1, true);
-    i2c.read(xgAddress, (data + 1), 1);
-
-    // Temperature is a 12-bit signed integer   
-    temperature_raw = data[0] | (data[1] << 8);
-
-    temperature_c = (float)temperature_raw / 16.0 + 25.0;
-    temperature_f = temperature_c * 1.8 + 32.0;
-}
-
-
-void LSM6DS3::readGyro()
-{
-    // The data we are going to read from the gyro
-    char data[6];
-
-    // Set addresses
-    char subAddressXL = OUTX_L_G;
-    char subAddressXH = OUTX_H_G;
-    char subAddressYL = OUTY_L_G;
-    char subAddressYH = OUTY_H_G;
-    char subAddressZL = OUTZ_L_G;
-    char subAddressZH = OUTZ_H_G;
-
-    // Write the address we are going to read from and don't end the transaction
-    i2c.write(xgAddress, &subAddressXL, 1, true);
-    // Read in register containing the axes data and alocated to the correct index
-    i2c.read(xgAddress, data, 1);
-    
-    i2c.write(xgAddress, &subAddressXH, 1, true);
-    i2c.read(xgAddress, (data + 1), 1);
-    i2c.write(xgAddress, &subAddressYL, 1, true);
-    i2c.read(xgAddress, (data + 2), 1);
-    i2c.write(xgAddress, &subAddressYH, 1, true);
-    i2c.read(xgAddress, (data + 3), 1);
-    i2c.write(xgAddress, &subAddressZL, 1, true);
-    i2c.read(xgAddress, (data + 4), 1);
-    i2c.write(xgAddress, &subAddressZH, 1, true);
-    i2c.read(xgAddress, (data + 5), 1);
-
-    // Reassemble the data and convert to degrees/sec
-    gx_raw = data[0] | (data[1] << 8);
-    gy_raw = data[2] | (data[3] << 8);
-    gz_raw = data[4] | (data[5] << 8);
-    gx = gx_raw * gRes;
-    gy = gy_raw * gRes;
-    gz = gz_raw * gRes;
-}
-
-void LSM6DS3::setGyroScale(gyro_scale gScl)
-{
-    // The start of the addresses we want to read from
-    char cmd[2] = {
-        CTRL2_G,
-        0
-    };
-
-    // Write the address we are going to read from and don't end the transaction
-    i2c.write(xgAddress, cmd, 1, true);
-    // Read in all the 8 bits of data
-    i2c.read(xgAddress, cmd+1, 1);
-
-    // Then mask out the gyro scale bits:
-    cmd[1] &= 0xFF^(0x3 << 3);
-    // Then shift in our new scale bits:
-    cmd[1] |= gScl << 3;
-
-    // Write the gyroscale out to the gyro
-    i2c.write(xgAddress, cmd, 2);
-    
-    // We've updated the sensor, but we also need to update our class variables
-    // First update gScale:
-    gScale = gScl;
-    // Then calculate a new gRes, which relies on gScale being set correctly:
-    calcgRes();
-}
-
-void LSM6DS3::setAccelScale(accel_scale aScl)
-{
-    // The start of the addresses we want to read from
-    char cmd[2] = {
-        CTRL1_XL,
-        0
-    };
-
-    // Write the address we are going to read from and don't end the transaction
-    i2c.write(xgAddress, cmd, 1, true);
-    // Read in all the 8 bits of data
-    i2c.read(xgAddress, cmd+1, 1);
-
-    // Then mask out the accel scale bits:
-    cmd[1] &= 0xFF^(0x3 << 3);
-    // Then shift in our new scale bits:
-    cmd[1] |= aScl << 3;
-
-    // Write the accelscale out to the accel
-    i2c.write(xgAddress, cmd, 2);
-    
-    // We've updated the sensor, but we also need to update our class variables
-    // First update aScale:
-    aScale = aScl;
-    // Then calculate a new aRes, which relies on aScale being set correctly:
-    calcaRes();
-}
-
-void LSM6DS3::setGyroODR(gyro_odr gRate)
-{
-    // The start of the addresses we want to read from
-    char cmd[2] = {
-        CTRL2_G,
-        0
-    };
-    
-    // Set low power based on ODR, else keep sensor on high performance
-    if(gRate == G_ODR_13_BW_0 | gRate == G_ODR_26_BW_2 | gRate == G_ODR_52_BW_16) {
-        char cmdLow[2] ={
-            CTRL7_G,
-            1
-        };
-        
-        i2c.write(xgAddress, cmdLow, 2);
-    }
-    else {
-        char cmdLow[2] ={
-            CTRL7_G,
-            0
-        };
-        
-        i2c.write(xgAddress, cmdLow, 2);
-    }
-
-    // Write the address we are going to read from and don't end the transaction
-    i2c.write(xgAddress, cmd, 1, true);
-    // Read in all the 8 bits of data
-    i2c.read(xgAddress, cmd+1, 1);
-
-    // Then mask out the gyro odr bits:
-    cmd[1] &= (0x3 << 3);
-    // Then shift in our new odr bits:
-    cmd[1] |= gRate;
-
-    // Write the gyroodr out to the gyro
-    i2c.write(xgAddress, cmd, 2);
-}
-
-void LSM6DS3::setAccelODR(accel_odr aRate)
-{
-    // The start of the addresses we want to read from
-    char cmd[2] = {
-        CTRL1_XL,
-        0
-    };
-    
-    // Set low power based on ODR, else keep sensor on high performance
-    if(aRate == A_ODR_13 | aRate == A_ODR_26 | aRate == A_ODR_52) {
-        char cmdLow[2] ={
-            CTRL6_C,
-            1
-        };
-        
-        i2c.write(xgAddress, cmdLow, 2);
-    }
-    else {
-        char cmdLow[2] ={
-            CTRL6_C,
-            0
-        };
-        
-        i2c.write(xgAddress, cmdLow, 2);
-    }
-
-    // Write the address we are going to read from and don't end the transaction
-    i2c.write(xgAddress, cmd, 1, true);
-    // Read in all the 8 bits of data
-    i2c.read(xgAddress, cmd+1, 1);
-
-    // Then mask out the accel odr bits:
-    cmd[1] &= 0xFF^(0x7 << 5);
-    // Then shift in our new odr bits:
-    cmd[1] |= aRate << 5;
-
-    // Write the accelodr out to the accel
-    i2c.write(xgAddress, cmd, 2);
-}
-
-void LSM6DS3::calcgRes()
-{
-    // Possible gyro scales (and their register bit settings) are:
-    // 245 DPS (00), 500 DPS (01), 2000 DPS (10).
-    switch (gScale)
-    {
-        case G_SCALE_245DPS:
-            gRes = 245.0 / 32768.0;
-            break;
-        case G_SCALE_500DPS:
-            gRes = 500.0 / 32768.0;
-            break;
-        case G_SCALE_2000DPS:
-            gRes = 2000.0 / 32768.0;
-            break;
-    }
-}
-
-void LSM6DS3::calcaRes()
-{
-    // Possible accelerometer scales (and their register bit settings) are:
-    // 2 g (000), 4g (001), 6g (010) 8g (011), 16g (100).
-    switch (aScale)
-    {
-        case A_SCALE_2G:
-            aRes = 2.0 / 32768.0;
-            break;
-        case A_SCALE_4G:
-            aRes = 4.0 / 32768.0;
-            break;
-        case A_SCALE_8G:
-            aRes = 8.0 / 32768.0;
-            break;
-        case A_SCALE_16G:
-            aRes = 16.0 / 32768.0;
-            break;
-    }
-}
\ No newline at end of file
--- a/LSM6DS3.h	Tue Jun 21 20:51:25 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +0,0 @@
-// Based on Eugene Gonzalez's version of LSM9DS1_Demo
-// Modified by Sherry Yang for LSM6DS3 sensor
-#ifndef _LSM6DS3_H__
-#define _LSM6DS3_H__
-
-#include "mbed.h"
-
-/////////////////////////////////////////
-// LSM6DS3 Accel/Gyro (XL/G) Registers //
-/////////////////////////////////////////
-#define RAM_ACCESS            0x01
-#define SENSOR_SYNC_TIME      0x04
-#define SENSOR_SYNC_EN        0x05
-#define FIFO_CTRL1            0x06
-#define FIFO_CTRL2            0x07
-#define FIFO_CTRL3            0x08
-#define FIFO_CTRL4            0x09
-#define FIFO_CTRL5            0x0A
-#define ORIENT_CFG_G          0x0B
-#define REFERENCE_G           0x0C
-#define INT1_CTRL             0x0D
-#define INT2_CTRL             0x0E
-#define WHO_AM_I_REG          0X0F
-#define CTRL1_XL              0x10
-#define CTRL2_G               0x11
-#define CTRL3_C               0x12
-#define CTRL4_C               0x13
-#define CTRL5_C               0x14
-#define CTRL6_C               0x15
-#define CTRL7_G               0x16
-#define CTRL8_XL              0x17
-#define CTRL9_XL              0x18
-#define CTRL10_C              0x19
-#define MASTER_CONFIG         0x1A
-#define WAKE_UP_SRC           0x1B
-#define TAP_SRC               0x1C
-#define D6D_SRC               0x1D
-#define STATUS_REG            0x1E
-#define OUT_TEMP_L            0x20
-#define OUT_TEMP_H            0x21
-#define OUTX_L_G              0x22
-#define OUTX_H_G              0x23
-#define OUTY_L_G              0x24
-#define OUTY_H_G              0x25
-#define OUTZ_L_G              0x26
-#define OUTZ_H_G              0x27
-#define OUTX_L_XL             0x28
-#define OUTX_H_XL             0x29
-#define OUTY_L_XL             0x2A
-#define OUTY_H_XL             0x2B
-#define OUTZ_L_XL             0x2C
-#define OUTZ_H_XL             0x2D
-#define SENSORHUB1_REG        0x2E
-#define SENSORHUB2_REG        0x2F
-#define SENSORHUB3_REG        0x30
-#define SENSORHUB4_REG        0x31
-#define SENSORHUB5_REG        0x32
-#define SENSORHUB6_REG        0x33
-#define SENSORHUB7_REG        0x34
-#define SENSORHUB8_REG        0x35
-#define SENSORHUB9_REG        0x36
-#define SENSORHUB10_REG       0x37
-#define SENSORHUB11_REG       0x38
-#define SENSORHUB12_REG       0x39
-#define FIFO_STATUS1          0x3A
-#define FIFO_STATUS2          0x3B
-#define FIFO_STATUS3          0x3C
-#define FIFO_STATUS4          0x3D
-#define FIFO_DATA_OUT_L       0x3E
-#define FIFO_DATA_OUT_H       0x3F
-#define TIMESTAMP0_REG        0x40
-#define TIMESTAMP1_REG        0x41
-#define TIMESTAMP2_REG        0x42
-#define STEP_COUNTER_L        0x4B
-#define STEP_COUNTER_H        0x4C
-#define FUNC_SR               0x53
-#define TAP_CFG               0x58
-#define TAP_THS_6D            0x59
-#define INT_DUR2              0x5A
-#define WAKE_UP_THS           0x5B
-#define WAKE_UP_DUR           0x5C
-#define FREE_FALL             0x5D
-#define MD1_CFG               0x5E
-#define MD2_CFG               0x5F
-
-// Possible I2C addresses for the accel/gyro
-#define LSM6DS3_AG_I2C_ADDR(sa0) ((sa0) ? 0xD6 : 0xD4)
-
-/**
- * LSM6DS3 Class - driver for the 9 DoF IMU
- */
-class LSM6DS3
-{
-public:
-
-    /// gyro_scale defines the possible full-scale ranges of the gyroscope:
-    enum gyro_scale
-    {
-        G_SCALE_245DPS = 0x0 << 3,     // 00 << 3: +/- 245 degrees per second
-        G_SCALE_500DPS = 0x1 << 3,     // 01 << 3: +/- 500 dps
-        G_SCALE_1000DPS = 0x2 << 3,    // 10 << 3: +/- 1000 dps
-        G_SCALE_2000DPS = 0x3 << 3     // 11 << 3: +/- 2000 dps
-    };
-
-    /// gyro_odr defines all possible data rate/bandwidth combos of the gyro:
-    enum gyro_odr
-    {                               // ODR (Hz) --- Cutoff
-        G_POWER_DOWN     = 0x00,    //  0           0
-        G_ODR_13_BW_0    = 0x10,    //  12.5        0.0081      low power
-        G_ODR_26_BW_2    = 0x20,    //  26          2.07        low power
-        G_ODR_52_BW_16   = 0x30,    //  52          16.32       low power
-        G_ODR_104        = 0x40,    //  104         
-        G_ODR_208        = 0x50,    //  208         
-        G_ODR_416        = 0x60,    //  416         
-        G_ODR_833        = 0x70,    //  833         
-        G_ODR_1660       = 0x80     //  1660
-    };
-
-    /// accel_scale defines all possible FSR's of the accelerometer:
-    enum accel_scale
-    {
-        A_SCALE_2G, // 00: +/- 2g
-        A_SCALE_16G,// 01: +/- 16g
-        A_SCALE_4G, // 10: +/- 4g
-        A_SCALE_8G  // 11: +/- 8g
-    };
-
-    /// accel_oder defines all possible output data rates of the accelerometer:
-    enum accel_odr
-    {
-        A_POWER_DOWN,   // Power-down mode (0x0)
-        A_ODR_13,       // 12.5 Hz (0x1)        low power
-        A_ODR_26,       // 26 Hz (0x2)          low power
-        A_ODR_52,       // 52 Hz (0x3)          low power
-        A_ODR_104,      // 104 Hz (0x4)         normal mode
-        A_ODR_208,      // 208 Hz (0x5)         normal mode
-        A_ODR_416,      // 416 Hz (0x6)         high performance
-        A_ODR_833,      // 833 Hz (0x7)         high performance
-        A_ODR_1660,     // 1.66 kHz (0x8)       high performance
-        A_ODR_3330,     // 3.33 kHz (0x9)       high performance
-        A_ODR_6660,     // 6.66 kHz (0xA)       high performance
-    };
-
-    // accel_bw defines all possible bandwiths for low-pass filter of the accelerometer:
-    enum accel_bw
-    {
-        A_BW_AUTO_SCALE = 0x0,  // Automatic BW scaling (0x0)
-        A_BW_408 = 0x4,         // 408 Hz (0x4)
-        A_BW_211 = 0x5,         // 211 Hz (0x5)
-        A_BW_105 = 0x6,         // 105 Hz (0x6)
-        A_BW_50 = 0x7           // 50 Hz (0x7)
-    };
-    
-    
-
-    // We'll store the gyro, and accel, readings in a series of
-    // public class variables. Each sensor gets three variables -- one for each
-    // axis. Call readGyro(), and readAccel() first, before using
-    // these variables!
-    // These values are the RAW signed 16-bit readings from the sensors.
-    int16_t gx_raw, gy_raw, gz_raw; // x, y, and z axis readings of the gyroscope
-    int16_t ax_raw, ay_raw, az_raw; // x, y, and z axis readings of the accelerometer
-    int16_t temperature_raw;
-
-    // floating-point values of scaled data in real-world units
-    float gx, gy, gz;
-    float ax, ay, az;
-    float temperature_c, temperature_f; // temperature in celcius and fahrenheit
-    float intr;
-
-    
-    /**  LSM6DS3 -- LSM6DS3 class constructor
-    *  The constructor will set up a handful of private variables, and set the
-    *  communication mode as well.
-    *  Input:
-    *   - interface = Either MODE_SPI or MODE_I2C, whichever you're using
-    *               to talk to the IC.
-    *   - xgAddr = If MODE_I2C, this is the I2C address of the accel/gyro.
-    *               If MODE_SPI, this is the chip select pin of the accel/gyro (CS_A/G)
-    */
-    LSM6DS3(PinName sda, PinName scl, uint8_t xgAddr = LSM6DS3_AG_I2C_ADDR(1));
-    
-    /**  begin() -- Initialize the gyro, and accelerometer.
-    *  This will set up the scale and output rate of each sensor. It'll also
-    *  "turn on" every sensor and every axis of every sensor.
-    *  Input:
-    *   - gScl = The scale of the gyroscope. This should be a gyro_scale value.
-    *   - aScl = The scale of the accelerometer. Should be a accel_scale value.
-    *   - gODR = Output data rate of the gyroscope. gyro_odr value.
-    *   - aODR = Output data rate of the accelerometer. accel_odr value.
-    *  Output: The function will return an unsigned 16-bit value. The most-sig
-    *       bytes of the output are the WHO_AM_I reading of the accel/gyro.
-    *  All parameters have a defaulted value, so you can call just "begin()".
-    *  Default values are FSR's of: +/- 245DPS, 4g, 2Gs; ODRs of 119 Hz for 
-    *  gyro, 119 Hz for accelerometer.
-    *  Use the return value of this function to verify communication.
-    */
-    uint16_t begin(gyro_scale gScl = G_SCALE_245DPS, 
-                accel_scale aScl = A_SCALE_2G, gyro_odr gODR = G_ODR_104, 
-                accel_odr aODR = A_ODR_104);
-    
-    /**  readGyro() -- Read the gyroscope output registers.
-    *  This function will read all six gyroscope output registers.
-    *  The readings are stored in the class' gx_raw, gy_raw, and gz_raw variables. Read
-    *  those _after_ calling readGyro().
-    */
-    void readGyro();
-    
-    /**  readAccel() -- Read the accelerometer output registers.
-    *  This function will read all six accelerometer output registers.
-    *  The readings are stored in the class' ax_raw, ay_raw, and az_raw variables. Read
-    *  those _after_ calling readAccel().
-    */
-    void readAccel();
-    
-    /**  readTemp() -- Read the temperature output register.
-    *  This function will read two temperature output registers.
-    *  The combined readings are stored in the class' temperature variables. Read
-    *  those _after_ calling readTemp().
-    */
-    void readTemp();
-    
-    /** Read Interrupt **/
-    void readIntr();
-    
-    /**  setGyroScale() -- Set the full-scale range of the gyroscope.
-    *  This function can be called to set the scale of the gyroscope to 
-    *  245, 500, or 2000 degrees per second.
-    *  Input:
-    *   - gScl = The desired gyroscope scale. Must be one of three possible
-    *       values from the gyro_scale enum.
-    */
-    void setGyroScale(gyro_scale gScl);
-    
-    /**  setAccelScale() -- Set the full-scale range of the accelerometer.
-    *  This function can be called to set the scale of the accelerometer to
-    *  2, 4, 8, or 16 g's.
-    *  Input:
-    *   - aScl = The desired accelerometer scale. Must be one of five possible
-    *       values from the accel_scale enum.
-    */
-    void setAccelScale(accel_scale aScl);
-    
-    /**  setGyroODR() -- Set the output data rate and bandwidth of the gyroscope
-    *  Input:
-    *   - gRate = The desired output rate and cutoff frequency of the gyro.
-    *       Must be a value from the gyro_odr enum (check above).
-    */
-    void setGyroODR(gyro_odr gRate);
-    
-    /**  setAccelODR() -- Set the output data rate of the accelerometer
-    *  Input:
-    *   - aRate = The desired output rate of the accel.
-    *       Must be a value from the accel_odr enum (check above).
-    */
-    void setAccelODR(accel_odr aRate);
-
-
-private:    
-    /**  xgAddress store the I2C address
-    *  for each sensor.
-    */
-    uint8_t xgAddress;
-    
-    // I2C bus
-    I2C i2c;
-
-    /**  gScale, and aScale store the current scale range for each 
-    *  sensor. Should be updated whenever that value changes.
-    */
-    gyro_scale gScale;
-    accel_scale aScale;
-    
-    /**  gRes, and aRes store the current resolution for each sensor. 
-    *  Units of these values would be DPS (or g's or Gs's) per ADC tick.
-    *  This value is calculated as (sensor scale) / (2^15).
-    */
-    float gRes, aRes;
-    
-    /**  initGyro() -- Sets up the gyroscope to begin reading.
-    *  This function steps through all three gyroscope control registers.
-    */
-    void initGyro();
-    
-    /**  initAccel() -- Sets up the accelerometer to begin reading.
-    *  This function steps through all accelerometer related control registers.
-    */
-    void initAccel();
-    
-    /** Setup Interrupt **/
-    void initIntr();
-    
-    /**  calcgRes() -- Calculate the resolution of the gyroscope.
-    *  This function will set the value of the gRes variable. gScale must
-    *  be set prior to calling this function.
-    */
-    void calcgRes();
-    
-    /**  calcaRes() -- Calculate the resolution of the accelerometer.
-    *  This function will set the value of the aRes variable. aScale must
-    *  be set prior to calling this function.
-    */
-    void calcaRes();
-};
-
-#endif // _LSM6DS3_H //
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LSM6DS3_sj.cpp	Tue May 02 17:30:18 2017 +0000
@@ -0,0 +1,389 @@
+#include "LSM6DS3_sj.h"
+
+LSM6DS3::LSM6DS3(PinName sda, PinName scl, uint8_t xgAddr) : i2c(sda, scl)
+{
+    // xgAddress will store the 7-bit I2C address, if using I2C.
+    xgAddress = xgAddr;
+    i2c.frequency(400000);
+}
+
+uint16_t LSM6DS3::begin(gyro_scale gScl, accel_scale aScl,  
+                        gyro_odr gODR, accel_odr aODR)
+{
+    // Store the given scales in class variables. These scale variables
+    // are used throughout to calculate the actual g's, DPS,and Gs's.
+    gScale = gScl;
+    aScale = aScl;
+    
+    // Once we have the scale values, we can calculate the resolution
+    // of each sensor. That's what these functions are for. One for each sensor
+    calcgRes(); // Calculate DPS / ADC tick, stored in gRes variable
+    calcaRes(); // Calculate g / ADC tick, stored in aRes variable
+    
+    
+    // To verify communication, we can read from the WHO_AM_I register of
+    // each device. Store those in a variable so we can return them.
+    // The start of the addresses we want to read from
+    char cmd[2] = {
+        WHO_AM_I_REG,
+        0
+    };
+
+    // Write the address we are going to read from and don't end the transaction
+    i2c.write(xgAddress, cmd, 1, true);
+    // Read in all the 8 bits of data
+    i2c.read(xgAddress, cmd+1, 1);
+    uint8_t xgTest = cmd[1];                    // Read the accel/gyro WHO_AM_I
+        
+    // Gyro initialization stuff:
+    initGyro(); // This will "turn on" the gyro. Setting up interrupts, etc.
+    setGyroODR(gODR); // Set the gyro output data rate and bandwidth.
+    setGyroScale(gScale); // Set the gyro range
+    
+    // Accelerometer initialization stuff:
+    initAccel(); // "Turn on" all axes of the accel. Set up interrupts, etc.
+    setAccelODR(aODR); // Set the accel data rate.
+    setAccelScale(aScale); // Set the accel range.
+    
+    // Interrupt initialization stuff;
+    initIntr();
+    
+    // Once everything is initialized, return the WHO_AM_I registers we read:
+    return xgTest;
+}
+
+void LSM6DS3::initGyro()
+{
+    char cmd[2] = {
+        CTRL2_G,
+        gScale | G_ODR_104,
+        
+    };
+
+    // Write the data to the gyro control registers
+    i2c.write(xgAddress, cmd, 2);
+}
+
+void LSM6DS3::initAccel()
+{
+    char cmd[2] = {
+        CTRL1_XL,
+        (A_ODR_104 ) | (aScale) | (A_BW_400),  
+    };
+
+    // Write the data to the accel control registers
+    i2c.write(xgAddress, cmd, 2);
+}
+
+void LSM6DS3::initIntr()
+{
+    char cmd[2];
+    
+    cmd[0] = TAP_CFG;
+    cmd[1] = 0x0E;
+    i2c.write(xgAddress, cmd, 2);
+    cmd[0] = TAP_THS_6D;
+    cmd[1] = 0x03;
+    i2c.write(xgAddress, cmd, 2);
+    cmd[0] = INT_DUR2;
+    cmd[1] = 0x7F;
+    i2c.write(xgAddress, cmd, 2);
+    cmd[0] = WAKE_UP_THS;
+    cmd[1] = 0x80;
+    i2c.write(xgAddress, cmd, 2);
+    cmd[0] = MD1_CFG;
+    cmd[1] = 0x48;
+    i2c.write(xgAddress, cmd, 2);
+}
+
+void LSM6DS3::readAccel()
+{
+    // The data we are going to read from the accel
+    char data[6];
+
+    // Set addresses
+    char subAddressXL = OUTX_L_XL;
+    char subAddressXH = OUTX_H_XL;
+    char subAddressYL = OUTY_L_XL;
+    char subAddressYH = OUTY_H_XL;
+    char subAddressZL = OUTZ_L_XL;
+    char subAddressZH = OUTZ_H_XL;
+
+    // Write the address we are going to read from and don't end the transaction
+    i2c.write(xgAddress, &subAddressXL, 1, true);
+    // Read in register containing the axes data and alocated to the correct index
+    i2c.read(xgAddress, data, 1);
+    
+    i2c.write(xgAddress, &subAddressXH, 1, true);
+    i2c.read(xgAddress, (data + 1), 1);
+    i2c.write(xgAddress, &subAddressYL, 1, true);
+    i2c.read(xgAddress, (data + 2), 1);
+    i2c.write(xgAddress, &subAddressYH, 1, true);
+    i2c.read(xgAddress, (data + 3), 1);
+    i2c.write(xgAddress, &subAddressZL, 1, true);
+    i2c.read(xgAddress, (data + 4), 1);
+    i2c.write(xgAddress, &subAddressZH, 1, true);
+    i2c.read(xgAddress, (data + 5), 1);
+
+    // Reassemble the data and convert to g
+    ax_raw = data[0] | (data[1] << 8);
+    ay_raw = data[2] | (data[3] << 8);
+    az_raw = data[4] | (data[5] << 8);
+    ax = ax_raw * aRes;
+    ay = ay_raw * aRes;
+    az = az_raw * aRes;
+}
+
+void LSM6DS3::readIntr()
+{
+    char data[1];
+    char subAddress = TAP_SRC;
+
+    i2c.write(xgAddress, &subAddress, 1, true);
+    i2c.read(xgAddress, data, 1);
+
+    intr = (float)data[0];
+}
+
+void LSM6DS3::readTemp()
+{
+    // The data we are going to read from the temp
+    char data[2];
+
+    // Set addresses
+    char subAddressL = OUT_TEMP_L;
+    char subAddressH = OUT_TEMP_H;
+
+    // Write the address we are going to read from and don't end the transaction
+    i2c.write(xgAddress, &subAddressL, 1, true);
+    // Read in register containing the temperature data and alocated to the correct index
+    i2c.read(xgAddress, data, 1);
+    
+    i2c.write(xgAddress, &subAddressH, 1, true);
+    i2c.read(xgAddress, (data + 1), 1);
+
+    // Temperature is a 12-bit signed integer   
+    temperature_raw = data[0] | (data[1] << 8);
+
+    temperature_c = (float)temperature_raw / 16.0 + 25.0;
+    temperature_f = temperature_c * 1.8 + 32.0;
+}
+
+
+void LSM6DS3::readGyro()
+{
+    // The data we are going to read from the gyro
+    char data[6];
+
+    // Set addresses
+    char subAddressXL = OUTX_L_G;
+    char subAddressXH = OUTX_H_G;
+    char subAddressYL = OUTY_L_G;
+    char subAddressYH = OUTY_H_G;
+    char subAddressZL = OUTZ_L_G;
+    char subAddressZH = OUTZ_H_G;
+
+    // Write the address we are going to read from and don't end the transaction
+    i2c.write(xgAddress, &subAddressXL, 1, true);
+    // Read in register containing the axes data and alocated to the correct index
+    i2c.read(xgAddress, data, 1);
+    
+    i2c.write(xgAddress, &subAddressXH, 1, true);
+    i2c.read(xgAddress, (data + 1), 1);
+    i2c.write(xgAddress, &subAddressYL, 1, true);
+    i2c.read(xgAddress, (data + 2), 1);
+    i2c.write(xgAddress, &subAddressYH, 1, true);
+    i2c.read(xgAddress, (data + 3), 1);
+    i2c.write(xgAddress, &subAddressZL, 1, true);
+    i2c.read(xgAddress, (data + 4), 1);
+    i2c.write(xgAddress, &subAddressZH, 1, true);
+    i2c.read(xgAddress, (data + 5), 1);
+
+    // Reassemble the data and convert to degrees/sec
+    gx_raw = data[0] | (data[1] << 8);
+    gy_raw = data[2] | (data[3] << 8);
+    gz_raw = data[4] | (data[5] << 8);
+    gx = gx_raw * gRes;
+    gy = gy_raw * gRes;
+    gz = gz_raw * gRes;
+}
+
+void LSM6DS3::setGyroScale(gyro_scale gScl)
+{
+    // The start of the addresses we want to read from
+    char cmd[2] = {
+        CTRL2_G,
+        0
+    };
+
+    // Write the address we are going to read from and don't end the transaction
+    i2c.write(xgAddress, cmd, 1, true);
+    // Read in all the 8 bits of data
+    i2c.read(xgAddress, cmd+1, 1);
+
+    // Then mask out the gyro scale bits:
+    cmd[1] &= 0xFF^(0x3 << 2);
+    // Then shift in our new scale bits:
+    cmd[1] |= gScl;
+
+    // Write the gyroscale out to the gyro
+    i2c.write(xgAddress, cmd, 2);
+    
+    // We've updated the sensor, but we also need to update our class variables
+    // First update gScale:
+    gScale = gScl;
+    // Then calculate a new gRes, which relies on gScale being set correctly:
+    calcgRes();
+}
+
+void LSM6DS3::setAccelScale(accel_scale aScl)
+{
+    // The start of the addresses we want to read from
+    char cmd[2] = {
+        CTRL1_XL,
+        0
+    };
+
+    // Write the address we are going to read from and don't end the transaction
+    i2c.write(xgAddress, cmd, 1, true);
+    // Read in all the 8 bits of data
+    i2c.read(xgAddress, cmd+1, 1);
+
+    // Then mask out the accel scale bits:
+    cmd[1] &= 0xFF^(0x3 << 2);
+    // Then shift in our new scale bits:
+    cmd[1] |= aScl;
+
+    // Write the accelscale out to the accel
+    i2c.write(xgAddress, cmd, 2);
+    
+    // We've updated the sensor, but we also need to update our class variables
+    // First update aScale:
+    aScale = aScl;
+    // Then calculate a new aRes, which relies on aScale being set correctly:
+    calcaRes();
+}
+
+void LSM6DS3::setGyroODR(gyro_odr gRate)
+{
+    // The start of the addresses we want to read from
+    char cmd[2] = {
+        CTRL2_G,
+        0
+    };
+    
+    // Set low power based on ODR, else keep sensor on high performance
+    if(gRate == G_ODR_13_BW_0 | gRate == G_ODR_26_BW_2 | gRate == G_ODR_52_BW_16) {
+        char cmdLow[2] ={
+            CTRL7_G,
+            1
+        };
+        
+        i2c.write(xgAddress, cmdLow, 2);
+    }
+    else {
+        char cmdLow[2] ={
+            CTRL7_G,
+            0
+        };
+        
+        i2c.write(xgAddress, cmdLow, 2);
+    }
+
+    // Write the address we are going to read from and don't end the transaction
+    i2c.write(xgAddress, cmd, 1, true);
+    // Read in all the 8 bits of data
+    i2c.read(xgAddress, cmd+1, 1);
+
+    // Then mask out the gyro odr bits:
+    cmd[1] &= 0xFF^(0x0F << 4);
+    // Then shift in our new odr bits:
+    cmd[1] |= gRate;
+
+    // Write the gyroodr out to the gyro
+    i2c.write(xgAddress, cmd, 2);
+}
+
+void LSM6DS3::setAccelODR(accel_odr aRate)
+{
+    // The start of the addresses we want to read from
+    char cmd[2] = {
+        CTRL1_XL,
+        0
+    };
+    
+    // Set low power based on ODR, else keep sensor on high performance
+    if(aRate == A_ODR_13 | aRate == A_ODR_26 | aRate == A_ODR_52) {
+        char cmdLow[2] ={
+            CTRL6_C,
+            1
+        };
+        
+        i2c.write(xgAddress, cmdLow, 2);
+    }
+    else {
+        char cmdLow[2] ={
+            CTRL6_C,
+            0
+        };
+        
+        i2c.write(xgAddress, cmdLow, 2);
+    }
+
+    // Write the address we are going to read from and don't end the transaction
+    i2c.write(xgAddress, cmd, 1, true);
+    // Read in all the 8 bits of data
+    i2c.read(xgAddress, cmd+1, 1);
+
+    // Then mask out the accel odr bits:
+    cmd[1] &= 0xFF^(0x0F << 4);
+    // Then shift in our new odr bits:
+    cmd[1] |= aRate;
+    
+//    Serial pc(USBTX, USBRX);
+//    pc.baud(921600);
+//    pc.printf("i2c Command = 0x%X 0x%X \r\n", cmd[0], cmd[1] );
+//    delete &pc;
+    
+    // Write the accelodr out to the accel
+    i2c.write(xgAddress, cmd, 2);
+}
+
+void LSM6DS3::calcgRes()
+{
+    // Possible gyro scales (and their register bit settings) are:
+    // 245 DPS (00), 500 DPS (01), 2000 DPS (10).
+    switch (gScale)
+    {
+        case G_SCALE_245DPS:
+            gRes = 245.0 / 32768.0;
+            break;
+        case G_SCALE_500DPS:
+            gRes = 500.0 / 32768.0;
+            break;
+        case G_SCALE_2000DPS:
+            gRes = 2000.0 / 32768.0;
+            break;
+    }
+}
+
+void LSM6DS3::calcaRes()
+{
+    // Possible accelerometer scales (and their register bit settings) are:
+    // 2 g (000), 4g (001), 6g (010) 8g (011), 16g (100).
+    switch (aScale)
+    {
+        case A_SCALE_2G:
+            aRes = 2.0 / 32768.0;
+            break;
+        case A_SCALE_4G:
+            aRes = 4.0 / 32768.0;
+            break;
+        case A_SCALE_8G:
+            aRes = 8.0 / 32768.0;
+            break;
+        case A_SCALE_16G:
+            aRes = 16.0 / 32768.0;
+            break;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LSM6DS3_sj.h	Tue May 02 17:30:18 2017 +0000
@@ -0,0 +1,307 @@
+// Based on Eugene Gonzalez's version of LSM9DS1_Demo
+// Modified by Sherry Yang for LSM6DS3 sensor
+#ifndef _LSM6DS3_H__
+#define _LSM6DS3_H__
+
+#include "mbed.h"
+
+/////////////////////////////////////////
+// LSM6DS3 Accel/Gyro (XL/G) Registers //
+/////////////////////////////////////////
+#define RAM_ACCESS            0x01
+#define SENSOR_SYNC_TIME      0x04
+#define SENSOR_SYNC_EN        0x05
+#define FIFO_CTRL1            0x06
+#define FIFO_CTRL2            0x07
+#define FIFO_CTRL3            0x08
+#define FIFO_CTRL4            0x09
+#define FIFO_CTRL5            0x0A
+#define ORIENT_CFG_G          0x0B
+#define REFERENCE_G           0x0C
+#define INT1_CTRL             0x0D
+#define INT2_CTRL             0x0E
+#define WHO_AM_I_REG          0X0F
+#define CTRL1_XL              0x10
+#define CTRL2_G               0x11
+#define CTRL3_C               0x12
+#define CTRL4_C               0x13
+#define CTRL5_C               0x14
+#define CTRL6_C               0x15
+#define CTRL7_G               0x16
+#define CTRL8_XL              0x17
+#define CTRL9_XL              0x18
+#define CTRL10_C              0x19
+#define MASTER_CONFIG         0x1A
+#define WAKE_UP_SRC           0x1B
+#define TAP_SRC               0x1C
+#define D6D_SRC               0x1D
+#define STATUS_REG            0x1E
+#define OUT_TEMP_L            0x20
+#define OUT_TEMP_H            0x21
+#define OUTX_L_G              0x22
+#define OUTX_H_G              0x23
+#define OUTY_L_G              0x24
+#define OUTY_H_G              0x25
+#define OUTZ_L_G              0x26
+#define OUTZ_H_G              0x27
+#define OUTX_L_XL             0x28
+#define OUTX_H_XL             0x29
+#define OUTY_L_XL             0x2A
+#define OUTY_H_XL             0x2B
+#define OUTZ_L_XL             0x2C
+#define OUTZ_H_XL             0x2D
+#define SENSORHUB1_REG        0x2E
+#define SENSORHUB2_REG        0x2F
+#define SENSORHUB3_REG        0x30
+#define SENSORHUB4_REG        0x31
+#define SENSORHUB5_REG        0x32
+#define SENSORHUB6_REG        0x33
+#define SENSORHUB7_REG        0x34
+#define SENSORHUB8_REG        0x35
+#define SENSORHUB9_REG        0x36
+#define SENSORHUB10_REG       0x37
+#define SENSORHUB11_REG       0x38
+#define SENSORHUB12_REG       0x39
+#define FIFO_STATUS1          0x3A
+#define FIFO_STATUS2          0x3B
+#define FIFO_STATUS3          0x3C
+#define FIFO_STATUS4          0x3D
+#define FIFO_DATA_OUT_L       0x3E
+#define FIFO_DATA_OUT_H       0x3F
+#define TIMESTAMP0_REG        0x40
+#define TIMESTAMP1_REG        0x41
+#define TIMESTAMP2_REG        0x42
+#define STEP_COUNTER_L        0x4B
+#define STEP_COUNTER_H        0x4C
+#define FUNC_SR               0x53
+#define TAP_CFG               0x58
+#define TAP_THS_6D            0x59
+#define INT_DUR2              0x5A
+#define WAKE_UP_THS           0x5B
+#define WAKE_UP_DUR           0x5C
+#define FREE_FALL             0x5D
+#define MD1_CFG               0x5E
+#define MD2_CFG               0x5F
+
+// Possible I2C addresses for the accel/gyro
+#define LSM6DS3_AG_I2C_ADDR(sa0) ((sa0) ? 0xD6 : 0xD4)
+
+/**
+ * LSM6DS3 Class - driver for the 9 DoF IMU
+ */
+class LSM6DS3
+{
+public:
+
+    /// gyro_scale defines the possible full-scale ranges of the gyroscope:
+    enum gyro_scale
+    {
+        G_SCALE_245DPS = 0x0 << 2,     // 00 << 3: +/- 245 degrees per second
+        G_SCALE_500DPS = 0x1 << 2,     // 01 << 3: +/- 500 dps
+        G_SCALE_1000DPS = 0x2 << 2,    // 10 << 3: +/- 1000 dps
+        G_SCALE_2000DPS = 0x3 << 2     // 11 << 3: +/- 2000 dps
+    };
+
+    /// gyro_odr defines all possible data rate/bandwidth combos of the gyro:
+    enum gyro_odr
+    {                               // ODR (Hz) --- Cutoff
+        G_POWER_DOWN     = 0x00,    //  0           0
+        G_ODR_13_BW_0    = 0x10,    //  12.5        0.0081      low power
+        G_ODR_26_BW_2    = 0x20,    //  26          2.07        low power
+        G_ODR_52_BW_16   = 0x30,    //  52          16.32       low power
+        G_ODR_104        = 0x40,    //  104         
+        G_ODR_208        = 0x50,    //  208         
+        G_ODR_416        = 0x60,    //  416         
+        G_ODR_833        = 0x70,    //  833         
+        G_ODR_1660       = 0x80     //  1660
+    };
+
+    /// accel_scale defines all possible FSR's of the accelerometer:
+    enum accel_scale
+    {
+        A_SCALE_2G = 0x00, // 00: +/- 2g
+        A_SCALE_16G = 0x04,// 01: +/- 16g
+        A_SCALE_4G = 0x08, // 10: +/- 4g
+        A_SCALE_8G = 0x0C  // 11: +/- 8g
+    };
+
+    /// accel_oder defines all possible output data rates of the accelerometer:
+    enum accel_odr
+    {
+        A_POWER_DOWN=0x00,   // Power-down mode (0x0)
+        A_ODR_13=0x10,       // 12.5 Hz (0x1)        low power
+        A_ODR_26=0x20,       // 26 Hz (0x2)          low power
+        A_ODR_52=0x30,       // 52 Hz (0x3)          low power
+        A_ODR_104=0x40,      // 104 Hz (0x4)         normal mode
+        A_ODR_208=0x50,      // 208 Hz (0x5)         normal mode
+        A_ODR_416=0x60,      // 416 Hz (0x6)         high performance
+        A_ODR_833=0x70,      // 833 Hz (0x7)         high performance
+        A_ODR_1660=0x80,     // 1.66 kHz (0x8)       high performance
+        A_ODR_3330=0x90,     // 3.33 kHz (0x9)       high performance
+        A_ODR_6660=0xA0,     // 6.66 kHz (0xA)       high performance
+    };
+
+    // accel_bw defines all possible bandwiths for low-pass filter of the accelerometer:
+    enum accel_bw
+    {
+        A_BW_AUTO_SCALE = 0x0,  // Automatic BW scaling (0x0)
+        A_BW_400 = 0x0,         // 408 Hz (0x0)
+        A_BW_200 = 0x1,         // 211 Hz (0x1)
+        A_BW_100 = 0x2,         // 105 Hz (0x2)
+        A_BW_50 = 0x3           // 50 Hz (0x3)
+    };
+    
+    
+
+    // We'll store the gyro, and accel, readings in a series of
+    // public class variables. Each sensor gets three variables -- one for each
+    // axis. Call readGyro(), and readAccel() first, before using
+    // these variables!
+    // These values are the RAW signed 16-bit readings from the sensors.
+    int16_t gx_raw, gy_raw, gz_raw; // x, y, and z axis readings of the gyroscope
+    int16_t ax_raw, ay_raw, az_raw; // x, y, and z axis readings of the accelerometer
+    int16_t temperature_raw;
+
+    // floating-point values of scaled data in real-world units
+    float gx, gy, gz;
+    float ax, ay, az;
+    float temperature_c, temperature_f; // temperature in celcius and fahrenheit
+    float intr;
+
+    
+    /**  LSM6DS3 -- LSM6DS3 class constructor
+    *  The constructor will set up a handful of private variables, and set the
+    *  communication mode as well.
+    *  Input:
+    *   - interface = Either MODE_SPI or MODE_I2C, whichever you're using
+    *               to talk to the IC.
+    *   - xgAddr = If MODE_I2C, this is the I2C address of the accel/gyro.
+    *               If MODE_SPI, this is the chip select pin of the accel/gyro (CS_A/G)
+    */
+    LSM6DS3(PinName sda, PinName scl, uint8_t xgAddr = LSM6DS3_AG_I2C_ADDR(1));
+    
+    /**  begin() -- Initialize the gyro, and accelerometer.
+    *  This will set up the scale and output rate of each sensor. It'll also
+    *  "turn on" every sensor and every axis of every sensor.
+    *  Input:
+    *   - gScl = The scale of the gyroscope. This should be a gyro_scale value.
+    *   - aScl = The scale of the accelerometer. Should be a accel_scale value.
+    *   - gODR = Output data rate of the gyroscope. gyro_odr value.
+    *   - aODR = Output data rate of the accelerometer. accel_odr value.
+    *  Output: The function will return an unsigned 16-bit value. The most-sig
+    *       bytes of the output are the WHO_AM_I reading of the accel/gyro.
+    *  All parameters have a defaulted value, so you can call just "begin()".
+    *  Default values are FSR's of: +/- 245DPS, 4g, 2Gs; ODRs of 119 Hz for 
+    *  gyro, 119 Hz for accelerometer.
+    *  Use the return value of this function to verify communication.
+    */
+    uint16_t begin(gyro_scale gScl = G_SCALE_245DPS, 
+                accel_scale aScl = A_SCALE_2G, gyro_odr gODR = G_ODR_104, 
+                accel_odr aODR = A_ODR_104);
+    
+    /**  readGyro() -- Read the gyroscope output registers.
+    *  This function will read all six gyroscope output registers.
+    *  The readings are stored in the class' gx_raw, gy_raw, and gz_raw variables. Read
+    *  those _after_ calling readGyro().
+    */
+    void readGyro();
+    
+    /**  readAccel() -- Read the accelerometer output registers.
+    *  This function will read all six accelerometer output registers.
+    *  The readings are stored in the class' ax_raw, ay_raw, and az_raw variables. Read
+    *  those _after_ calling readAccel().
+    */
+    void readAccel();
+    
+    /**  readTemp() -- Read the temperature output register.
+    *  This function will read two temperature output registers.
+    *  The combined readings are stored in the class' temperature variables. Read
+    *  those _after_ calling readTemp().
+    */
+    void readTemp();
+    
+    /** Read Interrupt **/
+    void readIntr();
+    
+    /**  setGyroScale() -- Set the full-scale range of the gyroscope.
+    *  This function can be called to set the scale of the gyroscope to 
+    *  245, 500, or 2000 degrees per second.
+    *  Input:
+    *   - gScl = The desired gyroscope scale. Must be one of three possible
+    *       values from the gyro_scale enum.
+    */
+    void setGyroScale(gyro_scale gScl);
+    
+    /**  setAccelScale() -- Set the full-scale range of the accelerometer.
+    *  This function can be called to set the scale of the accelerometer to
+    *  2, 4, 8, or 16 g's.
+    *  Input:
+    *   - aScl = The desired accelerometer scale. Must be one of five possible
+    *       values from the accel_scale enum.
+    */
+    void setAccelScale(accel_scale aScl);
+    
+    /**  setGyroODR() -- Set the output data rate and bandwidth of the gyroscope
+    *  Input:
+    *   - gRate = The desired output rate and cutoff frequency of the gyro.
+    *       Must be a value from the gyro_odr enum (check above).
+    */
+    void setGyroODR(gyro_odr gRate);
+    
+    /**  setAccelODR() -- Set the output data rate of the accelerometer
+    *  Input:
+    *   - aRate = The desired output rate of the accel.
+    *       Must be a value from the accel_odr enum (check above).
+    */
+    void setAccelODR(accel_odr aRate);
+    //void setAccelODR_NoBW(accel_odr aRate);
+
+
+private:    
+    /**  xgAddress store the I2C address
+    *  for each sensor.
+    */
+    uint8_t xgAddress;
+    
+    // I2C bus
+    I2C i2c;
+
+    /**  gScale, and aScale store the current scale range for each 
+    *  sensor. Should be updated whenever that value changes.
+    */
+    gyro_scale gScale;
+    accel_scale aScale;
+    
+    /**  gRes, and aRes store the current resolution for each sensor. 
+    *  Units of these values would be DPS (or g's or Gs's) per ADC tick.
+    *  This value is calculated as (sensor scale) / (2^15).
+    */
+    float gRes, aRes;
+    
+    /**  initGyro() -- Sets up the gyroscope to begin reading.
+    *  This function steps through all three gyroscope control registers.
+    */
+    void initGyro();
+    
+    /**  initAccel() -- Sets up the accelerometer to begin reading.
+    *  This function steps through all accelerometer related control registers.
+    */
+    void initAccel();
+    
+    /** Setup Interrupt **/
+    void initIntr();
+    
+    /**  calcgRes() -- Calculate the resolution of the gyroscope.
+    *  This function will set the value of the gRes variable. gScale must
+    *  be set prior to calling this function.
+    */
+    void calcgRes();
+    
+    /**  calcaRes() -- Calculate the resolution of the accelerometer.
+    *  This function will set the value of the aRes variable. aScale must
+    *  be set prior to calling this function.
+    */
+    void calcaRes();
+};
+
+#endif // _LSM6DS3_H //