Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 13 of 13

Thread: How to pass another Wire object to a library?

  1. #1
    Junior Member
    Join Date
    Aug 2022
    Posts
    6

    How to pass another Wire object to a library?

    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.sharep...c9LhQ?e=OPWJee

  2. #2
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,386
    As a simple solution you could use
    Code:
    #define Wire Wire1
    at the head of the .cpp files.

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    28,473
    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.

  4. #4
    Junior Member
    Join Date
    Aug 2022
    Posts
    6
    Here are the forks:
    https://github.com/01-BlackHawk-11/lis3mdl-Teensy-I2C
    https://github.com/01-BlackHawk-11/l...ino-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.
    Click image for larger version. 

Name:	Error.jpg 
Views:	29 
Size:	103.8 KB 
ID:	29124

  5. #5
    Junior Member
    Join Date
    Aug 2022
    Posts
    6
    Any Help or suggestion?

  6. #6
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,795
    I pushed up a quick and dirty version: https://github.com/KurtE/lsm6-arduin...2C/tree/Wire12

    That is for example with the example sketch:
    LSM6 imu; // Will use the wire object
    LSM6 imu(Wire1); // will use Wire1

  7. #7
    Junior Member
    Join Date
    Aug 2022
    Posts
    6
    Quote Originally Posted by KurtE View Post
    I pushed up a quick and dirty version: https://github.com/KurtE/lsm6-arduin...2C/tree/Wire12

    That is for example with the example sketch:
    LSM6 imu; // Will use the wire object
    LSM6 imu(Wire1); // will use Wire1
    Click image for larger version. 

Name:	Error2.jpg 
Views:	16 
Size:	69.7 KB 
ID:	29131
    Did not work. I have ensured that Wire1 is connected.

  8. #8
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,386
    Can you post your code, and be more explicit about in which way it "Did not work."

  9. #9
    Junior Member
    Join Date
    Aug 2022
    Posts
    6
    This time I abandoned whatever KurtE suggested (I think I've overloaded the constructor aswell). And this time I worked by the solution provided Richard Gemmell himself: https://github.com/Richard-Gemmell/t..._i2c/issues/31
    However as you can guys read in the issue I had an error as well.

  10. #10
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    28,473
    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.

  11. #11
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,795
    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...

  12. #12
    Junior Member
    Join Date
    Aug 2022
    Posts
    6
    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/l...ino-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

  13. #13
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,795
    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(...)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •