Adding slave address select to H3LIS331DL library

Hello,

As part of a work project I am attempting to add the ability to specify the I2C slave address to the H3LIS331DL library that Seed Studio has posted to Github. GitHub - Seeed-Studio/Accelerometer_H3LIS331DL: a library to use Grove & Xadow - 3-Axis Digital Accelerometer(±400g) ST makes demo boards that have the SDA[0] bit broken out to a pin, allowing 2 accelerometers to coexist on the same I2C bus. The demo code works fine for addressing the accelerometer at address 0x18 but the address is hard coded in the header file. My hope was to quickly mod the library so the address is a line argument for all the functions.

I'm a complete neophyte when it comes to C programming. I attempted to add an argument for the address to the basic setup and read data functions but the Arduino environment hangs when I attempt to compile. That seems to point to an issue in the C code since the Arduino environment isn't throwing an error.

Any guidance or suggestions would be extremely appreciated. FYI I removed the original library from the libraries folder in the Arduino folder so I could leave the include statements as is without accidently referencing the unmodified library.

Unfortunately the code is well beyond the 9k charcter limit so I will be attaching the C source and header files. Arduino code included below:

/* get accelerate data of H3LIS331DL
 * Auth : lawliet(lawliet.zou@gmail.com)
 * version : 0.1
 */

#include <H3LIS331DL.h>
#include <Wire.h>

//please get these value by running H3LIS331DL_AdjVal Sketch.
#define VAL_X_AXIS  203
#define VAL_Y_AXIS  165
#define VAL_Z_AXIS  371

byte addr0 = 0x18;
byte addr1 = 0x19;

H3LIS331DL h3lis;

void setup(){
  Serial.begin(9600);
  h3lis.init(addr0, H3LIS331DL_ODR_1000Hz, H3LIS331DL_NORMAL, H3LIS331DL_FULLSCALE_8);;
  h3lis.importPara(addr0, VAL_X_AXIS, VAL_Y_AXIS, VAL_Z_AXIS);
}

void loop(){
  int16_t x,y,z;
  h3lis.readXYZ(addr0, &x,&y,&z);
  Serial.print("x, y, z = ");
  Serial.print(x);
  Serial.print("\t");
  Serial.print(y);
  Serial.print("\t");
  Serial.println(z);

  double xyz[3];
  h3lis.getAcceleration(addr0, xyz);
  Serial.print("accelerate of x, y, z = ");
  Serial.print(xyz[0]);
  Serial.print("g");
  Serial.print("\t");
  Serial.print(xyz[1]);
  Serial.print("g");
  Serial.print("\t");
  Serial.print(xyz[2]);
  Serial.println("g");  
  
  delay(1000);
}

H3LIS331DL.cpp (41.7 KB)

H3LIS331DL.h (13.8 KB)

Ok an update. Changed the hard coded address into a private variable and added some code to the init function so the address variable is set during the init call. Got the whole mess to compile but now I am getting garbage output during getAccel and getXYZ function calls.

First the edits to the header function:
The header file previously defined H3LIS331DL_MEMS_I2C_ADDRESS as (which I then commented out)

#define H3LIS331DL_MEMS_I2C_ADDRESS     0x18

I made the following edits to the init function so that the user has to declare the slave address, output data rate, the power mode and the full scale.

class H3LIS331DL
{
public:
    H3LIS331DL(){
		_adjVal[0] = _adjVal[1] = _adjVal[2] = 0; 
    };
    void init(byte _H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_ODR_t  odr = H3LIS331DL_ODR_100Hz, 
            H3LIS331DL_Mode_t mode = H3LIS331DL_NORMAL,H3LIS331DL_Fullscale_t fullScale = H3LIS331DL_FULLSCALE_2);

and defined H3LIS331DL_MEMS_I2C_ADDRESS in the private variable section of the class.

private:
    uint8_t readReg(byte deviceAddr, byte Reg, byte* Data);
    uint8_t writeReg(byte deviceAddress, byte WriteAddr, byte Data);
    int16_t _adjVal[3];
	byte H3LIS331DL_MEMS_I2C_ADDRESS;

Onto the source code:
Made the edit to the init function to handle assigning the slave address:

void H3LIS331DL::init(byte _H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_ODR_t  odr,H3LIS331DL_Mode_t mode,H3LIS331DL_Fullscale_t fullScale){

    Wire.begin();
	_H3LIS331DL_MEMS_I2C_ADDRESS = H3LIS331DL_MEMS_I2C_ADDRESS;
    //set output data rate
    setODR(odr);
    //set PowerMode 
    setMode( mode);
    //set Fullscale
    setFullScale( fullScale);
    //set axis Enable
    setAxis( H3LIS331DL_X_ENABLE | H3LIS331DL_Y_ENABLE |  H3LIS331DL_Z_ENABLE);
}

And finally the Arduino code

#include <H3LIS331DL.h>
#include <Wire.h>

//please get these value by running H3LIS331DL_AdjVal Sketch.
#define VAL_X_AXIS  203
#define VAL_Y_AXIS  165
#define VAL_Z_AXIS  371
byte addr = 0x18;

H3LIS331DL h3lis;

void setup(){
  Serial.begin(9600);
  h3lis.init(addr, H3LIS331DL_ODR_100Hz, H3LIS331DL_NORMAL, H3LIS331DL_FULLSCALE_2);
  h3lis.importPara(VAL_X_AXIS,VAL_Y_AXIS,VAL_Z_AXIS);
  Serial.println("setup");
}

void loop(){
  int16_t x,y,z;
  h3lis.readXYZ(&x,&y,&z);
  Serial.print("x, y, z = ");
  Serial.print(x);
  Serial.print("\t");
  Serial.print(y);
  Serial.print("\t");
  Serial.println(z);

  double xyz[3];
  h3lis.getAcceleration(xyz);
  Serial.print("accelerate of x, y, z = ");
  Serial.print(xyz[0]);
  Serial.print("g");
  Serial.print("\t");
  Serial.print(xyz[1]);
  Serial.print("g");
  Serial.print("\t");
  Serial.print(xyz[2]);
  Serial.println("g");  
  
  delay(1000);

The code compiles and uploads but I get nothing out on the serial console. Any suggestions would be greatly appreciated.