ArduinoでIoTにチャレンジ<その7> Arduino MKR WiFi 1010に接続されたセンサからのデータをWebブラウザに表示する③
●測定値には来歴が必須
測定値はどこでいつ測定されたものかわかれば、格段に価値が上がります。測定値と測定時刻をセットにして記録表示することを検討します。このArduino MKR WiFi 1010にはRTC(リアルタイム・クロック)が内蔵され、WiFiNINAライブラリを利用してルータから正確な時刻を読み取りRTCの時刻合わせを行うことができます。
●RTCZeroライブラリ
現在時点の日時を、次の関数で取得すできます。
そのため、その時点の日時を得るための関数が次のように用意されていて、結果はバイト型の変数で受けることができます。時分秒のデータだけで1データ当たり3バイト必要になります。年月日まで含めると6バイト必要です。rtc. はRTCZeroライブラリのクラスから作成したインスタンスです。
rtc.getSeconds()
rtc.getMinutes()
rtc.getHours()
rtc.getDay()
rtc.getMonth()
rtc.getYear()
時分秒3バイトのデータを3000として、データ必要なメモリ量は3×3000で9000バイト必要となります。測定データの配列はfloat型で4バイトの大きさで3000データなので12000バイトとなり、配列のデータだけで21000バイトの容量となります。この状態でメモリにどの程度余裕があるかも確認します。
●時刻のデータを配列に格納
時刻のデータは2次元の配列timeary[n][i]に格納することにします。データはbyte型とします。nは0から2999まででデータのナンバを表します。iが0は秒のデータ、iが1は分のデータ、iが2は時のデータとします。配列の定義を次のように設定して、データの配列の後に記入しました。
float ta[3000];
byte timeary[3000][3];
Webブラウザに表示のための文字列の配列を二つ追加します。時刻の分秒をセットする配列をtary1とします。時の値を格納する配列をtary3とします。
char tary1[80]; 分秒のデータの表示値の文字配列
char tary2[80]; 測定データの表示値を格納する文字配列
char tray3[80]; 時のデータの表示値の文字配列
●データを読み込むタイミング
前回のプログラムは、Webブラウザに表示データを送信する直前のタイミングでセンサからデータを読み込み、画面の表示領域に埋め込んでいます。Webブラウザのリフレッシュの設定で、定期的に更新され同時にデータが読み込まれます。
ただしこの方法では、Webブラウザが表示されないとセンサのアクセスはありません。表示したときの測定結果があればよい場合はこれでもいいのですが、バッファにデータを蓄積する場合はブラウザのアクセスに関わらず測定する必要があります。
●定期的に処理するプログラム
long型の変数premillisには、前回センサの測定を行ったときの経過時間を示すmillis()関数の値がセットされています。(millis() / 1000 - premillis )の値は、前回の測定からの経過秒数になります。そのため、次のif文に指定した秒数10より大きくなると{}内の処理を行います。この{}内でpremillisに現在のmillis()関数の値がセットされるので、次に10秒の経過時間を経過しないと{}内の処理は実行されません。
==10にしないで>10にしているのは、タイミングによっては==この条件を取り逃がす場合があります。>にすると条件を逃すことはありません。
if (millis() / 1000 - premillis > 10) {
次の4行でセンサから測定値、RTCから時分秒の値をバッファに取り込みます。
ta[setp] = getlm75tempe(adr48);
timeary[setp][2] = rtc.getHours();
timeary[setp][1] = rtc.getMinutes();
timeary[setp][0] = rtc.getSeconds();
配列指標とpremillisの値を更新します。
setp = setp + 1;
premillis = millis() / 1000;
配列の上限(2999以上)に達したとき、初期値0に戻します。
if (setp > ENDP) {
setp = 0;
}
表示データを最新のデータから10データとしています。最新データの格納された配列の指標を更新します。
int wsp = setp - 1;
for (int i = 0; i <= 9; i++) {
arn[i] = wsp;
wsp = wsp - 1;
データの格納されている配列がリング・バッファになっているので、指標が最小値より少なくなったら最大値に戻ります。
if ( wsp < 0) {
wsp = ENDP;
}
}
}
●データをWebブラウザに表示する
時分秒のデータを文字列に変換するためには、次のように分:秒の組み合わせでフォーマット書式は%3d:%2dとしてtimeary[arn[0]][1]は分のデータ、timeary[arn[0]][0]は秒のデータとなります。
sprint(tary1,“%3d:%2d%3d:%2d ~ %3d:%2d“,
timeary[arn[0]][1], timeary[arn[0]][0],~ timeary[arn[9]][1], timeary[arn[9]][0]);
前回のプログラムにこれらの追加修正を行うプログラムをコンパイルして書き込みます。書き込んだプログラムの大きさは、次のようにArduino IDEの下の部分に表示されます。
表示内容は次のようになります。
最大262144バイトのフラッシュ・メモリのうち、スケッチが49668バイト(18%)を使っています。最大32768バイトのRAMのうち、グローバル変数が25804バイト(78%)を使っていて、ローカル変数で6964バイト使うことができます。
フラッシュ・メモリは18%しか利用していないから、まだまだプログラムを追加する余裕は十分あります。RAMの領域は8割近く利用しているので、追加して利用する場合には慎重に検討する必要があります。
Arduino UNOなどの場合にはこれだけ大きなバッファは確保できません。Arduino MKRシリーズを利用するメリットを強く感じます。
●実行結果
実行結果は、次のようになります。数字の表示が整数部分上位の0が表示される桁位置がそろいません。時、分の表示などを見やすく工夫する必要があります。
これらについてはArduinoのスケッチでなくHTMLの工夫が必要になります。任意の時間からの表示などWebブラウザの操作に関する検討を進めることを検討しています。
今回のテストしたプログラムMKRWiFiLM7506030を添付します。
(2022/06/09)
<神崎 康宏>