のっけからいきなりソース訂正。これまでのプログラムだと出力ログが

12:49:30 30.0	30.3	30.3	30.4	30.1	30.2
12:49:31 30.0	30.3	30.3	30.4	30.1	30.2
12:49:32 30.5	30.3	30.3	29.9	30.1	29.7

という風に出ますが、これをExcelに取り込むとPhoto01の様になってしまい、具合がよろしくありませんでした。

Photo01: お恥ずかしい話ながら、この原稿を書き始めるまでログを直接Excelに取り込んでなかった(muleの上で一度編集してからコピーしてた)ので気が付きませんでした。

これはログファイル生成時に、

// もう一度ansiBufを使いまわしてログファイル用文字列生成
sprintf_s(logFileStr, BUFSIZE,"%02d:%02d:%02d %s\t%s\t%s\t%s\t%s\t%s\r\n",
			       nowTime.tm_hour, nowTime.tm_min, nowTime.tm_sec,
			       tempBufStr[0], tempBufStr[1], tempBufStr[2],
			       tempBufStr[3], tempBufStr[4], tempBufStr[5]);

と、日付と温度のフィールドの間をスペースで埋めていたのが原因で、これを、

// もう一度ansiBufを使いまわしてログファイル用文字列生成
sprintf_s(logFileStr, BUFSIZE,"%02d:%02d:%02d\t%s\t%s\t%s\t%s\t%s\t%s\r\n",
			       nowTime.tm_hour, nowTime.tm_min, nowTime.tm_sec,
			       tempBufStr[0], tempBufStr[1], tempBufStr[2],
			       tempBufStr[3], tempBufStr[4], tempBufStr[5]);

とタブに置き換える事で、Excelでも正常に取り込むことが出来る。ということで修正版はこちら(TempSensor.zip)です。

Photo02: 修正するとこんな感じに。

さて、プログラムの残りの部分にはそれほど説明は要らないかと思う。ログファイルの指定は、素直にコモンダイアログを呼び出すことにしている。これはあらかじめLPOPENFILENAME型の構造体に必要なパラメータを格納しておき、これを引数にGetSaveFileName()を呼び出すことで実現できる。戻り値がBOOL型なので、Saveをキャンセルしたとか存在しないファイル名を指定した場合は、FALSEが返ってきてすぐに判断できる。またGetSaveFileName()が成功しても、その後CreateFile()に失敗した場合は、saveFlagをTRUEにしない、ということで対応が可能である。

これに続くセクションは、Settingメニューの各項目のMessage処理であるから、それほど難しい話ではない。WM_PAINT Messageに関しては、「画面更新を行いたい場合はInvalidateRect()を呼び出す」という実装にしているから、timeStr/tempStr/settingStrの各文字列バッファから文字列を取得し、毎回フォントを設定しながらそれぞれの文字列描画をDrawText()で行い、最後にEndPaint()を呼び出すことで描画が開始されるという訳だ。

という訳で、以上で一通り実装の説明は終了である。ちなみにこの実装では、RS232Cポート経由でのデータ取り込みと、ログファイル書き出しをさせていない。だから、例えばRS232Cで取り込み開始→ログファイルに書き出し開始→RS232Cで取り込み終了という手順をとっても、引き続きログファイルには書き出しが行われ続けている。これに関しては、RS232Cの取り込みを終了した時に、一緒に強制的にログファイル書き込み終了にする実装も考えたが、これだと一時的に記録を中断すると、次に再開するときにもう一度ファイルの保存ダイアログが出てしまう事になる。一つアイディアとしては、WMTIMERのMessageでwParamがTIMERID2の場合に、SaveFlagがTRUEの場合でもtransferFlagがFalseだったらWriteFile()(や、その前のSetFilePointer())を呼ばない、という実装はありえるだろう。このあたりは読者の好みで変更していただければと思う。

さて、これで終わってもいいのだが、実際に測定結果などをちょっとご紹介してみたいと思う。とりあえず手持ちのRADEON HD 6850を用意し(Photo03)、ここのブラケット(Photo04)、GPU下側のヒートシンク(Photo05)、GPU上側のGDDR5チップ(Photo06)、基板裏面のちょうどGPUあたり(Photo07)、ファンのカバー(Photo08)、及び外気温を測定してみることにした。このRADEON HD 6850をCore i7-2600K+Intel Z68マザーボードの環境にインストール(OSはWindows 7 64bit SP1 日本語版)し、この上で3DMark11をPerformance Profileで実行し、その際の温度変化を測定した。同時にGPU-Z 0.3.5を使い、GPU内部のTermal Sensorの温度も記録している。

Photo03: DX11世代のカードが1枚は無いと不便、ということで値段につられて購入したAFOXのAF6850-1024D5H1

Photo04: ブラケットの排気口付近にガムテープで固定

Photo05: カバー下側からセンサーをもぐりこませ、ヒートシンクと接触するようにした。

Photo06: こちらはカバー上からもぐりこませ、GDDR5チップに接触するように。

Photo07: GPUのちょうど真裏あたりにガムテープで固定。

Photo08: 一応カバーの温度も測定ということで、やっぱりガムテープで。

結果は? というと、グラフ1がGPU-Zの、グラフ2が今回の温度センサーを使っての温度となる。コア温度とヒートシンク温度が連動しないのはまぁ当然で、また山の位置がずれるのも仕方ないのだが、もう少し精度というか、何とかならないかな?というのがグラフ1と2を見比べての感想である。理由は簡単で、やはり温度センサーが結構大きいので、ガムテープで固定しても接触が悪く、うまく温度を測定しきれていない。何かしら、銅板などをつかってガイドを作ったほうがいいな、というところだが、さすがにこうした加工はそろそろMCUの範疇からかなり逸脱してきている気がするので今回は割愛する。とりあえずセンサーの周りに軽くアルミホイルを巻いて測定対象と接触させると、若干温度測定結果が改善したことだけは書き添えておきたい。

グラフ1:

グラフ2: