今回からWindows側プログラムの説明。基本は温度センサーの場合とほぼ同じだが、色々細工を加えた部分が多いので、順に説明してゆきたい。まずはプログラムソースと実効ファイルをまとめたもの(WattMeter.zip)を用意したので、これをダウンロードしていただければと思う。以下の原稿は、これをダウンロードし、ソースなどの当該箇所をエディタなどで開いているという前提で説明してゆく。
■ダウンロードはこちら
「WattMeter.zip」
まずリソースファイル系に関しては、以前の温度センサー向けと全く一緒である。Visual Studio.NET 2010 Professionalならば.rcファイルから直接メニューの作成やresource.hの生成が可能だが、Expressのみの方は.rcファイルと、やはりzipファイルに含まれているresource.hを利用して頂ければ画面が構築出来るはずだ。
で、肝心のWattMeter.cppである。今回は珍しく、_tWinMain()にも手を加えることになった。これは、コマンドラインパラメータを受け取るためのものである。「え、iniファイルやレジストリじゃないのか?」と言われてしまいそうだが、これにはちょっと理由がある。
前回までで説明した通り、WattMeterからデータを取り込む際には、電圧/電流を示す値を実際の電圧値/電流値に変換するための係数が必要になる。悪いことに、この値はどのWattMeterを、どのArduinoのどのAnalogポートに繋ぐか、で微妙に変わってくる。このため、複数のArduinoを用意して、それぞれ別のWattMeterに繋いでサンプリングといったシーンを考えた場合、複数のWindows側のプログラムが同時に動く事になる。勿論この事そのものは問題ない(Arduinoはそれぞれ別々の仮想COMポートに割り当てられるからだ)のだが、問題はこのケースでは、それぞれ別の係数がそれぞれのプログラムに必要になるという事だ。これをiniファイルあるいはレジストリで対応する場合は、スマートな方法なら「Profile」の様なものを複数持てるようにして、どのプロファイルを使うかをプログラム中で指定する、といったアプローチが考えられるし、もっと乱暴なやり方としてはCOMポートと係数を関連づけ、例えば「COM5で通信する場合は係数が0.648と0.097」みたいに決め打ちにすることも出来なくは無い。ただ前者はちょっと面倒だし、後者は柔軟性に欠ける。もっと簡単なアイディアは? ということでコマンドラインインターフェースを使うことにした。要するに起動の際に、後ろにパラメータを付加する形だ。
このやり方だと、プログラムのショートカットを作っておき(Photo01)、ここにパラメータを付加すれば良い(Photo02)。複数起動の場合は、ショートカットを名前を変えて複数作っておき、それぞれに異なるパラメータを書き込んでおけば済む。
ここで指定するものはCOMポート、電圧側係数、電流側係数の3つである。一応何も指定しなくても起動できるように、最初に、
#define DEF_COM_PORT 4 // デフォルトはCOM5:
#define DEF_COEF_VOL 0.646 // 電圧の変換用係数初期値
#define DEF_COEF_AMP 0.097 // 電流の変換用係数初期値
というデフォルトパラメータは用意しておく。さて、_tWinMain()の中身であるが、まず最初に引数のlpCmdLineの値をチェックする。これがNULLなら引数なしなので、そのままデフォルトパラメータで動作するが、NULLで無い場合はswscanf_s()を使ってこの引数をParseする(sscanf_s()でないのは、これがwide char型のポインタであるLPTSTR型で渡されるためである。このためswscanf_s()の第二引数もTEXT()マクロを使ってwchar型に変換している)。パラメータとしては、最初に0~15の数字が来ることを想定しており、0ならCOM1:、1ならCOM2:、という具合にCOM16:まで対応する。次に電圧と電流の変換係数が2つ来る事を想定しており、これが正しくParseできない場合はデフォルトパラメータが利用される。
ここまで書くと判る方も居られるかもしれないが、起動方法としては、
(1) WattMeter.exe
(2) WattMeter.exe 1
(3) WattMeter.exe 1 0.1 0.2
の3パターンが利用可能である。(1)の場合はCOMポートを含めて全てデフォルト値で起動し、(2)はCOMポートのみ変更され電圧/電流係数はデフォルト値、(3)だとCOMポート/係数ともに引数にあわせて変更される形だ。これにあわせて、Coef_Vol/Coef_Amp/portIndexの各変数は、グローバルに置いた。
(続く)