京都に帰ってきて電子工作する元気が出てきたので、電源周波数の観測を始めてみました。
1分単位のグラフをChart.jsで描き、10分中央値*1グラフをVictoriaMetrics + Grafanaで描いています。
ハードウェア
関電(60Hz)
ESP32
ESP32のモータ制御機能MCPWMが持ってるインプットキャプチャ機能で測定しています。
回路図はこんな感じ。
LM393でヒステリシスコンパレータとオープンコレクタ使ったレベルシフトをしてます。繋いでるACアダプタはデジットで30円たたき売りされてたACアダプタ*2を割って、ダイオードとコンデンサを回路側に移設しています。ケースはダイソーで売ってた手芸アイテム入れを流用しています。
ESP8266
10月ぐらいにえいやと腰を上げて、ESP8266で測定するモジュールをダイソー充電器に仕込みました。ゼロクロス回路こんどは部屋に落ちてたTLP521とワンゲートシュミットトリガTC7S14を使って実装。
自由研究の延長戦をしてた pic.twitter.com/kxdncZRLXH
— "にょる。" (@W53SA) 2022年10月10日
シングルコアなので素朴にTCP通信をするわけにもいかず非同期通信を頑張ることに。インプットキャプチャもないんで、ゼロクロス回路からのハードウェア割り込みでCCOUNT
を読み出しています。
東電(50Hz) AVR
自分の実装に自信が持てなかったので、とものさんが書かれたAVR(ATTiny)による観測を自分でも組んでみました。
同じ測定対象を別ハードウェアで測り続けてもアレなので、東京でADS-Bを受信してるRaspberry Piに繋いでいます。
ソフトウェア
ファームはArduinoなどC系で、データを受けるあたりはGoで書きました。AVRでUARTから流し込まれるデータをアップロードするのはPython3で実装しています。
測定値はどれほど正しいのか
要素はクロック刻みによる精度とクロックそのもの正確度の2つに分かれるので、それぞれ議論していきます。
ESP32の場合はインプットキャプチャのカウンタを読み出す割り込みハンドラ、ESP8266の場合はCCOUNT
を読み出す割り込みハンドラ、とそれぞれ割り込みがCPU内でどんな扱いを受けているのか問題もあるんですけど考えると沼なのでいったん忘れる。
クロック刻みによる精度
ESP-WROOM-32のMCPWMインプットキャプチャおよびESP-WROOM-02のCCOUNT
レジスタどちらも80MHzでカウンタが回っています。
これを参考にして、80MHzと50/60Hzの値を入れてみると
で、これが何Hzの幅を持つのかを考える。
雑にまとめると、0.0001Hz 程度の精度という感じですか。
実際に50/60Hz近辺でカウンタの刻み毎に算出される周波数を表にしてみるとこんな感じなので、0.0001Hzでよさそうです。
これ以上細かい数字を取るにはカウンタを回す速度を上げることになります。ESP8266のCCOUNTはCPUクロックで回っているのでsystem_update_cpu_freq
をいじればいけそうだけど、ESP32はAPB_CLKなので外部に発信機つけるしかないのかもしれない?
XTALによる正確度
ESP-WROOM-02はデータシートによると「ESP-WROOM-02 uses a 26-MHz crystal oscillator. The accuracy of the crystal oscillator should be ±10 PPM.」らしい。ESP-WROOM-32はデータシートによると「The module uses a 40-MHz crystal oscillator.」だそうで精度情報がない。まぁ、同じようなものを積んでると考えていいんじゃないかなぁ。
XTALの発振周波数がWiFiの基準周波数にもなってるはずなのでTCXO使ってると考えて良さそう。teardownでぐぐってモジュール分解画像探してもそれっぽいし。
TCXO精度が一桁ppmらしい。なので測定値もそれぐらいの正確度をもっているのではなかろうか。
TODO
- 電圧測定もしたいな~
ESP32は正直オーバースペック感があるので、ESP8266でなんとかならないかな(インプットキャプチャないけど…。)
*1:最初は平均値グラフ描いてたけど、欠測時にグラフがおかしくなったのでやめた。
*2:型番からぐぐって見つけた「ニッポン放送対応防災ラジオ「セキュリオ」MHS-1242T USED ラジオとしても使用可ミュディーヒューマンサービス アダプタ(MHS-AD001)付き」と見た目が同じなので、たぶんこれ。