Problem converting Adafruit IMU Library to use i2c_t3

Status
Not open for further replies.

JBrownlow

Member
I am working on a project using a Teensy 3.6 that requires use of multiple I2C interfaces, hence I have converted the libraries I am using from Wire.h to i2c_t3.h

My problem is in converting the 'Adafruit_L3GD20_U' library provided by Adafruit for their IMU LSM303DLHC_L3GD20 (9 DOF) to use with i2c_t3. Found here: https://learn.adafruit.com/adafruit-9-dof-imu-breakout/software

I have includes to i2c_t3, but the library header file uses the TwoWire data type.

Adafruit_L3GD20_U.h partial code (found in full from the link above)
Code:
...
class Adafruit_L3GD20_Unified : public Adafruit_Sensor
{
  public:
    Adafruit_L3GD20_Unified(int32_t sensorID = -1);

    bool begin           ( gyroRange_t rng = GYRO_RANGE_250DPS, TwoWire *theWire=&Wire); //The problem is on this line
    void enableAutoRange ( bool enabled );
    bool getEvent        ( sensors_event_t* );
    void getSensor       ( sensor_t* );
...

The error message I receive is as follows:
In file included from F:\Documents\Work\Hardware projects\Sensors\IMU_LSM303DLHC_L3GD20\IMU_LSM303DLHC_L3GD20.ino:4:0:

F:\Documents\Arduino\libraries\Adafruit_L3GD20_U-master/Adafruit_L3GD20_U.h:110:65: error: 'TwoWire' has not been declared

bool begin ( gyroRange_t rng = GYRO_RANGE_250DPS, TwoWire *theWire=&Wire);

F:\Documents\Arduino\libraries\Adafruit_L3GD20_U-master/Adafruit_L3GD20_U.h:110:83: error: could not convert '& Wire' from 'i2c_t3*' to 'int*'

bool begin ( gyroRange_t rng = GYRO_RANGE_250DPS, TwoWire *theWire=&Wire);


From what I understand, the TwoWire type does not exist in i2c_t3 and needs changing to work with the i2c_t3 library, but I don't know how to go about doing this having spent time doing research.

Any help is appreciated, I have reasonable experience writing and editing libraries, but this lower level communication stuff is my weakness!

Also this is my first forum post, so I apologise in advance if anything is not clear. I can provide more information if necessary.




Full Adafruit Adafruit_L3GD20_U.h Code:

Code:
/***************************************************
  This is a library for the L3GD20 GYROSCOPE

  Designed specifically to work with the Adafruit L3GD20 Breakout
  ----> https://www.adafruit.com/products/1032

  These sensors use I2C or SPI to communicate, 2 pins (I2C)
  or 4 pins (SPI) are required to interface.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Kevin "KTOWN" Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ****************************************************/
#ifndef __L3GD20_H__
#define __L3GD20_H__

#if (ARDUINO >= 100)
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif

#include <Adafruit_Sensor.h>
#include <i2c_t3.h>

/*=========================================================================
    I2C ADDRESS/BITS AND SETTINGS
    -----------------------------------------------------------------------*/
    #define L3GD20_ADDRESS           (0x6B)        // 1101011
    #define L3GD20_POLL_TIMEOUT      (100)         // Maximum number of read attempts
    #define L3GD20_ID                (0xD4)
    #define L3GD20H_ID               (0xD7)
    // Sesitivity values from the mechanical characteristics in the datasheet.
    #define GYRO_SENSITIVITY_250DPS  (0.00875F)
    #define GYRO_SENSITIVITY_500DPS  (0.0175F)
    #define GYRO_SENSITIVITY_2000DPS (0.070F)
/*=========================================================================*/

/*=========================================================================
    REGISTERS
    -----------------------------------------------------------------------*/
    typedef enum
    {                                             // DEFAULT    TYPE
      GYRO_REGISTER_WHO_AM_I            = 0x0F,   // 11010100   r
      GYRO_REGISTER_CTRL_REG1           = 0x20,   // 00000111   rw
      GYRO_REGISTER_CTRL_REG2           = 0x21,   // 00000000   rw
      GYRO_REGISTER_CTRL_REG3           = 0x22,   // 00000000   rw
      GYRO_REGISTER_CTRL_REG4           = 0x23,   // 00000000   rw
      GYRO_REGISTER_CTRL_REG5           = 0x24,   // 00000000   rw
      GYRO_REGISTER_REFERENCE           = 0x25,   // 00000000   rw
      GYRO_REGISTER_OUT_TEMP            = 0x26,   //            r
      GYRO_REGISTER_STATUS_REG          = 0x27,   //            r
      GYRO_REGISTER_OUT_X_L             = 0x28,   //            r
      GYRO_REGISTER_OUT_X_H             = 0x29,   //            r
      GYRO_REGISTER_OUT_Y_L             = 0x2A,   //            r
      GYRO_REGISTER_OUT_Y_H             = 0x2B,   //            r
      GYRO_REGISTER_OUT_Z_L             = 0x2C,   //            r
      GYRO_REGISTER_OUT_Z_H             = 0x2D,   //            r
      GYRO_REGISTER_FIFO_CTRL_REG       = 0x2E,   // 00000000   rw
      GYRO_REGISTER_FIFO_SRC_REG        = 0x2F,   //            r
      GYRO_REGISTER_INT1_CFG            = 0x30,   // 00000000   rw
      GYRO_REGISTER_INT1_SRC            = 0x31,   //            r
      GYRO_REGISTER_TSH_XH              = 0x32,   // 00000000   rw
      GYRO_REGISTER_TSH_XL              = 0x33,   // 00000000   rw
      GYRO_REGISTER_TSH_YH              = 0x34,   // 00000000   rw
      GYRO_REGISTER_TSH_YL              = 0x35,   // 00000000   rw
      GYRO_REGISTER_TSH_ZH              = 0x36,   // 00000000   rw
      GYRO_REGISTER_TSH_ZL              = 0x37,   // 00000000   rw
      GYRO_REGISTER_INT1_DURATION       = 0x38    // 00000000   rw
    } gyroRegisters_t;
/*=========================================================================*/

/*=========================================================================
    OPTIONAL SPEED SETTINGS
    -----------------------------------------------------------------------*/
    typedef enum
    {
      GYRO_RANGE_250DPS  = 250,
      GYRO_RANGE_500DPS  = 500,
      GYRO_RANGE_2000DPS = 2000
    } gyroRange_t;
/*=========================================================================*/

/*=========================================================================
    RAW GYROSCOPE DATA TYPE
    -----------------------------------------------------------------------*/
    /** Encapsulates a single raw data sample from the sensor. */
    typedef struct gyroRawData_s
    {
        /** The X axis data. */
        int16_t x;
        /** The Y axis data. */
        int16_t y;
        /** The Z axis data. */
        int16_t z;
    } gyroRawData_t;
/*=========================================================================*/

/**
 * Driver for the Adafruit L3GD20 3-Axis gyroscope.
 */
class Adafruit_L3GD20_Unified : public Adafruit_Sensor
{
  public:
    Adafruit_L3GD20_Unified(int32_t sensorID = -1);

