wiki:epics/bbb/debian/voltmon

Version 3 (modified by michkawa, 2 years ago) (diff)

--

INA226を使用した簡易電圧モニタ

某所で、1-5V程度の出力電圧を監視したいとの依頼があったので、BBBでEPICS内蔵の簡易電圧モニタを作成することになった。
電圧の測定は、I2C通信ができるモジュールやIC、Serial通信が可能なテスタなどが候補に挙がった。

モジュール 測定範囲[V] bit数
BBB内蔵 0 ~ 1.8 12
Arduino uno 0 ~ 5 10
Adafruit ADS1115 0 ~ VDD 16
INA226 I2Cディジタル電流・電圧・電力計モジュール 0~36 16(15)
MCP3425 VSS-0.3 ~ VDD+0.3 16

今回の目標としては

  • 安く作ること
    • テスタやPLCのADCモジュール、マルチメーター等は使えない
  • 分解能は12bit以上
  • スピードは考慮しない

としたので、

が候補となった。

I2C 接続試験

始めに通信が簡単そうなINA226 I2Cディジタル電流・電圧・電力計モジュールで実験してみた。

ブレッドボードにINA226モジュールを差し、4.7kΩのプルアップ抵抗をSCL,SDAに接続、電源は3.3Vを接続した。モジュールのI2Cアドレスは0x40になるように設定。
BBBとはI2C-2(P9-19,P9-20)にSCL,SDAをそれぞれ接続した。

BBBのI2C用のコマンドで確認。
入力した電圧は、VCC(3.3V)

root@beaglebone:~# i2cdetect -y -r 2
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
root@beaglebone:~# i2cget -y 2 0x40 0x02 w
0x720a

0x720aはリトルエンディアンなので、LSB,HSBを反転。(0x0a72 -> 2674)
2674 x 1.25[mV] = 3342.5[mV]
テスタで読んだ値が3.35Vなので正しそう。

その後、MCP3425も試してみたが、レジスタを読むだけでなく、RDYビットを設定したりしないといけないらしいので、今回はINA226 I2Cディジタル電流・電圧・電力計モジュールを使うことにした。

基板作成

基板は、秋月のBeagleBone・ユニバーサルプロトケープINA226 I2Cディジタル電流・電圧・電力計モジュールを載せて、LEMOコネクタから電圧を入力するようにした。
いつも問題になるケースは、BeagleBone Blck用ケースを加工して使うことにした。

最終的に、回路図

このようにしました。
ただ、コネクタとモジュール基板を上面に実装するとケースの蓋に当たってしまうので裏面に実装した。

IOC

IOCはdrvAsynI2Cを使って電圧レジスタを読み込むだけのお手軽仕様で。
レジスタマップ等のチップの仕様はTI INA226から。

とりあえず、積算時間、平均回数はデフォルトのまま変えないで、BusVoltageレジスタを読み込むだけのIOCを作成。

INA226 で通常測定で使用するレジスタは以下のようになっている。詳しくはdatesheetを参照。

POINTER(HEX) ADDRESS POWER-ON RESET(HEX) TYPE
00h Configuration Register 4127 R/W
01h Shunt Voltage Register 0000 R
02h Bus Voltage Register 0000 R
03h Power Register 0000 R
04h Current Register 0000 R

configure/RELEASE

RELEASEファイルは、使用するドライバサポートを追加。

ASYN       = $(EPICS_BASE)/../modules/soft/asyn/4-31
STREAM     = $(EPICS_BASE)/../modules/soft/stream/2.7.7_I2C
DRVASYNI2C = $(EPICS_BASE)/../modules/instruments/bbb/drvAsynI2C

I2Cを使うので対応したものを設定。

protocol file

プロトコルファイルはdrvAsynI2Cの例題にあったものをコピーして使用。

Terminator   = "";
LockTimeout  = 500;
ReplyTimeout = 100;
ReadTimeout  = 100;
WriteTimeout = 100;
MaxInput     = 2;
ExtraInput   = Error;

