ESP-WROOM-02とINA226でWiFi電流モニタ

WROOM-02 + INA226 WiFi電流モニタ

INA226 + WROOM-02 電流モニタ
  • 電流/電圧モニタデバイスのINA226と、WiFiが簡単に使えるESP-WROOM-02を使って、電流/電圧のモニタリングをWEBブラウザで行う。
  • ブラウザでは、電流/電圧/電力の数値でのモニタリングの他、電流および電圧をGoogleChartでグラフにする。
  • USBコネクタ間のVBUSラインを接続することで、各種マイコンボードの消費電流を観測するために作成した。
  • LCDやOLEDの表示デバイスを使うと文字が小さくて困るので、PCやスマホのブラウザに表示させることにした。
  • インターネットに接続できるWiFiルーターに接続することが前提だが、APモードを使えばネット接続無しでもなんとかなる。

INA226を使ったモジュール(CJMCU-226)

TI社の電流モニタデバイスINA226の機能や特徴を簡単にまとめると以下のような感じか。

  • 15ビット分解能のA/Dコンバーターを内蔵しており、VIN-とVIN+の間にはさむシャント抵抗(RSHUNT)の両端に生じる電位差 (シャント電圧)をA/D変換することが主たる機能。
  • I2C (SMBUS)インタフェースを備えているので、マイコンに接続して簡単に使える。
  • GNDに対するVIN-(またはVIN+)電圧 (バス電圧) も同時にA/D変換させることができる。
  • シャント抵抗値とシャント電圧からVIN+ – VIN-間の電流を算出したり、電流とバス電圧から電力を算出することができる。
  • 15ビットA/Dコンバータが計測できるシャント電圧 ( VSHUNT ) のフルスケールレンジは±81.92mVである。したがって、デジタル化したときの分解能は、計算上約2.5μV (81.92 ÷ 32768 ≒ 0.0025 ) ということになる。
  • シャント抵抗値 RSHUNTが0.1Ωの場合、変換結果のLSBは25μAで、モニタ可能なフルスケール電流 ( ISHUNT )は±819.2mAとなる。

詳細は、メーカーのデータシートを参照のこと。

今回はAliexpressで買ったメーカーというか出所不明のモジュール (CJMCU-226) を使った。送料込みで1枚あたり250円くらい。日本のamazonでも入手可能だろう。

INA226 CJMCU-226 表面

この写真の中央部やや下にある10ピンのICがINA226で、その上には0.1Ωのシャント抵抗( R100 と表記)が載っている。シャント抵抗の写真左側がVIN+、右側がVIN- に接続されている。

シャント抵抗の上の2つの穴(5mm間隔)にターミナルブロックをハンダ付けして利用しているが、手持ちのターミナルブロックの都合で、シャット抵抗に乗り上げてしまった。

INA226とターミナルブロック
INA226 CJMCU-226 裏面

このモジュールを回路図にしてみると、以下のようになっているようだった。

INA226モジュール

出荷時のI2Cアドレスは0x40 で、モジュール裏面のA0やA1をVCCと接続することで、その他3通りのアドレスを設定できるから、同じマイコンにシャント抵抗を変えた複数のモジュールを接続しておくこともできる。

電源電流をモニタする場合、対象デバイスに与える電源を先にINA226のVIN+に接続し、VIN-をデバイスの電源(VCC)に接続する。電流だけをモニタするときは、対象デバイスとINA219のGNDを接続する必要はないが、バス電圧(デバイスに供給されるVIN-の電圧)もモニタしたいときには、GNDを共通にしておく必要がある。

回路図

おそらく2015年に秋月で買った ESP-WROOM-02 DIP化キット (AE-ESP-WROOM-02) が机の隅に転がっていたのでコントロール用のマイコンとし、全体は以下のようにした。INA226との接続はI2Cなので、WROOM-02を使った開発ボードならばおおよそ大丈夫だろう。

INA226 + WROOM-02

ふつうのブレッドボードの上でこれを組み立てて、INA226モジュール、AE-FT234X(USB-シリアル変換モジュール)、+3.3V用電源モジュール(AMS1117-3.3使用)などを載せると以下のようになった。