    bool begin           ( gyroRange_t rng = GYRO_RANGE_250DPS, TwoWire *theWire=&Wire);
    void enableAutoRange ( bool enabled );
    bool getEvent        ( sensors_event_t* );
    void getSensor       ( sensor_t* );

    /** Raw sensor data from the last successful read event. */
    gyroRawData_t raw;

  private:
    void        write8  ( byte reg, byte value );
    byte        read8   ( byte reg );
    gyroRange_t _range;
    int32_t     _sensorID;
    bool        _autoRangeEnabled;
};

/* Non Unified (old) driver for compatibility reasons */
typedef gyroRange_t     l3gd20Range_t;
typedef gyroRegisters_t l3gd20Registers_t;

/**
 * Encapsulates a single XYZ data sample from the sensor.
 */
typedef struct l3gd20Data_s
{
  /** Data from the X axis. */
  float x;
  /** Data from the Y axis. */
  float y;
  /** Data from the Z axis. */
  float z;
} l3gd20Data;

/// @private
class Adafruit_L3GD20
{
  public:
    Adafruit_L3GD20(int8_t cs, int8_t mosi, int8_t miso, int8_t clk);
    Adafruit_L3GD20(void);

    bool begin ( l3gd20Range_t rng=GYRO_RANGE_250DPS, byte addr=L3GD20_ADDRESS );
    void read  ( void );

    l3gd20Data data;    // Last read will be available here

  private:
    void write8     ( l3gd20Registers_t reg, byte value );
    byte read8      ( l3gd20Registers_t reg );
    uint8_t SPIxfer ( uint8_t x );

    byte          address;
    l3gd20Range_t range;
    int8_t        _miso, _mosi, _clk, _cs;
};
#endif
 
Last edited:
Sorry I am not at my computer.

Looks like this library is setup to use different wire objects which is great. But since i2c_t3 does not use the same base class, you will need to edit all of the uses of the class twowire to the base class of i2c_t3...
 
Thanks for your quick response. Are you saying is that changing any file in the location 'Arduino>hardware>teensy>avr>libraries' that uses include <Wire.h> to <i2c_t3.h> should solve my problem?

I have changed Wire.h, Wire.cpp, WireKinetis.h and WireKinetis.cpp so far, but this does not resolve the issue. Where will I find the other files I must update?
 
What I am trying to say is that Wire.h and i2c_t3.h are not 100% compatible with each other.

There are a couple of issues, between using the two of them, which include:

They both use and create some of the same resources, so they can not both live in the same sketch. So if you include any other libraries that include wire.h, these must be changed to include i2c_t3.h instead.

But more specific to this issue. They both create some of the same objects, like Wire, they do not create them with the same C++ class name. That is the Wire library creates the Wire object using the class name twowire where as the i2c_t3 uses the class name i2c-t3. So when libraries like the one you are trying to use wish to allow developers to choose which Wire object to use (example on Teensy 3.6, I could instead reference the Wire2 object), their begin function allows me to pass in a pointer to which one I wish to use, and as such they have a pointer to the twowire class, which allows us with Teensy as well as some other platforms like I believe Arduino DUI to pass in another object. But since i2c_t3, uses different class name, you need to edit this header file and corresponding .cpp file to use the i2c_t3 class name instead. I would assume that this begin method stores this passed in value into a member variable with the twowire class type, which also would need to be updated.

There may be some other minor incompatibilities as well. I have not looked at their library to see if it uses any Teensy Wire library specific methods, like setSCL... If so would need to remove...
 
Great, that fixed my problem. The class name to replace TwoWire with is infact i2c_t3 (underscore rather than hyphen). Thank you very much for your help and explanation!
 
Status
Not open for further replies.
Back
Top