naoki86star

インターネットの片隅でなにかしら書いてみる

電流測定 by INA219 with PIC16F18326

 INA219というデバイスのDC電流電源センサー・I2C接続で使えるのを年末アマゾンで購入した(到着まで3週間くらい待つパターン)。当初はラズベリーパイでi2c接続で使ってみるつもりだった。その前に別のアナログ値出力のやつ試してみたのだけども、ADコンバータを併用する必要あり測定可能レンジもちょっと大きめのものを選んでしまい、今時点ではちょっと扱いにくかった。そこでこれを試してみたのだけども、ラズベリーパイ母艦でなかなかお手軽に測定してくれる。測定精度は10mA粒度期待ぐらいで妥当な値を示してくれる。データシートには、AとBの2つのグレードが存在する、と書いてあるけれどもまぁエントリーなほうのAでなかろうか。見分け方はデータシートざっと眺めても実物みてもちょっと自分にはわからなかった。
 このセンサーの自分の用途としては、1A程度以下の機器単体とか、電源単位を測る感じで、監視とか履歴を残したいなんてことはそれほど欲しない。でもたまに簡単に電流の数字がみれると嬉しい感じ。そこで、こんどはPIC16F18326を使って電流測定の結果を表示することを試してみる。*1

 まず、このデバイスをラズベリーパイで使うにあたり、次のモジュールを使っていた。

pip3 install pi-ina219

 ina219.pyのコードを追ってそれからこのモジュールの実行を観察することで、電流値を得るのに最小限以下のようにできることが分かった。解析に当たってINA219のコンストラクタ引数にloglevel=logging.DEBUGを渡すとデバッグログを出してポイントを表示してくれたのが助けになった。

Python 3.7.3 (default, Jul 25 2020, 13:03:44)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import smbus
>>> i2c=smbus.SMBus(1)
>>> i2c.write_word_data(0x40, 0x05, 0x3383)
>>> i2c.write_word_data(0x40, 0x00, 0x9f21)
>>> hex(i2c.read_word_data(0x40,0x04))
'0x502'
>>> 0x0205 * 1.220e-05 * 1000
6.3074
  • 0x05に0x3383を書き込んでいるのがcalibrationというもの
  • 0x00に0x9f21を書き込んでいるのがconfigurationというもの
  • 0x04から2バイト読みだしたのが電流値に相当(6.3074mAということ、ina219の先には緑LED2個つないだ状態の実行でだいたいこんなもの)

(エンディアンが頭を混乱させる。。)

参考にしたpythonモジュールでの試行参照はこんな感じ。

pi@Fit:~ $ cat bin/pi_ina219.py
from ina219 import INA219
from ina219 import DeviceRangeError
import logging

SHUNT_OHMS = 0.1
def read_ina219():
    ina = INA219(SHUNT_OHMS, log_level=logging.DEBUG)
    ina.configure()
    return ina.current()

if __name__=='__main__':
    print(read_ina219(), "mA")

 log_level=logging.DEBUGを与えて電流を参照すると一例として以下のように出てくれた。この例ではスマートフォンの充電につないでいた。このケースを見ることで、デフォルトのconfigurationで測定電流が設定した電流上限を超えると、レンジを上げて再度参照を実行する、という動きをしていることが分かった。

