Class Library of "INA226 CURRENT/POWER MONITOR with I2C"

Dependents:   INA226TEST Logger_V1 RS485R_2 SOUDA_YOKUTAN_R ... more

INA226 I2Cディジタル電流・電圧・電力計モジュールのクラスライブラリ

ストロベリー・リナックスから販売されてる電流・電圧計モジュールのクラスライブラリです

http://strawberry-linux.com/catalog/items?code=12031

/media/uploads/tosihisa/_scaled_2012-11-25_02.55.58.jpg /media/uploads/tosihisa/_scaled_2012-11-25_02.55.33.jpg

この写真では,INA226 を使って自作GPSロガーの電圧と電流を測定しています.

電圧と電流を同時に測定できますので,電源電圧の確認や,消費電力の計算に使えるでしょう.

テストプログラム

このクラスライブラリを使用したテストプログラムを公開しています.

Import programINA226TEST

INA226 Test Program. Using INA226 class library.

注意点

  • ストロベリーリナックスのマニュアルによると,「16ビットの電流の測定値に1.25を掛けたものがそのまま mA の直読になります.」とあるのですが,キャリブレーションレジスタに 0x0A00 を書き込んだ場合は,1.25 を掛ける必要は無さそうです.電圧は常に 1.25 を掛けます.
  • INA226 はキャリブレーションレジスタに書き込みを行わないと電流値は0のままです.電流を読み取る場合は,必ずキャリブレーションレジスタに値を書き込んでください.ストロベリーリナックスのモジュールであれば,シャント抵抗は 0.002Ω(2mΩ)と言う事で,INA226 の標準的な抵抗の様ですから,キャリブレーション値は 0x0A00 とおもいます.このクラスライブラリでは,キャリブレーション値の省略値は 0x0A00 にしています.
  • 持っているテスター(A&D AD-5518T)と測り比べをしてみました.電圧・電流共に,10〜20ミリ程の差がありそうです.

追記

mbed M0 (黄mbed) でも再コンパイルするだけで動きます.

/media/uploads/tosihisa/_scaled_2012-11-25_16.43.17.jpg

INA226.cpp

Committer:
tosihisa
Date:
2012-11-24
Revision:
0:3a05c5755625
Child:
1:e0ebc6af5e04

File content as of revision 0:3a05c5755625:

/*
 * Copyright (c) 2011 Toshihisa T
 * Released under the MIT License: http://mbed.org/license/mit
 */

#include "mbed.h"
#include "INA226.hpp"

INA226::INA226(I2C &i2c_,int addr_,int freq_) : i2c(i2c_),i2c_addr(addr_),freq(freq_)
{
    i2c.frequency(freq);
}

int INA226::isExist(void)
{
    char p_addr = 0;   //Select Configuration Register.
    i2c.frequency(freq);
    if(i2c.write(i2c_addr | 0,&p_addr,sizeof(p_addr)) == 0){
        return 1;
    }
    return 0;
}

int INA226::rawWrite(char pointer_addr,unsigned short val_)
{
    char val[3];
    val[0] = pointer_addr;
    val[1] = static_cast<char>((val_ >> 8) & 0x00ff);
    val[2] = static_cast<char>(val_ & 0x00ff);
    i2c.frequency(freq);
    if(i2c.write(i2c_addr | 0,val,sizeof(val)) == 0){
        return 0;
    }
    return 1;
}

int INA226::rawRead(char pointer_addr,unsigned short *val_)
{
    char p_addr = pointer_addr;
    char val[2];
    i2c.frequency(freq);
    if(i2c.write(i2c_addr | 0,&p_addr,sizeof(p_addr)) == 0){
        if(i2c.read(i2c_addr | 0x01,val,sizeof(val)) == 0){
            *val_ = static_cast<unsigned short>(val[0]);
            *val_ = (*val_ << 8) | static_cast<unsigned short>(val[1]);
            return 0;
        }
    }
    return 1;
}

int INA226::getVoltage(double *V_)
{
    unsigned short val;
    if(rawRead(0x02,&val) == 0){
        *V_ = static_cast<double>(val) * 1.25;
        return 0;
    }
    return 1;
}

int INA226::getCurrent(double *I_)
{
    unsigned short val;
    if(rawRead(0x04,&val) == 0){
        char *s_p = reinterpret_cast<char *>(&val);
        short d_s;
        char *d_p = reinterpret_cast<char *>(&d_s);
        *(d_p + 0) = *(s_p + 0);
        *(d_p + 1) = *(s_p + 1);
        *I_ = static_cast<double>(d_s) /* * 1.25 */;
        return 0;
    }
    return 1;
}

int INA226::setCurrentCalibration(unsigned short val)
{
    return rawWrite(0x05,val);
}