2024年6月9日 星期日

電量量測 - INA219直流電流電壓量測

電量量測 - INA219直流電流電壓量測

 電路圖

程式列表

Python - ePy-Lite_INA219.py

"""

  ePy-Lite_INA219.py

 

  ePy-Lite  INA219  Battery

  Pin       Pin

  -------------------------

            VIN+    BAT+

  VIN       VIN-

  P16_SDA0  SDA

  P17_SCL0  SCL

  GND       GND     BAT-

  3V3       VCC

"""

 

from micropython import const

from machine import Switch  #Get button KEY library

from machine import Pin, LED, I2C

from machine import Timer, RTC

import utime

import ustruct

import sys

from htu21d import HTU21D

import ssd1306

 

DEBUG = True

KeyADone = None

TimerDone = None

RTCDone = None

today = (2021,9,12,5,6,0,0,0)

 

I2C_FREQ = 100000

oled_width = 128

oled_height = 64

 

CONF_Reg        = const(0x00) # Configuration

SHUNT_V_Reg     = const(0x01) # Shunt Voltage

BUS_V_Reg       = const(0x02) # Bus Voltage

POWER_Reg       = const(0x03) # Power

CURRENT_Reg     = const(0x04) # Current

CALIBRATION_Reg = const(0x05) # Calibration

 

INA219_address = 0x45

MAX_CURRENT = 3.2 # Amps

CURRENT_LSB = MAX_CURRENT/(2**15)

R_SHUNT = 0.1 # Ohms

 

class INA219(object):

  def __init__(self, i2c=None,Rsh=0.1,BRNG=1,PG=3,BADC=3,SADC=3,MODE=7, addr=0x40):

    # construct an I2C bus

    if not i2c:

      i2c = I2C(0,I2C.MASTER,baudrate=100000)     #Create I2C0 Master Mode, Baudrate=100kHz

    self.i2c = i2c

    self.i2c_addr = addr

    self.buf = bytearray(2)

 

    self.Rsh = Rsh

    config = ((BRNG&0x00)<<13)|((PG&0x03)<<11)|((BADC&0x07)<<7)|((SADC&0x0F)<<3)|(MODE&0x07)

    CALIBRATION = int(0.04096 / (CURRENT_LSB * self.Rsh))

    self._write_register(CONF_Reg,config)

    self._write_register(CALIBRATION_Reg,CALIBRATION)

    if(DEBUG):

      print('Configuration:0x{:4X}'.format(config))

      print('Calibration:0x{:4X}'.format(CALIBRATION))

      print(self._read_register(CONF_Reg))

      print(self._read_register(CALIBRATION_Reg))

 

  def _write_register(self,reg,value):

    self.buf[0] = (value >> 8) & 0xFF

    self.buf[1] = value & 0xFF

    self.i2c.mem_write(self.buf, self.i2c_addr, reg)

 

  def _read_register(self,reg):

    self.buf = self.i2c.mem_read(2, self.i2c_addr, reg & 0xff)

    # value = (self.buf[0] << 8) | (self.buf[1])

    return self.buf

 

  def read_ShuntVoltage(self):

    """The shunt voltage (between V+ and V-) in Volts (so +-.327V)"""

    buffer = self._read_register(SHUNT_V_Reg)

    value = ustruct.unpack('!h', buffer)[0]

    return -value*self.Rsh #100uV/0.1Ω=1mA

 

  def read_Voltage(self):

    """The bus voltage (between V- and GND) in Volts"""

    buffer = self._read_register(BUS_V_Reg)

    value = ustruct.unpack('!h', buffer)[0]

    return (value>>3)*4.0 #mV

 

  def read_current(self):

    """The shunt voltage (between V+ and V-) in Volts (so +-.327V)"""

    buffer = self._read_register(CURRENT_Reg)

    value = ustruct.unpack('!h', buffer)[0]

    return -value/10

 

  def read_Power(self):

    """"""

    buffer = self._read_register(POWER_Reg)

    value = ustruct.unpack('!h', buffer)[0]

    return value*2

 

def key_int():

  global KeyADone

  KeyADone = True

 

def tick3(timer):

  global TimerDone

  TimerDone = True

 

def tickRTC(rtc):

  global RTCDone

  RTCDone = True

 

# Start Function

if __name__ == '__main__':

  print(sys.platform)

  ledY = LED('ledy')

  ledR = LED('ledr')

  ledY.off()

  ledR.off()

 

  KeyA = Switch('keya')    #Create button A

  KeyA.callback(key_int)

  KeyADone = False

 

  timer = Timer(3,freq = 5)

  timer.callback(tick3)

  TimerDone = False

 

  rtc = RTC()

  rtc.datetime(today)

  rtc.tickcallback(tickRTC)

  RTCDone = False

 

  i2c = I2C(0,I2C.MASTER,baudrate=I2C_FREQ)     #Create I2C0 Master Mode, Baudrate=100kHz

  oled = ssd1306.SSD1306_I2C(oled_width,oled_height,i2c)

  sensor = HTU21D(i2c)

 

  ina = INA219(i2c,R_SHUNT,0,3,3,3,7,INA219_address)

  utime.sleep_ms(100)

  print("--- Start measurement ---")

 

  while True:

    if RTCDone == True:

      ledY.toggle()

      RTCDone = False

 

    if TimerDone == True:

      ledR.on()

 

      Temperature = sensor.readTemperatureData()

      Humidity = sensor.readHumidityData()

 

      SVCell = ina.read_ShuntVoltage()    #

      VCell = ina.read_Voltage()    # read the voltage of the battery

      ICell = ina.read_current()    # read the current of the battery

      PCell = ina.read_Power()      # read the Power of the battery

 

      oled.fill(0)

      oled.text('INA219/HTU21D',0,0,1)

      oled.text('V:{:.1f}mV'.format(VCell),0,10,1)

      oled.text('I:{:.1f}mA'.format(ICell),0,20,1)

      oled.text('P:{:.1f}mW'.format(PCell),0,30,1)

      oled.text('T:{:.1f}C'.format(Temperature),0,40,1)

      oled.text('H:{:.1f}%'.format(Humidity),0,50,1)

      oled.show()

      if(DEBUG):

        print('V:{:.1f}mV, I:{:.1f}mA, P:{:.1f}mW'.format(VCell,ICell,PCell))

        # print('I:{:.1f}mA'.format(SVCell))

        print('Temperature:{:.1f}C,"Humidity:{:.1f}%'.format(Temperature,Humidity))

 

      ledR.off()

      TimerDone = False

 

    if KeyADone == True:      #Press A Key

      break

    # utime.sleep_ms(100)

 

  i2c.deinit() # close the connection to the module

  KeyA.callback(None)

  timer.callback(None)

  timer.deinit()

  ledY.off()

  print("Exit measurement.")

 

執行結果