ESP32電力計 改造設計書

<!-- markdown-mode-on --> **対象スケッチ:** ArduinoWattMeter_MQTT_v4.ino **作成日:** 2026-04-21 **改造目的:** ESP32内蔵ADCの非線形性・オフセット誤差に起因する電流測定誤差の解消 --- ## 目次 1. [現状システムの問題点](#1-現状システムの問題点) 2. [A. ハード変更](#2-a-ハード変更) 3. [B. ソフト変更](#3-b-ソフト変更) 4. [変更前後の比較](#4-変更前後の比較) --- ## 1. 現状システムの問題点 ### 1.1 ADC構成 | ピン | 用途 | 回路構成 | |------|------|---------| | GPIO35 | 基準電圧(Vref) | R4(100k$\Omega$)/R5(47k$\Omega$)分圧 + C1/C2(470μF)平滑 | | GPIO34 | 電圧測定 | AC変圧器 → D1/D2(1N5817)半波整流 → R3(1k$\Omega$) | | GPIO32 | 電流A測定 | CT → R8(30$\Omega$)バーデン → D5/D6(1N5817)両方向クランプ → R7(1k$\Omega$) | | GPIO33 | 電流B測定 | CT → バーデン → 両方向クランプ(CHAと同構成) | | GPIO36 | 周波数測定 | AC変圧器 → D3/D4(1N5817) → R6/R1 → 74HC14整形 | | GPIO39 | 電源電圧監視 | 5V分圧 | 現状の電流CH回路構成(CHA): ``` CT二次側 ├─(+)─── R7(1k$\Omega$) ────────────────── GPIO32 │ D5(1N5817) → VDD(3.3V) │ D6(1N5817) → GND R8(30$\Omega$) │ └─(-)────────────────────────────── GND ``` D5/D6はVDDおよびGNDへの両方向クランプ保護回路である。 <div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEghLbAEXDw-jOoD4LgaBBgd-QkPoE-MwOd5KYztMeTNq_2_poLgjqhG1rlaNj7ZPwUzzJ5ebj9s-G9LSx1tkJeI4vwPwuA90j7TEKJyQYXa-136pHRf-eZNLcKbOPitFbKInC7jSO2Q3Zzm9QRIvdyElTlrBmB9AlCX1Z66TufqsNclYvjzlKiNwIfnyx6H" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="893" data-original-width="1920" height="149" src="https://blogger.googleusercontent.com/img/a/AVvXsEghLbAEXDw-jOoD4LgaBBgd-QkPoE-MwOd5KYztMeTNq_2_poLgjqhG1rlaNj7ZPwUzzJ5ebj9s-G9LSx1tkJeI4vwPwuA90j7TEKJyQYXa-136pHRf-eZNLcKbOPitFbKInC7jSO2Q3Zzm9QRIvdyElTlrBmB9AlCX1Z66TufqsNclYvjzlKiNwIfnyx6H" width="800" /></a></div><br /><br /></div> ### 1.2 問題の所在 **電流測定の主要問題** ESP32内蔵ADCには以下の本質的な問題がある。 - 実効分解能は12bit公称に対し実測では10〜11bit相当 - 非線形性が大きく、入力電圧に対してADC出力が直線的でない - オフセット誤差が大きく、ゼロ付近の精度が特に劣る - CT二次側を半波整流してシングルエンド入力しているため、RMS計算に使えるサンプルが半サイクル分(50%)に制限される **電圧測定の問題(相対的に小さい)** - 電圧は絶対値が大きいためSNRは電流より有利 - v4スケッチのEMAフィルタおよびOUTPUT_INTERVAL拡張により、当面は許容範囲内と判断する ### 1.3 改造の範囲 | 対象 | 改造方針 | |------|----------| | 電流CH(A・B) | ADS1115に移行し、非線形性・オフセット誤差を根本解消する | | 電圧CH | ESP32 ADCを継続使用。Vref安定化のみ実施 | | 周波数CH | 変更なし | | 電源監視CH | 変更なし | --- ## 2. A. ハード変更 ### 2.1 Vref安定化(電圧CH改善・即時実施可能) **目的:** GPIO35のVref読み取りノイズを低減する **方法:** 既存のVref分圧回路(R4=100k$\Omega$、R5=47k$\Omega$)の出力ノードに電解コンデンサを追加する | 追加部品 | 値 | 接続箇所 | |----------|----|----------| | 電解コンデンサ | 47μF(耐圧6.3V以上) | GPIO35とGNDの間 | --- ### 2.2 ADS1115導入(電流CH改造・主要変更) #### 2.2.1 ADS1115の特長と採用理由 | 項目 | ESP32内蔵ADC | ADS1115 | |------|-------------|---------| | 分解能 | 12bit(実効10〜11bit) | 16bit(実効15bit) | | 非線形性 | 大きい | 無視できるレベル | | オフセット誤差 | 大きい | 最大±0.1mV(typ) | | 入力モード | シングルエンド | 差動入力 | | インターフェース | 内蔵 | I2C | | 最大サンプリングレート | 1000 SPS | 860 SPS | 差動入力を使用することで、CT二次側の正弦波をそのまま(整流なしで)取り込める。これによりRMS計算に全サイクルのサンプルが使用可能になる。 #### 2.2.2 ゲイン(PGA)設定の根拠 **系統構成と最大電流の考え方** 単相3線式40A契約の構成: ``` 契約ブレーカ(40A) ├─ L1 ──────────────────────── 最大40A │ ├─ 分岐ブレーカ(15A) → 回路1 │ ├─ 分岐ブレーカ(15A) → 回路2(並列) │ └─ ... ├─ N(中性線) └─ L2 ──────────────────────── 最大40A ├─ 分岐ブレーカ(15A) → 回路3 └─ ... ``` CTはL1またはL2の幹線に取り付けられている。各相の幹線には並列接続された分岐回路の電流の総和が流れるため、**L1・L2それぞれに最大40Aが流れ得る。** CT二次側の最大ピーク電圧: $$V_{peak,max} = \frac{40}{1800} \times 30 = 0.667\,\text{V}$$ 通常使用域(20A程度)のピーク電圧: $$V_{peak,normal} = \frac{20}{1800} \times 30 = 0.333\,\text{V}$$ ゲイン選択: | PGA設定 | FSR | LSBサイズ | $V_{peak,max}$に対する判定 | |---------|-----|-----------|--------------------------| | GAIN_EIGHT | ±0.512V | 15.6μV | **クリップ(0.667V &gt; 0.512V)** | | **GAIN_FOUR** | **±1.024V** | **31.25μV** | **適切(マージン35%)** | | GAIN_TWO | ±2.048V | 62.5μV | 分解能が低下 | **採用: GAIN_FOUR(±1.024V)** LSBサイズ比較: ESP32 ADC実効分解能の約800μVに対し31.25μV。**約26倍の分解能向上**。 #### 2.2.3 接続方式と保護回路 CT二次側を整流せず、バーデン抵抗R8(30$\Omega$)の両端をADS1115の差動入力に直接接続する。 **クランプダイオードの要否:** ADS1115の絶対最大入力電圧はVDD+0.3V(=3.6V)である。最大電流40AにおけるCT二次側最大電圧は0.667Vであり、絶対最大定格3.6Vに対して十分小さい。**クランプダイオードは不要**である。 ADS1115データシートの推奨に従い、入力ラインに電流制限抵抗(R_s)を両側に配置する。 変更後の回路構成(CHA): ``` CT二次側 ├─(+)─ R_s(33$\Omega$) ─── AIN0(+) R8(30$\Omega$) ← 継続使用 └─(-)─ R_s(33$\Omega$) ─── AIN1(-) ``` **既存部品の扱い:** | 部品 | 現用途 | 変更後 | |------|--------|--------| | R8 (30$\Omega$) | バーデン抵抗 | 継続使用 | | D5/D6 (1N5817) | 両方向クランプ | **削除**(不要) | | R7 (1k$\Omega$) | 直列抵抗 | **33$\Omega$に変更**してR_sとして流用 | | 電流B側 D/R相当 | 同上 | 同様に変更 | | D1/D2, R3 | 電圧CH(GPIO34) | 変更なし | | D3/D4, R6, R1 | 周波数CH(GPIO36) | 変更なし | **AIN1側追加部品:** | 追加部品 | 値 | 備考 | |----------|----|------| | 直列抵抗 | 33$\Omega$ | AIN1とCT二次側低電位端の間に挿入 | | CHB AIN3側も同様 | 同上 | 対称構成 | **R_sを33$\Omega$とする理由:** ADS1115のGAIN_FOUR設定での入力インピーダンスは約1.5k$\Omega$である。 $$\text{減衰率} = \frac{R_{in}}{R_s + R_{in}} = \frac{1500}{33 + 1500} \approx 98\%$$ 33$\Omega$であれば減衰は約2%であり実用上問題ない。 #### 2.2.4 I2C配線 | ADS1115ピン | 接続先 | |------------|--------| | VDD | 3.3V | | GND | GND | | SCL | ESP32 GPIO22 | | SDA | ESP32 GPIO21 | | ADDR | GND(I2Cアドレス: 0x48) | | ALRT | 未接続 | **I2Cプルアップ抵抗:** GPIO21/22に4.7k$\Omega$をVCC(3.3V)に対して追加する。 --- ## 3. B. ソフト変更 ### 3.1 変更の基本方針 - v4スケッチ(EMAフィルタ・OUTPUT_INTERVAL=5秒・Vref外れ値クリップ・EMAリセット)を**ベース**とする - 電流読み取り部のみADS1115対応に変更する - デュアルコア化・FreeRTOSタスク分離は**将来拡張**とし、今回は実施しない - コアの変更量を最小化し、既存の動作実績のあるロジックを最大限流用する ### 3.2 追加ライブラリ ``` Adafruit ADS1X15 ライブラリ(Arduino Library Manager より導入) 依存: Adafruit BusIO ``` ### 3.3 変更箇所一覧 | 変更箇所 | v4スケッチ | v5スケッチ | |----------|-----------|-----------| | グローバル変数 | `volatile float Irms_A_sum` 等 | ADS1115オブジェクト追加 | | `setup()` | ADC初期化のみ | ADS1115の初期化・連続変換開始を追加 | | `sampleData()` ISR | GPIO32/33をanalogRead | **電流読み取りを削除**(ISRからI2C不可のため) | | 電流読み取り | ISR内 | `aggregateAndSend()`内で`getLastConversionResults()`呼び出し | | `aggregateAndSend()` | ESP32 ADCの積算値からRMS計算 | ADS1115からの生値を用いたRMS計算に変更 | | K定数 | `KC_A`, `KC_B` | `K_A`, `K_B`に整理(校正後に確定) | ### 3.4 ADS1115の動作モード **連続変換モード(Continuous Conversion Mode)を採用する** - ADS1115は設定後、自動的に変換を繰り返す - `getLastConversionResults()` は最新の変換結果を即時返す(I2Cで約40μs) - `aggregateAndSend()` の呼び出し毎(5秒間隔)に複数回読み取り、積算する **制約事項:** 2チャンネルを順次読むと実効430 SPS相当になる。60Hz商用電源に対して約7サンプル/サイクルとなるが、SNRの大幅改善(26倍の分解能向上)がSPS低下を上回ると判断する。 --- ### 3.5 電流換算係数の構造(修正版) ADS1115導入後の電流換算式: $$I_{rms} = \sqrt{\frac{1}{n}\sum i_{raw}^2} \times K$$ 係数Kの工学的構造: $$K = \frac{LSB}{R_{burden}} \times N \times \frac{1}{\sqrt{2}} \times k_{cal}$$ | 要素 | 値 | 意味 | |------|----|------| | $LSB$ | 31.25μV | ADS1115の1カウントあたりの電圧(GAIN_FOUR) | | $N$ | 1800 | CTの変流比 | | $R_{burden}$ | 30Ω | バーデン抵抗 | | $\sqrt{2}$ | 1.414 | 正弦波のピーク/実効値変換 | | $k_{cal}$ | 実測決定(**乗数**) | $k_{cal}=1$ のときのスケッチ出力 $I_{sketch}$ に対し、クランプメータ値 $I_{clamp}$ が何倍かを示す補正係数。CT個体差・バーデン抵抗誤差・ADS1115誤差の総合補正 | スケッチ上の実装(修正版): ```cpp #define LSB_V 0.00003125f // GAIN_FOUR時のLSB(V) #define N_CT 1800.0f // 変流比 #define R_BURDEN 30.0f // バーデン抵抗(Ω) #define K_CAL_A 1.0f // 校正後に実測値で更新(乗数) #define K_CAL_B 1.0f // 校正後に実測値で更新(乗数) // k_cal は乗数(/ ではなく *) #define K_A (LSB_V * N_CT / R_BURDEN / 1.414f * K_CAL_A) #define K_B (LSB_V * N_CT / R_BURDEN / 1.414f * K_CAL_B) ``` --- ### 3.6 電流校正手順(修正版) #### 第1回測定:K_CAL_A/Bの決定 K_CAL_A = K_CAL_B = 1.0f のままv5スケッチを動かす。 複数の負荷点でクランプメータ値 $I_{clamp}$ とスケッチ出力値 $I_{sketch}$ を記録し、直線フィットする: $$I_{clamp} = a \times I_{sketch} + b$$ 勾配 $a$ が $k_{cal}$(= K_CAL_A)である。スケッチのK_CAL_A/Bを実測値に書き換えて再ビルドする: ```cpp #define K_CAL_A 5.2176f // 実測した勾配 a(CH-A) #define K_CAL_B 5.3465f // 実測した勾配 a(CH-B) ``` --- ### 3.7 不感帯の設定(修正版) K_CAL_A/Bを設定したスケッチで再度複数の負荷点で測定し直線フィットする: $$I_{clamp} = a' \times I_{sketch} + b'$$ **このときの $b'$ はクランプメータ軸(実電流 A)のY切片である。** K_CAL補正後のスケッチ出力は実電流スケールと一致しているため、$b'$ をそのまま Def_A/Def_B に設定できる。 ただし以下の制約に注意する: - $b' < 0$ の場合(CH-Aの実測例: −0.0996A):物理的に意味のある不感帯ではない。小さな正値(0.02〜0.05A)を安全側として設定する - $b' > 0$ の場合(CH-Bの実測例: +0.0731A):この値以下をゼロとみなす。$b'$ を僅かに上回る値に設定する ```cpp // CH-A: 切片が負 → 不感帯として意味なし、安全側に小さく設定 #define Def_A 0.05f // CH-B: 切片+0.0731A → これを上回る値に設定 #define Def_B 0.08f ``` --- ### 3.8 電流読み取りの変更 現状の`sampleData()`はタイマー割り込みで1msごとに自動実行され、電圧・電流A・電流BをESP32 ADCで読み取っている。 ADS1115導入後は電流の読み取りをADS1115から行うため、`sampleData()`から電流に関する処理を削除する。 ```cpp // 変更後のsampleData() void IRAM_ATTR sampleData(void* arg){ int r = analogRead(arefPin); v_raw = analogRead(voltagePin) - r; vrms_sum += (float)v_raw * v_raw; sample_count++; // 電流A・電流Bの読み取りは削除 } ``` ADS1115からの電流読み取りは`aggregateAndSend()`内で行う。 ### 3.9 電力計算の方式 | 計算項目 | 方式 | |----------|------| | $V_{rms}$ | 現状維持(ESP32 ISRによる積算) | | $I_{rms}$ | ADS1115からの積算 | | $Watt$ | $V_{rms} \times I_{rms}$(PF=1.0固定) | --- ## 4. 変更前後の比較 | 項目 | v4(現状) | v5(改造後) | |------|-----------|-------------| | 電流分解能 | 実効約800μV(ESP32 ADC) | 31.25μV(ADS1115 GAIN_FOUR) | | 電流入力方式 | 半波整流シングルエンド | 全波差動(整流不要) | | 電流サンプリング | 1000 SPS(ISR) | 最大430 SPS(2CH交互) | | Vref依存 | あり(GPIO35を毎サイクル参照) | 電流CHは完全に排除 | | 電力計算 | $\sum v_i \cdot i_i$(同期積算) | $V_{rms} \times I_{rms}$(PF=1.0固定) | | Vref安定化 | なし | GPIO35に47μF追加 | | スケッチベース | v4 | v4ベース(変更最小化) | --- ## 付記: 将来拡張(今回は対象外) - **デュアルコア化:** Core 0にWiFi/Blynk/MQTT/NVS、Core 1にサンプリング・計算を分離。周波数ジッタの根本解消に有効 --- *以上*
Next Post Previous Post