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

そんなわけで

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

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

2 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);
    }

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

コメントを残す

メールアドレスが公開されることはありません。