稼働中

Raspberry Pi Pico(s_18)INA219 用モジュール

INA219 INA219c.py

INA219は双方向電流/電力モニタです。I2C通信で制御します。※詳細はINA219のデータシートを参照ください。
Raspberry Pi PicoでINA219センサーモジュールを使う自作の’INA219c.py’を作成しました。記事d_21を元に作成しています。’INA219c.py’は末尾にあります。
使い方だけを記載します。

使い方

■ ファイル転送
Raspberry Pi Picoへ’INA219c.py’を送った後でimportして使います。
※INA219c.pyの末尾に、使用例(INA219_ex.py)の## example以降をコピペ追加しても動作確認できます。
■ メソッド
‘INA219c’をimportすると「INA_Conf、INA_meas、RST_set、read_Cfg」のメソッドが使えるようになります。
INA219(num=1,sda=10)で初期化します。
num:I2C0、I2C1の番号です。デフォルトは1(I2C1)
sda:SDAのGPIO番号です。デフォルトは10(GP10)
スレーブアドレス 0x40、シャント抵抗Rshは0.1Ωに設定しています。
(01)INA_Conf(d_lst)
d_lstの値からmax_expect_current、Configuration Registerを設定します。
d_lstは[IMAX,RST,BRNG,PGA,BADC,SADC,MODE]の設定データです。
下の例では[‘1.5′,’0′,’0′,’11’,’0011′,’0011′,’111′]で与えています。
各データの設定値はデーターシートを参照ください。
(02)INA_meas()
測定値や計算結果を返します。
シャント電圧uV、バス電圧mV、電流mA、パワーmWのリスト値が返ります。
(03)RST_set(RST=’0′)
Configuration Registerのリセットビットを操作します。
‘1’でリセットします。’0’で解除します。
Configuration はデフォルトの0x399fになります。
(04)read_Cfg()
Configuration Registerの値を表示します。

使用例

INA219で5V電源に接続した1.5kΩの抵抗に流れる電流などを測定しました。
(記事d_21の接続図と同じです。)


INA219c_ex.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from machine import I2C,Pin
import time
from INA219c import INA219
# INA219 current power monitor
#slave address hex(64)='0x40'  A1,A0=0,0

## example
a=INA219()
# config set data [IMAX,RST,BRNG,PGA,BADC,SADC,MODE]
config_dat=['1.5','0','0','11','0011','0011','111']

d=a.INA_Conf(config_dat)    #instance

# meas=[vsh,vbs,cur,pwr]シャント電圧uV、バス電圧mV、電流mA、パワーmW
meas=a.INA_meas()
print('Vsh(uV)=', meas[0])
print('Vbus(mV)=', meas[1])
print('I(mA)=', meas[2])
print('Pow(mW)=', meas[3])

print('Vcc(mV)=',meas[1]/1000+meas[1])

# Reset Check----------------
print('')
print('Configuration')
a.read_Cfg()           #リセット前のconfig

print('RST_bit セット')
a.RST_set('1')
a.read_Cfg()           #リセット後のconfig

print('RST_bit 解除')
a.RST_set('0')
a.read_Cfg()           #解除後のconfig

実行結果

実行すると以下のようになりました。※Thonnyのshellに表示されます。


>>> %Run -c $EDITOR_CONTENT
Vsh(uV)= 300.0
Vbus(mV)= 4944.0
I(mA)= 3.204346             #5V/1.5kΩ=3.33mA
Pow(mW)= 16.47949
Vcc(mV)= 4948.944           #電源電圧

Configuration
0b0001100110011111 0x199f   #現在の設定値 16V FSR
RST_bit セット
0b0011100110011111 0x399f   #リセットでデフォルト値になる。32V FSR
RST_bit 解除
0b0001100110011111 0x199f   #解除で元設定になる
>>> 

INA219モジュール用


