ESP32入門 通信機能が標準搭載されたマイコン・ボード (9)の補足説明
●snprintf()の使い方
ESP32マイコン・ボードとWi-Fi経由でWebブラウザで通信を行うプログラムを「ESP32入門 通信機能が標準搭載されたマイコン・ボード」の記事で紹介しました。その中で9回目の、測定した温度をWebに表示①の記事で使用したsnprintf()関数の使い方について読者から質問がありました。
ESP32入門 通信機能が標準搭載されたマイコン・ボード (9) 測定した温度をWebに表示① https://www.denshi.club/cookbook/arduino/esp32/esp32-9-web.html |
この記事で利用したsnprintf()について具体例をもとに説明します。まず規格を調べます。JISのC言語の規格のsnprintf()関数は次のように規定されています。
●JIS規格のsnprintf
JISのC言語の仕様書 JIS X 3010 :2003にsnprintf関数が次のように定義されています。
◆形式 ◆機能 ◆返却値 |
●筆者の解釈
規格書の記述は少々わかりにくいので、実際にこの命令をArduinoのプログラムの中で利用して記述するときに、筆者がどのような思いで記述しているかまとめてみます。
◆書式
書式にある#include <stdio.h>の記述は、Arduino IDEのコンパイラが対応していますから、Arduino IDEで利用するときは記述を省略できます。
snprintf(文字列配列、最大文字数、フォーマットの文字列、変換指定子対象の変数); |
文字列配列 : 変数を変換指定子の指定に従い変換し、文字列で設定された見出しを含めて新しい配列を構成し、第一の引数で指定した文字列配列に設定する。 最大文字数 : 配列に設定する文字数の最大値を設定する。この値は配列の大きさを超えない値とする。 フォーマットの文字列 : 説明や見出しなどと変換指定子が組み合わされたフォーマットを指定するための文字列。変換指定子は次に続く変換対象の変数と対応している。 変換指定子対象の変数 :変換指定子の変換対象となる変数で、変数の数は変換指定子の数に対応している。 |
フォーマットの文字列の中で設定する書式は「JIS X 3010 :2003」の7.19.6.1 fprintf関数(p.198)の説明を参考に、書式の設定方法を以下にまとめました。
書式の設定方法 : 変換の書式は次のようになります。
% フラグ フィールド幅 精度 長さ修飾子 変換指定子 |
変換指定の最初は % の文字から始まる。続く各項目は次のような役割を担う。 ◆フラグ (省略可能、複数設定可) - : 変換結果を左詰めに表示する。この指定がないと右詰めになる ◆フィールド幅(省略可) 数値 : 変換結果の最小フィールドを指定します。文字数が指定より少ない場合、0または空白で埋められる。また、文字数が指定より大きい場合はこの指定は無視され、変換された結果を表示する。 ◆精度(省略可) .n : フィールド幅の次に小数点と精度を示す数値を設定する。変換指定子ごと ◆長さ修飾子(省略可) 実引数の大きさを指定する修飾子。この修飾子の意味は次のようになる。 ◆変換指定子 d、i : 10進数で出力する ◆restrict ポインタに対する修飾子。このrestrict修飾子で指定されたポインタは同一のオブジェクトに対して複数のポインタを介してアクセスすることがないように記述されていて、プログラムの最適化が行われても不都合がないことをコンパイラに示すためのものです。上記の条件を守る責任はプログラマにあります。またこの修飾子はコンパイラに対する指定でプログラムの動作に関しては何ら影響を与えません。プログラムの動作を考えるときはこの修飾子はあってもなくても同じです。 |
以上の規格のまとめに従い、次の項目でWebブラウザに表示するためのデータ作成を行っているsnprintf()関数について説明します。
ESP32入門 通信機能が標準搭載されたマイコン・ボード (9) 測定した温度をWebに表示① https://www.denshi.club/cookbook/arduino/esp32/esp32-9-web.html |
●実際の関数の記述
この関数の3番目の引数の”<html> から </html>“までが、書式を決める文字列です。
snprintf(temp, 400,
"<html>\ // ブラウザで表示するためのHTML文書の開始を示す
<head>\ // 次のhttp-equiv='refresh'で自動更新が指定されている
<meta http-equiv='refresh' content='3'/>\ // 間隔は3秒に設定されている
<title>Denshi Club ESP32 test</title>\ // 文書のタイトルで画面には表示されない
<style>\ // バックグラウンドのカラー・コード、フォント、文字の色を指定
body{background-color:#40e0d0;font-family:Arial,Helvetica,Sans-Serif;Color:#000000;}\
</style>\
</head>\
<body>\
<h1>Temperature from ESP32</h1>\
<p>Uptime: %02d:%02d:%02d</p>\ // 経過時間の書式
<p>Temperature: %8.2f</p>\ // 温度の書式
</body>\
</html>",
hr, min % 60, sec % 60, //経過時間の実引数
tvalue // 測定温度の実引数
);
●測定データの表示の仕様を決める
次のUptimeは見出しでは、その後の%02dが時間の表示をフラグが0でゼロ・サプレス、フィールド長を2桁で、変換指定子がdで十進数表示を指定しています。時分秒の間に分離のための:が挿入されています。書式は同じ指定となっています。
次の行のTemperature:は温度測定の見出しでは、フィールド長が8桁、精度が2桁で実数表示のfの変換指定子で書式が設定されています。
<p>Uptime: %02d:%02d:%02d</p>\
<p>Temperature: %8.2f</p>
対応する実引数が、書式の文字列の引数の次の引数として設定しています。
●実行結果
実行結果について、経過時間は2桁の時:分:秒で表示され、温度は小数以下2桁の実数値として表示されています。
経過時間の表示の値が1桁の場合ゼロ・サプレスが行われていなく空白のようです。テスト時には気づかず確認が漏れていました。現在システムをばらしているので、再度組み立ててArduinoの仕様なのか確認します。
(2020/4/18 V1.0)
<神崎康宏>