Class object scope if I2C address is unknown until setup()

Dear All,

  1. How does one instantiate a class object for an I2C sensor if the I2C address of that sensor needs to be determined during setup()?
    Alternatively,
  2. Can a class object be instantiated in a subroutine and then accessed from elsewhere?

Background:
I want to record current over (long) time. The current varies to some degree around a low or high mean, but once connected, it never changes from the low to high categories or vice versa (eg 1A±100mA or 20A±1000mA).
I'm using two INA219 sensors with different I2C addresses and different shunt resistors. Depending on the current category (low|high) I want to record, I will connect my source to only one of the INA sensors. The electrical setup is similar to what we have on our multimeters where we use different input sockets for the 0..2 and 2..10A ranges.

In setup(), I read the bus voltage from both sensors to determine whose shunt resistor is connected. Once this is known, I want to limit future readings to this sensor only.

This means that I don't know the I2C address for my connected sensor at the time the INA class object is usually instantiated (before setup()), because the address remains unknown until setup() runs.

I can instantiate the INA219 object in setup() after determining the I2C address, but how do I access it in loop()?.

Sorry for asking two different questions, I hope that answers to either will solve the problem :wink:

Simplified code below:

#include <Adafruit_INA219.h>
byte A_addr = 0x40; // address of sensor A (known)
byte B_addr = 0x41; // address of sensor B (known)
byte C_addr = 0; // address of the connected INA sensor (unknown at this stage)

void setup() {
// read bus voltage from first sensor
  Adafruit_INA219 ina_A(A_addr);
  ina_A.begin();
  float A_voltage = ina_A.getBusVoltage_V();

// read bus voltage from second sensor
  Adafruit_INA219 ina_B(B_addr);
  ina_B.begin();
  float B_voltage = ina_B.getBusVoltage_V();

// assign address of connected sensor to C_addr (range and error checking removed)
  if (A_Voltage > B_Voltage) {
  C_addr = A_addr;
  }
  else {
  C_addr = B_addr;
  }

// now we have C_addr, but how to instantiate ina_C(C_addr) to make it accessible in loop()?
}

Rather than creating a third instance, use the version of .begin() that lets you set the address. Something like this should work:

#include <Adafruit_INA219.h>
const byte A_addr = 0x40; // address of sensor A (known)
const byte B_addr = 0x41; // address of sensor B (known)

Adafruit_INA219 ina;

byte C_addr = 0; // address of the connected INA sensor (unknown at this stage)

void setup() {
  // read bus voltage from first sensor
  ina.begin(A_addr);
  float A_voltage = ina.getBusVoltage_V();

  // read bus voltage from second sensor
  ina.begin(B_addr);
  float B_voltage = ina.getBusVoltage_V();

  // assign address of connected sensor to S_addr (range and error checking removed)
  if (A_Voltage > B_Voltage) {
    C_addr = A_addr;
  }
  else {
    C_addr = B_addr;
  }

  // Switch to the desired device
  ina.begin(C_addr);

  // now we have C_addr, but how to instantiate ina_C(C_addr) to make it accessible in loop()?
}

Many thanks John, this is a great idea and I can confirm it's working fine!