INA219c.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from machine import I2C,Pin
import time
# INA219 current power monitor
#slave address hex(64)='0x40'  A1,A0=0,0
class INA219:
    def __init__(self,num=1,sda=10):      
        self.addr=0x40
        self.i2c=I2C(num, scl=Pin(sda+1), sda=Pin(sda), freq=400_000)
        # register map 各レジスタのアドレス
        self.Cfg=0x00 # configuration R/W    設定が必要
        self.Vsh=0x01 # shunt voltage R signed
        self.Vbs=0x02 # bus voltage   R [3:15] 13bit 読出し注意
        self.Pow=0x03 # power         R
        self.Cur=0x04 # current       R signed
        self.Cal=0x05 # calibration   R/W    設定が必要

        self.Vsh_LSB=10*10**-6   #Shunt voltage LSB 10uV fixed
        self.Bus_LSB= 4*10**-3   #Bus   voltage LSB 4mV  fixed
        #Rsh-ohm
        self.Rsh=0.1             # shunt register ohm

    # d_lst=[IMAX,RST,BRNG,PGA,BADC,SADC,MODE]
    def INA_Conf(self,d_lst):
        # max_expect_current
        IMAX=float(d_lst[0])
        # config set data
        conf='0b'
        for i in d_lst[1:]:
            conf=conf+i

        self.config=int(conf)
        
        # PGの値から符号ビットを特定する
        PG='0b'+d_lst[3]              #PGA(|PG1|PG0|)=d_lst[3]
        self.s_bit=int(PG)+13
        
        # Calc
        self.Cur_LSB=IMAX/2**15       #SIGNがあるので15ビット
        self.Pow_LSB=20*self.Cur_LSB
        self.CAL=int(0.04096/(self.Cur_LSB*self.Rsh))
        
        # config set
        self.w_reg(self.Cfg,self.config)
        # calibrate setting
        self.w_reg(self.Cal,self.CAL)
      
        return conf

    # read start register set
    def r_reg(self,reg):
        buf=bytearray(1)
        buf[0]=reg
        self.i2c.writeto(self.addr,buf)
        r_dat=self.i2c.readfrom(self.addr,2)      # MSByte(0)LSByte(1)の2byte
        # 8bit*2>>16bit
        dat=r_dat[0]<<8 | r_dat[1]                # 2bytes 16bitデータにする
        #print('r_reg=',dat,hex(dat))
        return dat

    #符号付きの二進数を表示するにはbin(-7 & 0xf)とする必要があります。
    # signed data fugo keisan 
    def sig(self,dat,num):
        if dat >= (2**(num-1)):
            dat=dat-(2**num)
        return dat

    # regi-pointer,dat=16bit>>8bit msb,lsb
    def w_reg(self,reg,dat):
        buf=bytearray(3)                  # pointer MSByte LSByte の3bytes
        buf[0]=reg
        buf[1]=(dat>>8 & 0xff)  # MSB 16bit wo shift site 8bit
        buf[2]=(dat & 0xff)           # LSB 
        self.i2c.writeto(self.addr,buf)
        time.sleep_us(10)

    # config-regi data
    def read_Cfg(self):
        r_dat=self.r_reg(self.Cfg)
        self.d_PRN(r_dat)

    # 16bit bin print format
    def d_PRN(self,dat):
        print('{:#018b}'.format(dat),hex(dat))

    def INA_meas(self):
        # シャント電圧測定 シャント電圧レジスタ*10uV  uA signed  PGA/?bit
        vsh=self.sig(self.r_reg(self.Vsh),self.s_bit)*self.Vsh_LSB*10**6
        # バス電圧測定 バス電圧レジスタ*4mV
        vbs=(self.r_reg(self.Vbs)>>3)*self.Bus_LSB*1000    # mV Vbs 13bit
        # each calculation
        # 電流値計算 current reg*Cur_LSB
        cur=self.sig(self.r_reg(self.Cur),16)*self.Cur_LSB*1000  # mA signed 16bit
        # 電力計算 パワーレジスタ*Pow_LSB
        pwr=(self.r_reg(self.Pow))*self.Pow_LSB*1000             # mW
        return vsh,vbs,cur,pwr

    # RST: Reset Bit
    def RST_set(self,RST='0'):
        #global config
        RST='0b'+RST
        self.config=(self.config & 0x7fff)| (int(RST) <<15) #reset bit change
        self.w_reg(self.Cfg,self.config)  
        # calibrate setting  リセット後は必要
        self.w_reg(self.Cal,self.CAL)
        time.sleep_ms(10)
        return self.config