INA226 I2C Current Sensor Module

Place code snippets and demo code here
Post Reply
lyizb
Posts: 113
Joined: Fri Feb 12, 2021 8:23 pm
Has thanked: 49 times
Been thanked: 31 times

INA226 I2C Current Sensor Module

Post by lyizb »

The INA226 can read voltages up to 36V and currents as determined by the shunt resistor connected to it.

I want to monitor at least 4 small solar panels to compare the effects of a poor azimuth and tilt angle (what is possible where I may in the future mount full-sized panels) with a more ideally-aligned panel. These will be mounted on the front of my barn. I will also be looking at shading, since it is possible that in the winter in Nova Scotia, the lower panels will be partially or completely shaded by the house.

The INA226 looks perfect for this, but the Arduino and other code examples I found seemed overly complex (to the point where I couldn't understand exactly what they were doing--even after looking at the library code). I also found the data sheet confusing--I had to actually get a circuit to work before I understood what the data sheet was saying about how to set the Calibration register. The wiring diagrams on the internet were helpful.

Datasheet: https://www.ti.com/lit/ds/symlink/ina22 ... 9076066708

I'm using two different modules:
INA226 module 1.jpg
INA226 module2t.jpg
(I just ordered another 5 of the first type from Aliexpress for $2.02US each including shipping.)

Here's a sample Arduino wire-up:
Arduino INA226.jpg
In this test, the motor is replaced by an LED, and the "Source" is either 5V or 3V3 from an ESP32-S2Mini.

My wiring is just a lash-up for developing the code.

The INA226 has 8 registers: Configuration, Shunt voltage drop, Source Voltage, Power, Current, Calibration, Alert, and Mask. The Configuration register has default values which I did not change. It is necessary to set the Calibration register for the Power and Current registers to be filled in. The calculation is used in the program: 0.00512 divided by ( 0.001 * 0.01 ) (the latter two numbers are the number of volts per incremental value of the voltage reading, and the .01 is the ohmic value of the shunt resistor (labelled 010 on the first module type I have, and 100 on the second--it's also possible to remove the on-board shunt resistor and wire up a much larger external one--so that, for instance, a 100Ah 12V battery could be monitored--that's a future project).

I ran the program first with the source voltage from the 3V3 pin on the ESP32-S2Mini I was using, and then again with the voltage from the 5V pin. Here are the readings I got:

Code: [Local Link Removed for Guests]

Calib: 512
           Config    ShuntV    BaseV     Power     Current   Calib     Mask      Alert     
I2C  &h40  4127      106       3.31V      8mW      66mA      200       8         0         
Calib: 512
           Config    ShuntV    BaseV     Power     Current   Calib     Mask      Alert     
I2C  &h40  4127      25E       5.11V      31mW      152mA      200       8         0         
Here's the code:

Code: [Local Link Removed for Guests]

' ina226_test.bas
' https://www.ti.com/lit/ds/symlink/ina226.pdf?ts=1719076066708 TI data sheet
' https://github.com/macgeorge/STM32-example-codes/blob/master/6%20-%20INA226/F7_INA226.c
' 
rConfig=0:rShuntV=1:rBaseV=2:rPower=3:rCurrent=4:rCalib=5:rMask=6:rAlert=7:rManuf=&hFE:rDieID=&hFF
iConfig=0:iShuntV=0:iBaseV=0:iPower=0:iCurrent=0:iCalib=0:iMask=0:iAlert=0:iManuf=0:iDieID=0
i=0:j=0:k=0:l=0:m=0:n=0:reg=0: flagI2C2=0:port=&h40

dim ia(3) ' input buffer, 
dim ib(8) ' register values
dim sReg$(9)="Config","ShuntV","BaseV","Power","Current","Calib","Mask","Alert","Manuf","DieID"

I2C.SETUP 33, 35  ' set I2C port on pins 33-sda and 35-scl--esp32-S2Mini

'i2c.ReadRegArray port,rConfig,2,ia()
'ib(0)=ia(0)*256+ia(1)
'wlog hex$(ib(0)) ' returns '4127--power-on configuration reg value

  iCalib = 0.00512 / ( 0.001 * 0.01 )
  wlog "Calib: ";iCalib ' 512 for .010 Ohms, 1mv/LSB
  ia(0)=iCalib/256: ia(1)=iCalib-(ia(0)*256)
  i2c.WriteRegArray port,rCalib,2,ia()
  gosub outputvals
  end

outputvals:
  a$="           "
  for i=0 to 7
    a$=a$+sReg$(i)+space$(10-len(sReg$(i)))
  next i
  wlog a$
  a$ = "I2C  &h"+hex$(port)+"  "
  for i=0 to 7
    i2c.ReadRegArray port,i,2,ia()
    ib(i)=ia(0)*256+ia(1)
    select case i
      case rBaseV: a$=a$+str$(int(ib(i)*0.00125*100)/100)+"V      " ' to hundredths of a volt
      case rPower: a$=a$+str$(ib(i))+"mW      "
      case rCurrent: a$=a$+str$(ib(i))+"mA      "
      case else: a$=a$+hex$(ib(i))+space$(10-len(hex$(ib(i))))
    end select
  next i
  wlog a$
return 
Pic of the lash-up:
INA226 test rig with ESP32-S2Mini.jpg
I've also successfully tested the module with 12 volts. It should have no problem with my small 18V solar panels
You do not have the required permissions to view the files attached to this post.
lyizb
Posts: 113
Joined: Fri Feb 12, 2021 8:23 pm
Has thanked: 49 times
Been thanked: 31 times

Re: INA226 I2C Current Sensor Module

Post by lyizb »

For anyone looking at this, the calculation for current is wrong--it should be divided by 25, so, for instance, 3.31 volts at 66/25mA is 8.8mW, and 5.11V at 152/25mA is 31mA.

The values I get for Power and Current do not match the readings of a volt/ammeter device I wired in, so there is something wrong with the Calibration value. I will investigate further and report--but it may take a while--another project has gotten in the way.

(And incidentally, I love the way I wake up about every morning with a new project or wrinkle with Annex and the ESP32--thank you again, Francesco. The latest is emergency lighting for when the power goes out using Dollar Store LEDs which use 3-AAAs--the batteries are terrible (bright for maybe an hour), but the LEDs are quite bright when powered/dimmed at 5V using S2Minis or C3SuperMinis and IRLZ44N mosfets. I am controlling 4 of these LED lights from an ESP32-S2Mini now with a browser, and plan to add 4-5 more remotely using MQTT. Easy programming with Annex)

I do plan to get back to the INA226 before long--I have 7 small solar panels to monitor in various locations that I want to get mounted before we are too far past the summer solstice.
Post Reply