INA226 + WROOM-02
  • INA226のI2Cアドレスは0x40 (デフォルト)とした。
  • INA226のALEは、アサート時LOWのオープンコレクタに設定しておくことで、トリガモードの変換開始指示でHIGHとなり、変換や計算が完了してデータレジスタから新しい値が読出し可能となるとLOWとなる。これを使って変換完了を検出する。
  • マイコンをリセットするときは、SW1(EN)を単独で押して離す。
  • スケッチやデータファイルをフラッシュメモリに転送するときは、SW1 を押したままSW2を押し、SW1、 SW2の順に離してやる(リセット時IO0=LOW)。
  • +3.3V電源モジュールは、+3.3V出力(~800mA)の定電圧レギュレータ(AMS-1117-3.3)と周辺に必要なコンデンサ、LED、抵抗が載った便利なモジュールで、以前amazonで10個500円くらいで入手したもの。

    AMS1117モジュール
  • 電源用USB MicroBコネクタはAMS1117の入力用で、USBハブなどから+5Vを供給する。
  • USB-シリアル変換モジュール AE-FT234XはWROOM-02へのプログラム転送やシリアルモニタのために接続した。ただ、今回のスケッチにはOTAライブラリも組み込むので、初期のスケッチ転送とシリアルモニタでの動作確認が済めば外してしまえる。ボードの電源用には別途USBコネクタを置いた。

ソフトウェア

ダウンロード

構成ファイルは当サイトの https://okiraku-camera.tokyo/blog/download/ESP_INA226_httpd.zip からダウンロードできます。チェックサム(SHA256)はこちら。MITライセンス。

ESP_INA226_httpd.zip を展開すると、以下に記すようなファイルが展開されます。Arduinoスケッチ用のフォルダに適当なフォルダを作ってその中に格納してください。

ファイル構成と使い方

構成ファイルは以下のとおり。

ファイル名 内容
ESP_INA226_httpd.ino メインスケッチ。
ESP8266 Arduino Core に含まれている ESP8266WebServer ライブラリを使ったWEBサーバーを実装。WiFiクライアントとしてインターネット接続できるWiFiルーターに接続する必要がある。
インターネットに接続できない場合も考慮して、アクセスポイントモードでのビルドも可能。
esp_ota.h OTAライブラリを利用するためヘッダファイル。
ina226_if.cpp INA226用のライブラリ。Wireライブラリを使ってINA226とI2C通信を行う。
ina226_if.h INA226用のライブラリ用のヘッダファイル。
ina226_if クラスの定義を含んでいる。
data/index.html ブラウザで動かすhtmlファイルで、メインスケッチに実装したWEBサーバーと通信し、電流や電圧の取得、表示、グラフ化、INA226の動作設定などを行う。

WROOM-02のフラッシュファイルシステム(LittleFS)に格納する前提だが、PCのファイルとして直接ブラウザに読んでも動作する。

WROOM-02 (ESP8266)でのビルド

ESP8266用のボードを組み立てスケッチを書くのは久しぶりだったので、ESP8266 Communityによる、ESP8266 Arduino Core (3.0.2) Arduino IDE 1.8.15に新たに導入して利用した。また、今回のスケッチにはOTA用のライブラリ (ArduinoOTA) を組み込んでいる。

Arduino IDEのツールメニューを開くと以前によく利用していたころよりも設定項目が増えていて、おもなところは以下のように設定した。

項目 設定 備考
ボード Generic ESP8266 Module
CPU Frequency 80MHz
Crystal Frequency 26MHz
Reset method no dtr (ck) Tx/Rxしか接続していない。
Flash Size 4MB  (FS:2MB OTA;~1019KB) OTA対応。
Flash Mode QIO
Flash Frequemcy 40MHz
MMU 32KB ICACHE, 32KB IRAM 初期設定

今回利用したWROOM-02のFlash Size は4MBytesのはずなので、FS (File System)サイズを2MBとし、OTA用に上限の1019KBを選択した。OTAを使う場合、フラッシュメモリにはスケッチサイズの2倍の空きが必要になるから、FSを2MBとすれば約1MBに制限されるのはやむを得ない。今回のスケッチのサイズは以下のようになった。

sizes.py の出力

size.pyは詳細なセグメントサイズを表示してくれる。

xtensa-lx106-elf-size の出力

arduino共通のメモリ使用状況。

xtensa-lx106-elf-sizeの出力は、size.pyの出力をまとめた値を表示している。

  • フラッシュサイズ = IROM + IRAM + DATA + RODATA 
  • RAMサイズ = DATA + RODATA + BSS 

IROMおよびIRAM の各セグメントにはコードが配置される。IROMはフラッシュメモリに配置されているふつうのコードのサイズ、IRAMはESP8266のInstruction RAMに配置されるコードのサイズを表している。コアライブラリでは、割り込みハンドラやよく使われそうな関数など、IRAM_ATTR という属性付きで宣言されている。

