Is it OK to create multiple I2C objects which represent the same I2C bus and pins

So say I have multiple I2C devices on the same bus.
In I2CDeviceA.cpp I create a I2C device
-----------------------I2CDeviceA.cpp---------------------
I2C i2cA(I2C_SDA, I2C_SCL );


In I2CDeviceB.cpp I create an I2CDevice on the same bus with same pins

-----------------------I2CDeviceB.cpp---------------------
I2C i2cB(I2C_SDA, I2C_SCL );

Is this OK? or do I need to create one global device with those parameters and then access it by reference when I have different devices on the same BUS?

Also I see the i2c.lock() / unlock() functions. I assume it is necessary to use that if using threads?

Thankyou

Hello Andy,

If you’d like to have two (or more) I2C devices, belonging to the same microcontroller, on the same bus then for the associated objects you should select two (or more) different I2C interfaces available on the same chip. If the same I2C interface was selected for both objects the same piece of hardware would be initialized and used for both of them (despite being created in different source files and having different names).

For example, if you use NUCLEO-F746ZG as your target board then you can select the I2C1 interface for the first device:

-----------------------I2CDeviceA.cpp---------------------

#define I2C1_SDA  PB_9
#define I2C1_SCL  PB_8

I2C i2cA(I2C1_SDA, I2C1_SCL);
...

and the I2C4 interface for the second device:

-----------------------I2CDeviceB.cpp---------------------

#define I2C4_SDA  PF_15
#define I2C4_SCL  PF_14

I2C i2cB(I2C4_SDA, I2C4_SCL);
...

I don’t think lock() and unlock() are necessary because they have already been ‘built-into’ the I2C class read() and write() methods.

In case you’d like to use the same I2C interface in both source files anyway then there are several options. For example:

  1. Create one global object and in the source files use aliases.

-----------------------main.cpp------------------------------

...
I2C i2c(I2C_SDA, I2C_SCL );
I2C &i2cA = i2c;
I2C &i2cB = i2c;
...

-----------------------I2CDeviceA.cpp---------------------

extern I2C i2cA;

i2cA.read():
...

-----------------------I2CDeviceB.cpp---------------------

extern I2C i2cB;

i2cB.read();
...
  1. Create one global object and in the source files use pointers.

-----------------------main.cpp------------------------------

...
I2C i2c(I2C_SDA, I2C_SCL );
I2C *i2cA = &i2c;
I2C *i2cB = &i2c;
...

-----------------------I2CDeviceA.cpp---------------------

extern I2C* i2cA;

i2cA->read();
...

-----------------------I2CDeviceB.cpp---------------------

extern I2C *i2cB;

i2cB->read();
...
1 Like