How to pass another Wire object to a library?

DelVione

Member
I want to modify those libraries in order to pass other I2C buses (Wire1 or Wire2) instead of the default Wire. The libraries are LIS3MDL and LSM6. I use the Teensy 4.1 I2C library as well by Richard Gemmell. I would like to use the device connected to the corresponding bus in order to get readings from it. And how can I incorporate multi-instancing for getting readings from multiple devices?

Here are the library files: https://cardmaillouisville-my.share...lAqwhK8lhiUp0BTxP5XPYdAYci5F0FFc9LhQ?e=OPWJee
 
As a simple solution you could use
Code:
#define Wire Wire1
at the head of the .cpp files.
 
Are these the sensor libraries you're really using?

https://github.com/pololu/lsm6-arduino

https://github.com/pololu/lis3mdl-arduino

If anyone is going to go to the trouble of editing these to properly allow the I2C / Wire port to be specified in their init() functions, best to do so as a github fork so it can be contributed back to the original library as a pull request. Editing copies of file from Microsoft Sharepoint is a dead-end path, in terms of making the improvement benefit anyone else in the world.
 
Here are the forks:
https://github.com/01-BlackHawk-11/lis3mdl-Teensy-I2C
https://github.com/01-BlackHawk-11/lsm6-arduino-Teensy-I2C


What I had in mind was adding a variable that stores the wire address like this:
Code:
I2CDriverWire MyWire;

Replace every instance of Wire with MyWire. And make a function that I can call in my ino files like so:
Code:
void LIS3MDL::set_wire(I2CDriverWire& wire)
{
	MyWire  = wire;
}
As well as including the function definitions in the header files to avoid errors. But I still get errors while compiling.
Error.jpg
 
Can't see much of the code in your screenshot...

Did you also change Wire.begin() to Wire1.begin() in your program? Looks like this library doesn't call the Wire library begin function, so you need to do it for the correct port before calling the library functions.
 
Sorry, have no idea what did not work means...
Also the one warning, I left in as it was there before and the owner should look at it and decide if just adding a default: break;
is OK or was he supposed to something in that case.

Obviously would be good to see code and setup to understand

As for the other version of code: very unclear at times what your other code is doing different, that is: I2CDriverWire
Looks like whole different class and the set function set_wire function was assigning a wire object to another object...

Like, what would you expect: Wire1 = Wire2;
To do?

Which is why I instead keep a pointer to the current Wire object...
 
So I have tried a new method of achieving this according to Richard. I have updated the init functions to accept a Wire object parameter.
https://github.com/01-BlackHawk-11/lis3mdl-Teensy-I2C
https://github.com/01-BlackHawk-11/lsm6-arduino-Teensy-I2C

This time I get this error:
Arduino: 1.8.19 (Windows 10), TD: 1.56, Board: "Teensy 4.1, Raw HID, 600 MHz, Faster, US English"

In file included from C:\Program Files (x86)\Arduino\MiniIMU9AHRS\MinIMU9AHRS\I2C.ino:33:0:

C:\Program Files (x86)\Arduino\libraries\LIS3MDL/LIS3MDL.h:51:73: error: 'sa0State' has not been declared

bool init(I2CDriverWire& wire = Wire, deviceType device = device_auto, sa0State sa0 = sa0_auto);

^

C:\Program Files (x86)\Arduino\libraries\LIS3MDL/LIS3MDL.h:51:88: error: 'sa0_auto' was not declared in this scope

bool init(I2CDriverWire& wire = Wire, deviceType device = device_auto, sa0State sa0 = sa0_auto);

^

I2C: In function 'void Compass_Init()':

I2C:138: error: call to 'bool LIS3MDL::init(I2CDriverWire&, LIS3MDL::deviceType, int)' uses the default argument for parameter 3, which is not yet defined

mag.init(Wire1);

^

call to 'bool LIS3MDL::init(I2CDriverWire&, LIS3MDL::deviceType, int)' uses the default argument for parameter 3, which is not yet defined
 
Sorry I asked this before with the solution I posted on what was not working?
But again, I did the changes directly using the Pololu version of the library. I have no idea what if anything you have that is different?


Quick look at your stuff:
bool init(I2CDriverWire& wire = Wire, deviceType device = device_auto, sa0State sa0 = sa0_auto);

So what is: I2CDriverWire ?

Is it some class that is defined in some Header file? That is the only usage of it in this header file. So it has no idea what it is?
Your .cpp file has:
Code:
#include <i2c_driver_wire.h>
...
bool LSM6::init(I2CDriverWire& wire, deviceType device, sa0State sa0)
{
	Wire = wire;
...

So you include a different Wire library? Why?
If you really need to? You need to include it in your library header file.

Also: Wire = wire;
Will probably never work.

You are trying to assign the Main Wire object to something else? Not sure if that is defined. And if it did work would likely screw up anywhere
else that might try to use the real Wire object.

That is why in the version I did has a member variable: TwoWire *_pwire; // which wire object are we using.
Which I assign in the constructor. If instead you wish to do on the Init same difference:
However, for compatibility with current code, I would have added it at the end of the parameter list, as if there is any existing sketch that does something like:
myls6.init(device_DS33);

you're adding it as the first parameter would break this sketch.

But in either case, if I changed what I did to do on the init.
Then the init like:
bool init(deviceType device = device_auto, sa0State sa0 = sa0_auto, TwoWire &wire=Wire);

Code:
bool LSM6::init(deviceType device, sa0State sa0, TwoWire &wire)
{
  // perform auto-detection unless device type and SA0 state were both specified
  _pwire = &wire;
...
Note then everywhere in the code that was doing: Wire.xxx(...)
Would be changed to: _pwire->xxx(...)
 
Back
Top