ICACHE (Instruction Cache)は、実行のためにフラッシュから読み出すキャッシュ領域の大きさで、ビルド時の領域分けには関係しない。

DATAは初期値をもつデータで、ブート時にフラッシュからRAMに初期値が転送される。RODATAはたぶん const データで、やはりフラッシュからRAMに転送される。最後のBSSは未初期化(初期値を持たない)データのブロックで、変数型によっては0で初期化される。

OTAライブラリの組み込み

OTA (Over-The-Air) とは、WiFiなどの無線通信を経由してフラッシュ内のスケッチやデータを更新するための仕組みで、ESP8266 Arduino Coreに ArduinoOTAというライブラリが用意されている。

OTAを利用して更新を行いたいスケッチには、OTAライブラリを組み込んで使う必要があるので、以下のようなファイル (esp_ota.h) を用意した。これは、ArduinoOTAライブラリのスケッチ例に含まれている BasicOTA.ino から必要な部分を抜粋したもの。

メインスケッチの setup() 内で ota_setup( OTA_PORT_NAME ); としてOTAライブラリの組み込みを行い、loop()内で handle_ota(); を呼び出すようにすれば、Arduino IDEに転送用のポートが表示されるようになる (初回はシリアル転送とESP8266の手動リセットが必要)。

今回のスケッチはもともとWiFiを使う前提のものなので esp_ota.h 内でWiFiルーターに接続するコードは入れていないが、スケッチ自体にWiFi接続がないものなら ota_setup() 内で WiFi.begin(ssid, password); とかやってルーターに接続しておくようにする。

ota_setup() の引数として “ina226_ota_port”  という名前をセットしているので、Arduino IDEのツール/シリアルポートに以下のように表示された (IPアドレスは、192.168.63.10)。

OTA転送ポート

WiFi設定について

  • メインスケッチの void setup_wifi() で、WiFiルーターに接続するためのssid、パスワード、IPアドレス、ゲートウェイアドレス設定する必要がある。
  • GoogleChartを利用しているので、インターネットからGoogleChart用のスクリプトを読み込む必要がある(スクリプトをローカルにコピーしての使用は許諾されていない)。
  • index.html をPCのファイルとして利用するのに便利なように固定IPアドレスとしている (サーバーからではなくPCからブラウザに読み込んだ場合、JavascriptにサーバーのIPアドレスを設定してやる必要があるため)。
  • setup_wifi()  内では、以下のように条件分けしてあるので、WROOM-02をAPモードでビルドする際には、最初を#if 0 としてからビルドする。

INA226とのインタフェース

INA226をI2C経由でコントロールする部分はライブラリとしても使えるように独立させた ( ina226_if.cpp / .h )。詳しくは添付のソースを参照してください。。

INA226の設定やデータのことなど

通信速度は400kHzとし、Arduino core のWireライブラリを素直に利用した。INA226には、10個の16ビット長のレジスタがあり今回はそのうちの7つを使っている。

ポインタアドレス 名称
ソースでの定義
機能/備考
0x00 コンフィグレジスタ
REG_CONFIG
デバイスのリセット、A/D変換の対象設定、A/D変換時間、平均化回数などの設定。
トリガモードでは、このレジスタへの書き込みにより変換が開始し、同時にALEピンが非アサート状態となる。
0x01 シャント電圧レジスタ
REG_SHUNT_V
シャント電圧の変換結果を保持。変換完了時に読み出す。
0x02 バス電圧レジスタ
REG_BUS_V
バス電圧の変換結果を保持。変換完了時に読み出す。
0x03 電力レジスタ
REG_POWER
電力の計算結果を保持。変換完了時に読み出す。
REG_CALIBRATION== 0のとき無効。
0x04 電流レジスタ
REG_CURRENT
電流の計算結果を保持。変換完了時に読み出す。
REG_CALIBRATION== 0のとき無効。
0x05 キャリブレーションレジスタ
REG_CALIBRATION
電流および電力を算出する際のフルスケールとLSBから導く係数を設定する。
今回はシャント電圧とシャント抵抗値から電流を求めるのと同様な2048とした。
0x06 マスクイネーブルレジスタ
REG_MASK_ENABLE
アラート状態の設定機能と変換完了フラグをもつ。
今回は変換完了時にALEピンがLOWになるように設定。

INA226の動作設定は、WiFi経由でブラウザから行うようにした。font-sizeはちょっと大きめ。

INA229 Current Monitor Settings

各設定項目の内容は以下のとおり。

