Arduinoの言語環境は「C++」。 vsprintf()で
Arduinoの言語環境は「C++」。「C」とはちょっと違う。
オブジェクトにクラス、メソッド、継承・・・
・・・きちんと理解できていません。
例題を参考にしてごそごそと。
Win環境だと古~いBorland C++Builderが使い慣れている
んですが、Winという世界でのプログラムはマイコンを使い
こなす環境とは全く違います。
Arduinoでの「C++」らしい処理、こんなページを見つけました。
・日記/2020-06-18/Arduino で printf() を使いたい
クラス「Print」に対する実行関数を指定して、
「vsprintf()」で書式指定文字列を付加し、シリアル出力や
液晶表示を行うという手法です。
・・・なるほどです。
シリアル出力と先日のI2CインターフェースのACM0802液晶 を
使って動きを確かめてみました。 (スペースに全角使ってます)
// Wireと液晶制御のヘッダーファイル
#include <Wire.h> // I2C
#include <j3LCD_ACM0802_I2C.h> // LCD制御ヘッダーファイル
// LCDという名を指定するとともにI2Cアドレスを指定
j3LCD_ACM0802_I2C LCD(0x3C); // I2Cアドレスを設定
// クラス「Print」へのポインタ 2つ TxとDispという名で
Print *Tx = &Serial; // シリアル出力
Print *Disp = &LCD; // 液晶表示
/***** セットアップ *****/
void setup(){
Serial.begin(9600); // シリアル通信
Wire.begin(); // I2C開始
LCD.begin(8, 2); // 液晶開始 文字数と行数
}
/***** LOOP *****/
void loop(){
long t, tn;
Serial.println(F("Tx TEST")); // タイトル表示
LCD.print(F("DispTest")); // 「.print」を使ったいつもの書式で
t = millis() / 100L; // 0.1秒
while(1){
tn = millis() / 100L;
if(t != tn){ // 変化?
t = tn;
Tx->println(t); // 0.1秒ごとにシリアル出力
LCD.setCursor(0, 1); // 液晶表示位置
Disp->print(t); // 「->」でオブジェクトに対するprint実行
}
}
}
Serial.println()とLCD.print()と同じことが、「->」という記述で
実行できます。
これを使って、vsprintfです。
/***** Printクラスへの書式付シリアル出力 *****/
// *cp : &Serial &LCDなど実行する関数のアドレスを入れるポインタ
void cpPrintf_P(Print *cp, const char *s, ...)
{
va_list vp;
char bff[40]; // バッファを確保
va_start(vp, s);
vsnprintf_P(bff, sizeof(bff), s, vp); // PSTRで書式を指定
cp->print(bff); // cpへ出力
va_end(vp);
}
実際使うのは「vsnprintf_P」。
「n」付でバッファのオーバーランを避け、
「_P」付で書式指定文字でのRAMエリア増大を防いで、
という処理です。
先ほどの出力している3行、こうなります。
cpPrintf_P(&Serial, PSTR("%ld.%ldsec\r\n"), t/10, t%10);
LCD.setCursor(0, 1);
cpPrintf_P(&LCD, PSTR("%6ld.%ld"), t/10, t%10);
書式付指定できるので1秒桁と0.1秒桁の処理が簡単に済ませられます。
ただ、毎回「&Serial」「&LCD」を付けるのが面倒かとも。
2種類しか使わないのなら、それぞれへ出力する、
「TXprintf_P」と「LCDprintf_P」を別個に作っておくほうが
(ちょいプログラムのスペースが無駄にはなるけど)
良いかなぁとも思います。
※関連
・2018年2月20日:「vsprintf()」で数値出力を
・2021年7月7日:秋月のI2C液晶表示器 ACM0802C-NLW-BBW-IIC 文字表示ライブラリ
| 固定リンク
「Arduino」カテゴリの記事
- 初めて買ったArduino UNO・・・今は(2023.05.25)
- 液晶表示コントローラ HD44780で迎撃(2023.05.16)
- Arduino UNOで3相モーターを回す(2023.05.01)
- Arduino サーミスタを使った温度測定で 【ゼロ除算問題】(2023.03.23)
- A/Dコンバータでサーミスタの抵抗値を読む サーミスタをつなぐ場所は?(2023.03.21)
コメント