RdReg {
    out ${1} ${2};
    in  "%02r";
}

WtReg {
    out ${1} ${2} "%02r";
}

始めは、実験時にi2cgetで取得できたように、リトルエンディアンのデータが出力されるかと思ったが、データは普通の値として取得できたので、エンディアン変換等の後処理をする必要はなかった。

Db file

DBファイルは、streamdeviceでレジスタを読み込んで、電圧変換するだけ。
一応、configurationレジスタの設定も作成してあるが、いまのところ使っていない。

record(longin, "$(USER):INA226:BUS_VOLT:GET:RAW") {
    field(DESC, "INA226 bus registor read")
    field(DTYP, "stream")
    field(INP,  "@INA226.proto RdReg($(I2C_ADDR),2) $(BUS)")
    field(SCAN, "$(SCAN)")
    field(FLNK, "$(USER):INA226:BUS_VOLT:GET")
}

record(calc, "$(USER):INA226:BUS_VOLT:GET") {
    field(DESC, "convert voltage")
    field(INPA, "$(USER):INA226:BUS_VOLT:GET:RAW")
    field(CALC, "A*0.001*1.25")
    field(EGU,  "V")
    field(PREC, "3")
}

#################################################
#
# bit 0~2:   operate mode
#     3~5:   shunt voltage conversion time
#     6~8:   bus voltage conversion time
#     9~11:  averaging mode
#     12~14: reserved
#     15:    config reset
#
record(longout, "$(USER):INA226:CONF_REG:SET") {
    field(DESC, "Set config registor")
    field(DTYP, "stream")
    field(OUT,  "@INA226.proto WtReg($(I2C_ADDR),0) $(BUS)")
}

src/Makefile

src/MakefileにDBDとlibを設定する。

# Include dbd files from all support applications:
presSens_DBD += asyn.dbd
presSens_DBD += stream.dbd
presSens_DBD += drvAsynI2C.dbd

# Add all the support libraries needed by this IOC
presSens_LIBS += asyn
presSens_LIBS += stream
presSens_LIBS += drvAsynI2C

st.cmd

st.cmdは、送信先のデバイスをdrvAsynI2CConfigureにするだけで、いつものstreamdeviceと時と同じ。

#!../../bin/linux-arm/presSens

## You may have to change presSens to something else
## everywhere it appears in this file

< envPaths

epicsEnvSet("STREAM_PROTOCOL_PATH", ".:../../presSensApp/Db")

cd "${TOP}"

## Register all support components
dbLoadDatabase "dbd/presSens.dbd"
presSens_registerRecordDeviceDriver pdbbase

drvAsynI2CConfigure("I2C","/dev/i2c-2",1)

## Load record instances
dbLoadRecords("db/INA226.db","USER=PFaVA:test,I2C_ADDR=0x40,SCAN=1 second,BUS=I2C")

cd "${TOP}/iocBoot/${IOC}"
iocInit

#var streamDebug 1
#asynSetTraceMask( "I2C", 0, -1 )
#asynSetTraceIOMask( "I2C", 0, -1 )

実行

make後にst.cmdを実行するが、I2Cデバイスへのアクセスは通常はrootでしか許可されていないので、IOCの起動はrootで実行する必要がある。
もしくは専用のユーザーを作成し、I2Cデバイスへのアクセスを許可する設定をするしかないが、今回はrootで実行する。

IOCを起動後、cagetしてみる。
入力電圧は、3.3V電源。

beaglebone:/opt/epics/app/presSens> caget PFaVA:test:INA226:BUS_VOLT:GET PFaVA:test:INA226:BUS_VOLT:GET:RAW
PFaVA:test:INA226:BUS_VOLT:GET 3.36625
PFaVA:test:INA226:BUS_VOLT:GET:RAW 2693

テスタの読み値で3.37Vなのでほぼ同じ。

Attachments (6)

Download all attachments as: .zip