項目 選択肢 説明
Conversion Target Shunt + Bus
Shunt のみ
Bus のみ
変換対象を設定する。
Sampling and Averaging 1回
4回
16回
64回
INA226内で平均を得るためのサンプル回数を設定する。
Conversion Time 140usec
204usec
332usec
588usec
1.1msec
INA226のA/D変換時間を設定する。
Use Calibration Register チェック時は既定のキャリブレーション値を使う。
非チェック時は0を使う。
Use origin htmlファイルをPCのローカルディスクから読むとき、サーバーのスキームとアドレスとして使う。
サーバー側のスケッチでは、 server.enableCORS(true);  によりクロスオリジン でのリソース共有を許可。

これらの設定内容をhttpリクエストでWROOM-02に送り、それぞれをINA226に設定するようにしている。

I2Cアドレスやシャント抵抗の値は、複数のINA226モジュールをWROOM-02に接続する場合を考慮して設定できるようにした。

今回のプログラム (ina226_if) では、シャント電圧とシャント抵抗からオームの法則で電流を求めているので、キャリブレーションレジスタを使わなくても(値0をセットしても)電流や電力の値は変わらない。キャリブレーションレジスタに0をセットしたとき、変換時間が短くなることも期待したが変換時間に変化はなかった。

WROOM-02のFS領域にhtmlファイルを格納してそこから読み出すときにはオリジン指定は不要だが、スクリプトはすぐに直したくなるから、PCのファイルとして利用できる方が便利だろう。

変換時間など

INA226では、シャント電圧とバス電圧それぞれのA/D変換時間を8通りに設定できる。今回の実装ではいずれも同じ値になるようにし5種類から選択できるようにした。電源電圧が安定している対象を相手にするならば、バス電圧だけ高速にしてシャント電圧はゆっくり目にしてやることもなども可能で、そのあたりはコンフィグレジスタの設定次第となる。

また、複数の変換結果を取得して平均値をデータレジスタに格納する機能もあり、こちらも8通りのサンプル回数が設定できるようになっている。今回の実装では4種類(1, 4, 16, 64サンプル)から選択するようにした。

時間が関係する要素が複数あるので、コンフィグレジスタに書き込んで変換開始を指示してから、データが用意されるまでの変換完了時間を測ってみたところ、変換対象ごとに以下のようになった。

A/D変換時間 平均化回数 Shunt and Bus Shuntのみ Busのみ
140us 1 360us 238us 197us
4 1.22ms 665us 624us
16 4.63ms 2.37ms 2.33ms
64 18.3ms 9.20ms 9.16ms
204us 1 490us 303us 262us
4 1.72ms 925us 884us
16 6.71ms 3.41ms 3.37ms
64 26.64ms 13.4ms 13.3ms
332us 1 750us 433us 392us
4 2.77ms 1.45ms 1.40ms
588us 1 1.27ms 694us 652us
1.1ms 1 2.31ms 1.21ms 1.17ms

平均化回数を増やしたときの変換完了時間は、1回だけのときの回数倍よりは短いものの、目安としては回数倍と考えて良さそうだった。

トリガモードではコンフィグレジスタへの書込みでALEピンが非アサート状態(今回の設定ではHIGH)となり、変換/計算結果がデータレジスタから読出し可能となった時点(変換完了時点)でアサート状態(LOW)となる。これをロジアナで観測してALEピンがHIGHの期間の時間を変換完了時間としている。

また、変換完了時(ALEピン=LOW)になった時点で4つのデータレジスタ(シャント電圧、バス電圧、電流、電力)を読み出すときの様子をロジアナで見ると、以下のようになっていた。

INA229 data read

読出しの開始から終了までに約590μsecかかっている。

ついでに書いておくと、コンフィグレジスタへの書込みには約125μsec かかるので、マイコン側から見たトータルの変換時間は、125 + (INA226の変換完了時間) + 590 (μsec) になるだろう。したがって、シャント電圧とバス電圧を最速で取得するのに要する時間は 125 + 360 + 590  = 1.1msec  になる。

電流と電力の転送をやめた場合データを読み出すための時間は300μsecほどになるから、変換結果をマイコンのメモリに格納していく前提ならば1秒間に1000サンプル以上取得することはできるだろう。

I2Cインタフェース

16ビット長レジスタの書込みと読出しは、上位バイト、下位バイトの順に行う。以下のようなメソッドを用意した。

I2C対応のRTC(DS3231とか)などでは、8ビットレジスタを連続して読み書きするときデバイス側でポインタアドレスを暗黙でインクリメントしてくれたりするが、INA226では毎度毎度ポインタアドレスを設定する必要がある。

