Using more then 1 INA226

First post but I have enjoyed reading and learning a lot.

My project requires the use of 3 INA226. I know how to set the address on each INA226 and an i2c scan finds all 3. My sketch works as desired when dealing with the first INA226 which I left at the default address of 0x40. I also see that the default address is set in the INA226.h file.

My question is, how can I switch to the second and third INA226 in the sketch?

PS: Anyone know where I can find pre-mounted INA226 breakouts like the ones available with the INA219? Those suckers are hard to mount/solder.

Edit: I'm using a MAC and had to blackout OS X10.11 to OS X10.10 due to issues with IDE. I'm also using Version 1.0 of the IDE for similar reasons.

You guys are great, thanks in advance.

David

post your sketch and include the 3 x i2c addresses and im sure we can work it out

RV solar system monitor. 1st INA226 = Solar Panel V & A input to Charge Controller (CC), the 2nd INA 226 = CC V & A out to batteries, 3rd INA 226 = V & A input to inverter from batteries and the 2 ACS712 will measure AC current from 2 120VAC phases of the inverter output.

Sketch - My first and a work in progress.

I don't know how to put in the second and third INA226.

//INA226 Bi-directional Current/Power Monitor.

#include <SD.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <INA226.h>
#include "RTClib.h"

RTC_DS1307 RTC;

INA226 ina;

#define LOG_INTERVAL 10000 // mills between entries (reduce to take more/faster data)
#define SYNC_INTERVAL 10000 // mills between calls to flush() - to write data to the card.
#define aref_voltage 5.0 // Can tie 3.3V to ARef and measure it with a multimeter!

uint32_t syncTime = 0; // time of last sync()

LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 20 chars and 4 line display

const int chipSelect = 10;

File logfile; // the logging file

void error(char *str)
{
Serial.print("error: ");
Serial.println(str);
while(1);
}

void setup()
{
lcd.init(); // initialize the lcd
lcd.backlight();
lcd.clear();

Wire.begin();
RTC.begin();

if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
// uncomment it & upload to set the time, date and start run the RTC!
//RTC.adjust(DateTime(DATE, TIME));
}

// Default INA226 address is 0x40

ina.begin();

// Configure INA226
ina.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);

// Calibrate INA226. Rshunt = 0.015 ohm, Max excepted current = 8A
ina.calibrate(0.015, 8.0);

// make sure that the default chip select pin is set to output, even if you don't use it:
pinMode(10, OUTPUT);

// see if the card is present and can be initialized:
if (!SD.begin(chipSelect))
{
error("Card failed, or not present");
}

// create a new file
char filename[] = "LOGGER00.CSV";
for (uint8_t i = 0; i < 100; i++)
{
filename[6] = i/10 + '0';
filename[7] = i%10 + '0';
if (! SD.exists(filename))
{
// only open a new file if it doesn't exist
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}
}

void loop()
{
// DateTime now;

// delay for the amount of time we want between readings
delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));

DateTime now = RTC.now();

//Print Date to Log file.
logfile.print(now.year(), DEC);
logfile.print('/');
logfile.print(now.month(), DEC);
logfile.print('/');
logfile.print(now.day(), DEC);
logfile.print(' ');
logfile.print(now.hour(), DEC);
logfile.print(':');
logfile.print(now.minute(), DEC);
logfile.print(':');
logfile.print(now.second(), DEC);
logfile.print(", ");

//Print Voltage & Current Data to Log file.
logfile.print(ina.readShuntVoltage(), 2);
logfile.print(", ");
logfile.print(ina.readShuntCurrent(), 2);
logfile.print(", ");

logfile.print(ina.readShuntVoltage(), 2);
logfile.print(", ");
logfile.print(ina.readShuntCurrent(), 2);
logfile.print(", ");

logfile.print(ina.readShuntVoltage(), 2);
logfile.print(", ");
logfile.print(ina.readShuntCurrent(), 2);
logfile.print(", ");

logfile.print(ina.readShuntVoltage(), 2);
logfile.print(", ");
logfile.print(ina.readShuntCurrent(), 2);
logfile.println();

//Print Voltage & Current Data to LCD.
// lcd.clear();
lcd.setCursor(0, 0);
lcd.print("PANEL ");
lcd.print(ina.readShuntVoltage(), 2);
lcd.print("V ");
lcd.print(ina.readShuntCurrent(), 2);
lcd.print("A");

lcd.setCursor(0, 1);
lcd.print("CC-OUT ");
lcd.print(ina.readShuntVoltage(), 2);
lcd.print("V ");
lcd.print(ina.readShuntCurrent(), 2);
lcd.print("A");

lcd.setCursor(0, 2);
lcd.print("INV-IN ");
lcd.print(ina.readShuntVoltage(), 2);
lcd.print("V ");
lcd.print(ina.readShuntCurrent(), 2);
lcd.print("A");

lcd.setCursor(0, 3);
lcd.print("P1 ");
lcd.print(ina.readShuntVoltage(), 2);
lcd.print("A ");
lcd.print("P2 ");
lcd.print(ina.readShuntCurrent(), 2);
lcd.print("A");

delay(1000);

// Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
// which uses a bunch of power and takes time
if ((millis() - syncTime) < SYNC_INTERVAL) return;
syncTime = millis();

// blink LED to show we are syncing data to the card & updating FAT!
logfile.flush();
}

Output of log file:
2016/1/1 18:2:49 0 0 0 0 0 0 0 0
2016/1/1 18:2:59 0 0 0 0 0 0 0 0
2016/1/1 18:3:9 0 0 0 0 0 0 0 0
2016/1/1 18:3:19 0 0 0 0 0 0 0 0
2016/1/1 18:3:29 0 0 0 0 0 0 0 0
2016/1/1 18:3:39 0 0 0 0 0 0 0 0
2016/1/1 18:3:49 0 0 0 0 0 0 0 0
2016/1/1 18:3:59 0 0 0 0 0 0 0 0
2016/1/1 18:4:9 0 0 0 0 0 0 0 0
2016/1/1 18:4:19 0 0 0 0 0 0 0 0
2016/1/1 18:4:29 0 0 0 0 0 0 0 0
2016/1/1 18:4:39 0 0 0 0 0 0 0 0

The first two columns after date are the first line on the display below, second two the second line, third two the third line and forth two the forth line which will come from two ASC712 via Arduino analog 0 and 1.

Display:

FullSizeRender.jpg

ina.calibrate(0.015, 8);

What does the smiley face do?

There are stickies at the top of the forum that you were supposed to read BEFORE posting, so you don't look stupid posting code like this.

INA226 ina;

not 100% sure but INA226 calls the library and ina is the name you assigned

as you gave it the name ina you told it to begin

ina.begin();

I don't see where you assigned the address to ina maybe the sample code shows where its assigned

I would have presumed that is was assigned with the name

INA226 ina(0x40);

but I don't have the library to check

once you have worked out where the address is added just create 3 name (or use ina and 2 extra names) then make 3 begins using the 3 names.

It would seem that if you call the same library to initialize each of your INA226's, that they necessarily are assigned that single default address you say is set in the library. So maybe you have to make three libraries, differing only by the default address, then give them different names, and include each separately, and then initialize you units separately, one with each library. Whew!

I was wrong after looking it seems the address goes in the

ina.begin(0x40); default if nothing is entered will be // Default INA226 address is 0x40

well that's if im looking at the same library

PaulS:
What does the smiley face do?

There are stickies at the top of the forum that you were supposed to read BEFORE posting, so you don't look stupid posting code like this.

Ha! the second parameter passed to INA226.calibrate is the max expected current. I had 8, but it is float so should have been 8.0.

I did read all the stickies but did not apply them well.

I don't feel stupid at all. My first sketch and it works well, what there is of it. Can you help with my specific problem?

Thanks

gpop1:

INA226 ina;

not 100% sure but INA226 calls the library and ina is the name you assigned

as you gave it the name ina you told it to begin

ina.begin();

I don't see where you assigned the address to ina maybe the sample code shows where its assigned

I would have presumed that is was assigned with the name

INA226 ina(0x40);

but I don't have the library to check

once you have worked out where the address is added just create 3 name (or use ina and 2 extra names) then make 3 begins using the 3 names.

The default address of 0x40 is assigned in INA226.h. #define INA226_ADDRESS (0x40). I have tried unsuccessful to remove it from there and add it to my sketch. Maybe I should try again.

jrdoner:
It would seem that if you call the same library to initialize each of your INA226's, that they necessarily are assigned that single default address you say is set in the library. So maybe you have to make three libraries, differing only by the default address, then give them different names, and include each separately, and then initialize you units separately, one with each library. Whew!

I like your idea. I have considered writing my own version of the library. Doing three copies would be a fast way to prove the concept.

Thanks

gpop1:
I was wrong after looking it seems the address goes in the

ina.begin(0x40); default if nothing is entered will be // Default INA226 address is 0x40

well that's if im looking at the same library

I have not tried passing the address in the INA226.begin(). I will try and see if it will override the #define INA226_ADDRESS (0x40) in the INA226.h.

Thanks

gpop1:
I was wrong after looking it seems the address goes in the

ina.begin(0x40); default if nothing is entered will be // Default INA226 address is 0x40

well that's if im looking at the same library

SOLVED

You got it Sir, moving the INA226 initialization inside void loop(), modifying and passing the INA226 address in ina.begin(0x44), and repeating it for each INA226 address works.,

//Initialize the 1st INA226

ina.begin(0x44);

// Configure INA226
ina.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);

// Calibrate INA226. Rshunt = 0.015 ohm, Max excepted current = 8A
ina.calibrate(0.015, 8.0);

........do the stuff for this INA226 and repeat for 2nd and 3rd.

Thanks to all. I love you guys!

should be able to do

INA226 ina_1;
INA226 ina_2;
INA226 ina_3;

ina_1.begin(0x44);
ina_2.begin(0x40);
ina_3.begin(0x27);

ina_1.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);

ina_2.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);

ina_3.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);

then all refrences in code use ina_1 , ina_2 or ina_3

logfile.print(ina_2.readShuntCurrent(), 2);

think theres also a ina.calibrate(0.015, 8.0); that will need repeating 3 times

You could also use an array of objects perhaps:

INA226 inas [3] ;