商用の系統電力において発送電システムが崩壊し停電を引き起こす「ブラックアウト」。本連載では、製作費数円程度の自作プローブを使ってブラックアウトを予測するシステムの構築を試みる。第3回は、第2回で製作したACプローブをArduinoに接続して商用電源の周波数を計測してみる。
今回は、前回製作したACプローブをArduinoに接続して、AC電源の周波数計測、PCへのデータ記録、時系列の周波数変化のグラフ化までをやってみたいと思います。
前回記事を公開した後、ACプローブのフォトカプラの逆電圧保護について、読者の皆さまからさまざまなご意見を頂戴いたしました。これに併せて、前回記事の該当箇所に追記を行っております。
本件については、以下に挙げる東芝デバイス&ストレージ発行のフォトカプラアプリケーションノート「トランジスタカプラの基本特性と応用設計」を引用する形で、あらためて補足しておきたいと思います。
逆電圧保護
発光ダイオードに逆方向サージ電圧が加わる場合は、以下の図のように発光ダイオードにSiダイオード(例えば、1SS352または可視および赤外発光ダイオード)を逆並列接続し、発光ダイオードに逆耐圧以上の逆電圧が印加されないようにします。
「トランジスタカプラの基本特性と応用設計」の6ページ目から引用
図1で今回の実験に用いる機器の構成を示します。
前回作成した、AC100Vの波形を取り込むACプローブはオープンコレクターでArduinoに接続します。
Arduinoではプローブから得られた信号を基にAC100Vの周波数を求めます。現状では1分間に1回周波数を計測することを想定しています。
計測した周波数の値はUSBケーブル経由でPCに送られます。PC側ではいったんデータをファイルに落とし、表計算ソフトなどを用いて周波数の変化をグラフ化します。
図2では、ACプローブにArduinoを接続した状態を示しています。
ACプローブからは、フォトカプラ内のフォトトランジスタのコレクター側とエミッター側に接続されたリード線が2本出ています。
ACプローブから出ているリード線は、LANケーブルの中にあるUTPケーブルのワンペア分を流用しています。これの良いところはブレッドボードと相性が良くて、被覆を剥がせばそのままブレッドボードのホールに具合よく刺さるところです。
さて、UTPケーブルは単色の線とその単色+白のストライプになっている線の2本がねじり合っています。差動信号を送る際、単色の方がネガティブ、ストライプの方がポジティブになります。今回もこれと同じ流儀で、ストライプの方をコレクター、単色の方をエミッターにしています。
エミッター側をArduinoのグランド(GND)に、そしてコレクター側は2番ピンに接続します。2番ピンは後述のプログラムで入力に設定し、内部でプルアップするよう設定します。
リスト1はArduinoで動作するAC電源の周波数を計測するプログラムです。
1:// AC Frequency measurement 2:volatile unsigned long now,prev,counter=0; 3:void setup() { 4: pinMode(2, INPUT_PULLUP); 5: attachInterrupt(digitalPinToInterrupt(2), count, FALLING); 6: Serial.begin(9600); 7:} 8: 9:void loop() { 10: if (counter==0){ 11: Serial.println(now-prev); 12: prev = now; 13: delay(20); 14: } 15: } 16: 17:void count(){ 18: counter++; 19: if (counter==3600) { 20: now=micros(); 21: counter=0; 22: } 23: }
2行目で割り込み処理に関わる変数をvolatile宣言しています。prevはその必要はないのですが物はついでということもありますので。
3〜7行目までがsetup関数でこのプログラムが起動して1回だけ実行される関数です。
4行目で2番ピンを入力ピンとし、マイコン内部でプルアップ設定を行っています。
5行目で割り込み設定を行っています。何番ピンのイベントに対する割り込みなのか(2番ピン)、イベント発生時に呼び出される関数名(count)、そして割り込みを発生させるイベントの種類(2番ピンに入力された波形の立ち下がり)を設定しています。
6行目では仮想シリアルポートを用いてPCと通信するので、その設定を行っています。通信速度は9600bpsです。
9行目からはloop関数なのですが、先に17行目から説明します。
17〜23行目まではcount関数です。これは割り込みが発生したときに呼び出される関数です。
18行目でcounterを+1します。これはAC電源のパルス数をカウントする変数です。2行目で宣言しています。
19〜22行目まではif文のクローズですが、counterが3600になったら現在時間をμs単位で変数nowに保存し、counterを0にリセットします。
以上が割り込み時に行う処理になります。
さて、9行目からのloop関数にもどります。
10〜14行目がif分のクローズとなります。
11行目で、もしcounterの値が0なら、割り込み関数内で記録したその時点の時間から前回の割り込みが発生した時間の差を取ってその値をPC側に送信します。
12行目でprev変数に割り込み発生時の時間(now)を代入します。
13行目で20msほど待ちます。これは16.6ms、すなわち次のAC電源のパルスが来るまでにloop関数が呼ばれる可能性があるからです。16.6ms以上間をあける必要があるので、余裕を持って待ち時間を20msに設定しました。
Copyright © ITmedia, Inc. All Rights Reserved.