メインスケッチ ESP_INA226_httpd.ino

メインスケッチは、ESP8266 Arduino Core に含まれている ESP8266WebServer ライブラリを使っていて、WiFiクライアントモードでWiFi ルーターに接続することを前提としている。以下のAPI を用意した。

/get_trig

コンフィグレジスタへの書込みで変換を開始し、ALEピンがLOWになった時点でデータレジスタからの取得を行ってデータをCSV形式で応答する。コンフィグレジスタに書き込む値は、スケッチ内に用意した初期値、あるいは、 /setsettings によってブラウザから受け取ったものを使う。

/get_cont

連続モードでのデータ取得を行う。初回のみコンフィグレジスタを連続モードに設定して書込みを行い、あとはリクエストに応じてデータレジスタからの読出しとデータの応答を行う。

応答するデータは以下のように文字列化した浮動小数点データを連ねたCSV形式になっている。

先に書いたように、変換対象、変換時間、平均化回数をセットした時点でデータレジスタから新規データを取得できるまでの時間はわかるので、その時間以上のインターバルでポーリングしてやるならば、連続モードでもトリガモードでも大して変わらない。

/getsettings

サーバー側がもつINA226の設定値をCSV形式で応答する。例えばブラウザをリフレッシュしたようなとき、サーバー側の設定値をブラウザ側(スクリプト) に教えるために用いている。

/setsettings

ブラウザ側の設定内容をサーバー側に通知する。

server.onNotFound

上記4つ以外のリクエストがきたら、onNotFound() ハンドラが呼ばれる。パス要素がFS内のファイル名と一致すればFSから読みだした内容を応答するし、なければステータス404を応答する。

ブラウザ用のHTMLファイル (index.html)

サーバーアドレスをブラウザでリクエストすると、以下のような画面が開く。

INA226 index.html

Polling Interval の横のフィールドに指定した msecごとにサーバーに対してトリガモード (/get_trig) または連続モード(/get_cont) のリクエストを出し、取得した数値で表示を更新する。

Settings ボタンを選択すると、前に示した設定画面を表示する。その横の赤い点々は、動作していることを示すためのもので、ポーリングごとに1点ずつ増えていく。

下側の矩形領域は、取得した値をグラフ表示するための領域で、3つのボタンでログの開始、グラフ表示、ログおよびグラフ消去を行う。

詳細については、data/index.html のスクリプトを参照のこと。

index.htmlはFS領域に格納

index.htmlファイルは、基本的にはWROOM-02のフラッシュファイルシステム(FFS)内に格納する。Arduino IDEのツールメニューの ESP8266 LittleFS Data Upload を選択することで、スケッチのあるフォルダに作った data フォルダの内容がFFSに転送される。

Arduino IDE

転送はシリアルでもOTAでも可能だが、シリアル転送の方が何をやっているのかわかりやすい気がする。

前にも書いたように、FFSに転送せずにPCにおいた index.html をブラウザに読み込んで使ったもかまわない。

ブラウザで使っているところ

特に使い方というのもないので、PCのChromeとスマホのChromeでモニタ表示しているところをYouTubeに動画を登録した。

グラフ

INA229 Current Monitor

グラフ部分を切り出したもの。

これは Seeeduino XIAO-m0 の3つのオンボードLEDを1つずつ点灯させては消灯させているとき、USBケーブルのVBUSを流れる電流と電圧をモニタしたもので、2つ載っている青色LEDを点灯させたときの方が、橙色LEDより個々の消費電流が少ないなんてことが分かる。青色は1個あたり0.75mA程度で、橙色の方は1個あたり1.3mA程度。

USBケーブルのVBUS電流をモニタするために、最初の写真のようなVBUSを引き出したケーブル?を作成して使った。

きょうのまとめ

  • INA226を使った電流モニタを作る前に、同じTI社のINA219も使っていた。INA226と比べると、分解能が低い(ADCは12ビット)、ALEピンがない、オフセット電圧が大きい(誤差が大きい)といったデメリットもあるが、PGA(Pre Gain Amp)を内蔵しているので、広いフルスケールレンジを選択できるから、Raspberry Pi  (Model4B) のような消費電流の大きな相手にもシャント抵抗を変えることなく使えるのが利点だろう。
  • hoboNicolaアダプタに使う各種マイコンの、定常時やスリープ時の電流測定に使う予定。
  • なにか肝心なことを書いていないような気もするので、気がついたら追記していきます。