pi@Fit:~/bin $ python3 pi_ina219.py
2021-01-30 14:01:30,590 - INFO - INA219 gain set to 0.04V
2021-01-30 14:01:30,593 - DEBUG - INA219 shunt ohms: 0.100, bus max volts: 32, shunt volts max: 0.04, bus ADC: 3, shunt ADC: 3
2021-01-30 14:01:30,596 - INFO - INA219 calibrate called with: bus max volts: 32V, max shunt volts: 0.04V
2021-01-30 14:01:30,599 - INFO - INA219 max possible current: 0.400A
2021-01-30 14:01:30,601 - INFO - INA219 current LSB: 1.220e-05 A/bit
2021-01-30 14:01:30,605 - INFO - INA219 power LSB: 2.439e-04 W/bit
2021-01-30 14:01:30,608 - INFO - INA219 max current before overflow: 0.3996A
2021-01-30 14:01:30,612 - INFO - INA219 max shunt voltage before overflow: 39.9598mV
2021-01-30 14:01:30,616 - INFO - INA219 calibration: 0x8333 (33587)
2021-01-30 14:01:30,620 - DEBUG - INA219 calibration: 0x8333
2021-01-30 14:01:30,623 - DEBUG - INA219 write register 0x05: 0x8333 0b1000001100110011
2021-01-30 14:01:30,628 - DEBUG - INA219 Wrote to register 0x05: [131, 51]
2021-01-30 14:01:30,631 - DEBUG - INA219 configuration: 0x219f
2021-01-30 14:01:30,634 - DEBUG - INA219 write register 0x00: 0x219f 0b0010000110011111
2021-01-30 14:01:30,639 - DEBUG - INA219 Wrote to register 0x00: [33, 159]
2021-01-30 14:01:30,645 - DEBUG - INA219 Read 0xE305 from register pair 0x02, 0x03
2021-01-30 14:01:30,648 - DEBUG - INA219 read register 0x02: 0x05e3 0b0000010111100011
2021-01-30 14:01:30,652 - INFO - INA219 Current overflow detected - attempting to increase gain
2021-01-30 14:01:30,656 - DEBUG - INA219 Read 0x9F21 from register pair 0x00, 0x01
2021-01-30 14:01:30,659 - DEBUG - INA219 read register 0x00: 0x219f 0b0010000110011111
2021-01-30 14:01:30,663 - INFO - INA219 gain is currently: 0.04V
2021-01-30 14:01:30,665 - INFO - INA219 calibrate called with: bus max volts: 32V, max shunt volts: 0.08V
2021-01-30 14:01:30,670 - INFO - INA219 max possible current: 0.800A
2021-01-30 14:01:30,673 - INFO - INA219 current LSB: 2.439e-05 A/bit
2021-01-30 14:01:30,675 - INFO - INA219 power LSB: 4.878e-04 W/bit
2021-01-30 14:01:30,679 - INFO - INA219 max current before overflow: 0.7992A
2021-01-30 14:01:30,683 - INFO - INA219 max shunt voltage before overflow: 79.9195mV
2021-01-30 14:01:30,687 - INFO - INA219 calibration: 0x4199 (16793)
2021-01-30 14:01:30,690 - DEBUG - INA219 calibration: 0x4199
2021-01-30 14:01:30,693 - DEBUG - INA219 write register 0x05: 0x4199 0b0100000110011001
2021-01-30 14:01:30,698 - DEBUG - INA219 Wrote to register 0x05: [65, 153]
2021-01-30 14:01:30,702 - DEBUG - INA219 Read 0x9F21 from register pair 0x00, 0x01
2021-01-30 14:01:30,704 - DEBUG - INA219 read register 0x00: 0x219f 0b0010000110011111
2021-01-30 14:01:30,707 - DEBUG - INA219 configuration: 0x299f
2021-01-30 14:01:30,711 - DEBUG - INA219 write register 0x00: 0x299f 0b0010100110011111
2021-01-30 14:01:30,716 - DEBUG - INA219 Wrote to register 0x00: [41, 159]
2021-01-30 14:01:30,720 - INFO - INA219 gain set to: 0.08V
2021-01-30 14:01:30,726 - DEBUG - INA219 Read 0xB206 from register pair 0x02, 0x03
2021-01-30 14:01:30,729 - DEBUG - INA219 read register 0x02: 0x06b2 0b0000011010110010
2021-01-30 14:01:30,733 - DEBUG - INA219 Read 0x2F40 from register pair 0x04, 0x05
2021-01-30 14:01:30,737 - DEBUG - INA219 read register 0x04: 0x402f 0b0100000000101111
400.7560975609756 mA

 こんな感じで自分で計算することをさぼってcaliblation/configurationの値として、0.4A/0.8A/1.6A用の値を得た。このデバイスは電源投入直後だとconfigurationは値が入っているけどもcaliblationが0らしい。caliblationだけ書き込んで使うという設計もできる、んだろうがなんかややこしい。


 PICのほうは(も)習い始めでいろいろ苦戦。の末にようやく目的に到達。PICで動かしてみた試作(作り変え2版目)。PICのコードと配線の両者で四苦八苦。PIN番号をすぐ勘違いする。PIC用のコードとしては、caliblation/configurationを固定値で最初に初期化している。
 これはM5Stackの充電を測ってるときの表示。結構流れてるんだという印象。見直すとまだ配線変えたくなる。。

# (後日追記)M5StackにはM5Stack用電池モジュールを付けている 。リチウムイオン電池でありよくある充電チャージャコントローラは0.5Aor0.1Aで流すらしいので600mA以上はおかしいと思いなおした。デバイスは2個入手していたのでもう一つで同じ測定をしてみたら600mAには到達していなかった。個体ごとにキャリブレーションの値を決定して書き込む必要がありそう。

f:id:naoki86star:20210205193504j:plain
試作2版目


 率直なところ、データシートだけでは自分はここまで到達できなかったと思う。
 I2Cの実際の通信もよく理解しておらず、トラブルシューティングには本当は実際の信号をみる必要がでてくるだろうけど、そこは素人の趣味でやっていることということで、資金的にも設備的にもやれる範囲内で。

*1:テスター使えば済む話なんですけども。。。今回の過程でデジタルテスターの必要性というか利便性を理解してきた、気がする。