INA226でお手軽電圧・電流測定(ついでにBit-BangでI2C)

INA226をArduinoで使ってみました。後半にはオマケで、FTDIのBitBangモードを使った疑似I2Cを使ったバージョンもあります。

INA226とはテキサスインスツルメンツのICで、手軽かつ超高精度に電流・電圧・電力を測定することができます。インタフェースはI2Cです。

シャント抵抗まで実装されたモジュールが、ストロベリーリナックスから販売されているので、今回はそれを使いました。シャント抵抗が2mΩと小さいので、電圧降下がほとんど無視できます。

INA226モジュール

Arduinoと接続してみる

Arduinoとつないでみます。と言っても10kΩの抵抗2本なので超簡単。

取得できるのは電圧(Bus Voltage)、シャント抵抗電圧(Shunt Voltage)、電流(Current)、電力(Power)の4種類。電力、シャント電圧→電流の変換、平均化処理はIC内部勝手にやってくれます。電流と電力を計算するために、初期化時にCalibrationレジスタにシャント抵抗の定数を書き込んでおく必要があります。(2mΩの場合は0A00h)

詳しくは、ソースを見てください。

ソースはこちら:ina226_test2

2013/09/04追記:電力が1/10で表示される不具合を修正しました。

レジスタダンプ

回路図(Arduinoで接続)

実際に測ってみる

Nintendo 3DSLLの充電電流を測ってみました。813mAだそうです。(途中で電流が変動したので、写真の電源は0.65Aになってます)

配線がテキトウだったせいで、電源からUSBの付け根までハイサイド・ローサイド合計で約50mVの電位差がありました。きちんと測定するには、配線の抵抗も考慮しないとダメですね…。

3DSLLを充電中

3DSLL充電中

精度はどのくらい?

自宅のデジタルテスターで測った値とはほぼ一致してたので、まあ大丈夫な感じと思うんですが、秋月で4.096Vの高精度シャントレギュレータ(LM4040AIM3-4.1/NOPB)を買ったので、試しにつないでみました。4096mVぴったり!素敵!!

が…この値は、INA226の電源電圧に3.3Vを使ったとき。5.0Vにすると、4098Vになっちゃいました。orz

シャントレギュレータの電圧を測定

シャントレギュレータの電圧

FTDIのBitBangモードで疑似I2Cしてみる

元々は一昨年のKick4勉強会のネタですが、FTDIのFT232/245シリーズにはBitBangモードというICの信号線をパラレルIOのように使える機能があって、それを使って簡易的なI2C通信をやってしまおうという実験です。

できる!Bit-Bangモード

外付け部品がダイオード2本と抵抗3本だけなので、わざわざマイコンまで使いたくない場合にいいかも。

ソースはこちら(Visual C++2010):bitbang_ina226

2013/09/04追記:電力が1/10で表示される不具合があります。そのうち修正します…

BitBangで通信

回路図(BitBangでI2C)

Bitbangでi2c

そんなわけで

調整が要らないし、精度は高い(と思う)ので、なかなか面白いモジュールだと思います。

ゆくゆくはケースに組み込んで、スタンドアロンの計測器にしたいなぁと思ってます。

13 comments

  1. はじめまして。つい1週間ほど前からArduinoをつつきだしたド素人です。
    現在、簡易電圧電流データロガーを作ろうと試行錯誤中で、検索していたらこのページに辿り着きました。同じストロベリーリナックスさんのINA226のモジュールを使っているので、大変参考になっています。(その他も参考にしてます。)
    テストソースを使わせていただいたのですが、どうも電力の数値が1ケタ少ないようです。最初、私の設定ミスかな?と思い、調べたのですが、上図の結果も少ないようなので、ソースコードの計算式に何かあるのかも知れません。
    (プログラムも初めてなので、どこを見ていいかも分かっていないです。)
    気になっただけです、では。

  2. コメントありがとうございます。
    すみません!堂々と間違っていました。当方の不具合です。お恥ずかしい…。

    取り急ぎ、164行目を以下のように修正していただければ正しい表示になるのではと思います。ソースも差し替えておきました。

    power = (long)readRegister(INA226_REG_POWER) * 2500; // LSB=25mW

    power = (long)readRegister(INA226_REG_POWER) * 25000L; // LSB=25mW

    サンプルのソースはsnprintfを使うためにわざわざ整数で演算しており見にくいです、特にこだわりが無ければ、loop()関数はシンプルに以下のように書けます。
    shortでキャストしているのは負数への対応です。

    void loop(void)
    {
    double v = (double)((short)readRegister(INA226_REG_BUS_VOLTAGE)) * 0.00125f;
    double i = (double)((short)readRegister(INA226_REG_CURRENT)) * 0.001f;
    double p = (double)readRegister(INA226_REG_POWER) * 0.025f;

    Serial.print(p); // 電力表示
    Serial.println(“W”);

    Serial.print(v); // 電圧表示
    Serial.println(“V”);

    Serial.print(i); // 電流表示
    Serial.println(“A”);

    delay(1000);
    }

    記事の方は近日修正します。
    ご報告ありがとうございました。

  3. 初めまして
    ずいぶん前に、私設 太陽光発電システムの充電電流を測定したいと思い、
    INA226を購入しました。
    貴殿のページを見て、プログラムの動作までは、行ったのですが、
    当方の持っているINA226のシャント抵抗は25mΩなのですが、プログラムの、
    どこを修正すれば、宜しいのでしょうか?
    ぶしつけなご質問ですみません。

    • 初めまして。コメントありがとうございます。
      シャント抵抗の値に合わせて、「Calibration Register (5)」を設定する必要があり、2mΩの場合は0A00hとなります。
      実際に定義している場所は、以下になります。
      ina226_test2:ina226_test.inoの14行目の「const word INA226_CAL_VALUE = 0x0A00;」
      bitbang_ina226:BitBangI2CDlg.cppの202行目の「val = 0x0A00;」
      具体的な計算については、INA226のデータシートの「7.5.1 Programming the Calibration Register」を参照して下さい。

  4. TOMOさん

    始めまして、最初から大変不躾なお願いで大変失礼ではございますがTOMOさんのINA226用スケッチを一部追加変更をしてCQ出版社向け原稿中の中国製Li-ion BatterynCharger Moduleの充電特性測定に利用させて頂きました。原稿中にはTOMOさんスケッチを利用させて頂いた旨を記載させて頂きますのでご了承をお願いいたします。

    • 初めまして!ご連絡ありがとうございます。
      拙いコードですが、ご活用頂けてとても嬉しいです。
      QCの本(雑誌?)チェックしますね!

  5. TOMO様

    ご快諾頂き有難う御座います。
    トラ技12月号 中国製リチウムイオン電池用充電モジュールの製品解析記事に引用される予定です。

    並木精司

  6. ありがとうございます。
    記事を拝見しました。
    充電ICの動作について解析されていて興味深かったです。
    試そうと思えば通販で手に入るところもいいですね。

  7. TOMO様

    初めまして、TKと申します。

    仕事でINA228を購入し、電圧測定に使うことを検討しています。
    電子工作は素人で、ネットの記事を探していたのですが、INA228について直接書かれたものは見当たりませんでした。
    記事を拝見して測定を試してみたのですが、やはりうまく動かないようです。
    INA226は16ビットでINA228は20ビットなのが原因だと思うのですが、宜しければ、どこを修正すればよいか教えていただけませんでしょうか。
    また、これらの装置は2進数で測定結果を送ってきており、プログラム上で10進数に変換しているという理解で合っていますでしょうか。

    初歩的な質問で大変恐縮ですが、ご回答いただければ幸いです。

    • TKさん、初めまして!コメントありがとうございます。

      INA228を使ったことが無いのですが、データシートを確認したところ、レジスタの構成がINA226と違っていましたのでINA226のソースを大幅に改修しなければ動かないのではと思います。

      探してみたところ、INA228を制御するコードを公開されている方がいらっしゃいましたので、そのコードを参考にされた方が良いかと思います。(中身まで見たわけではないので、動作の保証は致しかねます)
      https://github.com/search?q=ina228

      • ご返信いただきありがとうございました。

        おぼろげにデータシートの読み方が分かってきまして、電圧のレジスタが2hから5hに変更されていることがわかりました。
        レジスタフィールドで電圧は23-4ビットに格納されているようなのですが、単純に左に4つずらして読み込んでは駄目なんでしょうか?
        実際やってみると、LSBのさらに4倍をかけると大体正しい数値が返ってきました(分解能がてんで低いですが)

        • データシートを見てみましたが、VBUSはシフトせず単純に195.3125uVを掛ければ良いようです。
          「8.2.2.5 Calculate Returned Values」に例があるので見てみてください。

  8. INA226とArduino UNO r3 で、ソーラーパネルの電圧電流計測を試している者です!
    無事に配線を終え、I2Cでのデータ取得をを表示させたのですが、初めのConfiguration Register(00h)しか正しいデータが取れず(あとはすべて1・・・)、はんだ付けの時にIC壊したのかと顔面蒼白していました。。

    そんなところ、ここのサイトのテストプログラムに助けられました!(=うまくデータ取れました!)
    Readばかりで、何もWhiteしていませんでした。。(たぶん、Calibration Register(05h)のA00hを設定していなかったのが問題だったのでしょうか・・)
    わかりやすいプログラム、ありがとうございました!

    p.s. 2031.09.03になっておりました。たぶん、2013.09.03ですね!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です