『Arduino側の時計、温度情報をシリアル通信で送受信しつつ、Processingでアナログ時計に加え、日付時刻、温度をデジタル表示』してみるページ。
Lチカ、グラフプロットに続くArduinoとProcessing連携第3弾。
ProcessingだけでもPCの日付時刻情報を元に時計の実装はできるわけですが、ここでは、Arduinoに接続したRTCモジュールと温度センサモジュールの情報を使い、シリアル通信については、Firmataライブラリを利用せず、ハンドシェイク式としました。
今回は、公式サイトのProcessing 3+用clock example、前回のグラフプロットをベースとさせて頂き、PCシステム時計からではなく、シリアル通信したArduinoからの日付時刻からアナログ時計とデジタル時計に反映、加えて温度表示、背景画像の挿入と、これらに伴う微調整を行ないました。
配線も一目瞭然なスケッチは後述するとして回路として必要になるハードウェアは、ArduinoボードとRTCモジュール、温度センサ、ブレッドボードを各1個とジャンパワイヤだけ。(もちろん、USBケーブルとPC、Arduino IDEもしくは代替も要るけど。)
今回は、RTCモジュールに余っていたDS1302、DS3231と違い、これには温度計機能がないため、温度センサには、37センサーキットに入っていたアナログ・デジタル両対応の温度センサを使い、デジタル値を送信することにしました。
37センサーキットには、温湿度センサモジュールもありますが、他で使っているため、残り3つある温度センサの内、先のものを使うことにしました。
必要なソフトウェアは、Arduino IDEか代替とProcessing。
Arduinoのスケッチは、後段リンクにもある前回のArduinoとProcessingによるグラフプロットとDS1302購入時に動作確認時に使わせて頂いたライブラリをベースとさせて頂きました。
int型のyear()をシリアル送受信するにあたり、変に混乱したくなく、ビットシフト(演算)は回避したいなと思っていたら、ビットシフトを説明しつつ、Arduino側で小数点以下切り捨てる整数型の変数に0-1023のアナログ値/256(仮にA)、アナログ値%256(仮にB)の結果を個別に入れて送信、Processing側で整数値としてA*256+Bのように計算すれば同じことができるというアナログ値分割情報を公開されていたので拝借、年の値に流用。
当初、Arduino側で日付時刻の表示用加工([/]や[:])したものを1セットとして一度に送ろうと考えていましたが、結果、加工はProcessing側で行なうことにしました。
Processing側のスケッチは、公式サイトのProcessing 3+用アナログ風時計サンプルと、やはり、後段リンクにもある前回のArduinoとProcessingによるグラフプロットをベースとさせて頂きました。
全体的に変数宣言に統一感がなかったりしますが、気にしないことにし、当然、背景画像も使えるよね?と思っていたことから、[PImage]型変数を使い、とりあえず、GIMPで作った背景画像を設定、日付時刻データは細切れで受信し、[/]や[:]を入れる加工は、Processing側で行なうことにしました。
尚、背景画像に使う画像の保存形式は.jpgはいけましたが、.pngはダメでした([2018/03/22:訂正・追記]RGB LEDデモでは.pngでもいけた)、また、size()指定したポップアップ画面のサイズと画像サイズはピッタリ同じにする必要がありました。
もし、このスケッチを使う場合、針の色や文字色が白なので、針や文字の色を変更するか、濃いめの背景色を設定するか、これらを識別できる色合いの背景画像を用意するなどしないと何も見えなくなるので注意。
ここで対象になるのは、温度の[℃]のみですが、Processingにおいてスケッチ上やポップアップ画面上で日本語表示する場合には、[ファイル] => [設定...]で[言語:]を[日本語]、[エディターとコンソールのフォント:]を[IPAゴシック]など日本語表示対応フォントに設定しておく必要がありました。
今回のハマりポイントは、JavaやProcessingではお馴染みらしき[NullPointerException]、結果、String型宣言した変数を初期化していなかったことが原因と判明、初期化で解決。
ちなみにArduinoとProcessingでシリアル通信、送受信データを参照しているスケッチにおいて、受信データの格納に配列を使っている場合、配列要素数が少なかったり、多かったりした場合や、Arduino側(シリアルポート)の準備ができていないとか、指定したシリアルポートが異なる状態でProcessingのスケッチを実行した場合もエラーの1つとして[NullPointerException]は起こり得るようです。
実用的とは言えませんが、タイムリーな日付時刻もシリアル通信で十分送受信できることがわかりました。