I2CインターフェースLCDモジュール用のライブラリを作る(6)機能の動作確認
■ライブラリのデバッグ(1)
今回作成したライブラリの基本的な動作の確認はできました。ライブラリに用意した機能の動作確認を行います。
public変数としては、クラスで次のコンテナと関数を定義しています。init_lcd2i()は以前使用していましたが、現在は使用していません。
i2clcd();
i2clcd(byte i2cadr);
i2clcd(byte lbr, byte i2cadr);
i2clcd(byte v5or33, byte lbr, byte i2cadr);
ここまでがコンテナで、i2clcdを実体化するためプログラムの最初に記述します。LCDモジュールへのコマンドの書き込み、表示データの書き込みを行うi2cwritecmd()、i2cwritedata()もpublicの設定となっているので、ライブラリ外のArduinoのスケッチからも利用できます。
int i2cwritecmd(byte cmd);
int i2cwritedata(byte data);
int i2cwritedsd(byte cltd, byte data);
void lcdcu_set(int x, int y);
void lcdclear();
void lcdhome();
void dsift_l();
void dsift_r();
void init_lcd();
void init_lcd2();
void i2cprint( String pdata);
privateの関数としてbyte chkcltdata(byte adr);が設定されています。この関数はコンテナで設定されたI2Cデバイス、LCDモジュールに関するデータから処理の手順を決める関数なので、利用者には知らせる必要がないのでprivateの設定にしてあります。
●テスト回路
テスト回路と最初のテスト・プログラムは「I2CインターフェースLCDモジュール用のライブラリを作る(4)ライブラリ化(3)」
で使用したものをそのまま利用します。
ブレッドボード上にAQM1602、ACM1602をそれぞれセットし両方に同じ値を表示し、シフト、カーソル操作などのコマンドのテストも両方に同じ操作を行い結果が同じになるか確認します。Arduino UNOを利用しているので、電源電圧両方とも5V電源で動作させます。
●テスト・プログラム
#include <i2clcd.h>
i2clcdのライブラリを呼び出します。Wireライブラリを使用していますが、Wireライブラリのインクルード、開始処理はi2clcdライブラリのコンストラクタの中で行っているので、このスケッチでは記述していません。
int n = 0;
整数変数nをカウントアップして、その値をLCDモジュールに表示します。ここでは変数の定義と初期値を0にしています。
i2clcd alcd;
引数のないi2clcdのコンストラクタを利用して、ACM1602のモジュールを制御するインスタンスalcdを生成します。ライブラリの中では、次に示すようにI2CのアドレスはACM1602の0x50、データ書き込みの制御コード0x80に設定しています。_br、_v5or33の値はACM1602では使用しませんが、不定にならないように初期化しています。その後、Wireライブラリの初期化を行い、コンストラクタの処理を終えています。
i2clcd::i2clcd() {
_addr = 0x50;
_cltdata = 0x80;
_br =0x13;
_v5or33 = 3;
Wire.begin();
}
---
i2clcd qlcd(0x3E, 5);
AQM1602のモジュールを制御するインスタンスqlcdを、I2Cのアドレスと電源電圧を指定して生成します。コンストラクタの中でアドレスを引数にしてchkcltdata()関数を呼び出し、AQM1602対応したデータ書き込み制御コードを_cltdataにセットしています。その後、電源電圧に応じた輝度の値を設定し、Wireライブラリの初期化を行っています。
i2clcd::i2clcd(byte i2cadr,byte v5or33) {
_addr = i2cadr;
_cltdata = chkcltdata(i2cadr);
_v5or33 = v5or33;
if (_v5or33 == 5) {
_br = 0x23;
}
else {
_br =0x13;
}
Wire.begin();
}
void setup() {
alcd.init_lcd();
qlcd.init_lcd();
}
それぞれのモジュールの初期化を行います。
void loop() {
alcd.lcdclear();
qlcd.lcdclear();
n = n + 1;
alcd.i2cprint(String(n));
alcd.i2cprint(":");
qlcd.i2cprint(String(n));
qlcd.i2cprint(":");
delay(1500);
}
●ほかの条件でのコンストラクタの確認
次のようにアドレスを指定し、ほかの引数を指定しない場合、
i2clcd alcd(0x50);
i2clcd qlcd(0x3E);
上段のACM1602はi2clcd alcd();と同様に適正な表示となります。一方下方のAQM1602の表示は、電源電圧を指定していないためデフォルトの3.3V電源で設定されているので、少し輝度が強くなりすぎています。
●表示位置を設定する関数
表示位置を設定するalcd.lcdcu_set(0, 1);で、同じ表示を下段の左端から表示しテストしました。結果は、次に示すように正しく表示されました。
●表示のシフト
alcd.dsift_r();で表示位置を右にシフトし、最後にalcd.dsift_l();表示位置を左にシフトして元に戻します。これでライブラリの関数をテストすることができます。
これらの処理を追加したプログラムは次のようになります。
上段に13の表示をしてから、alcd.lcdcu_set(0, 1)でカーソルの位置を下段の左端にセットすると、同じnの値13が上段と同じように下段に表示されています。
右側にシフトしスペースの後に13が表示されるはずが、反対に表示されました。
左にシフトするはずが右にシフトして、表示が元の13に戻りました。
●ライブラリの関数を修正
この関数では、右シフトでコマンド0x1C、L/Rビットを1にしてしまいました。左シフト・コマンドを誤って0x18とし、L/Rビットを0に指定しました。
void i2clcd::dsift_l() {
i2cwritecmd(0x1C);
}
void i2clcd::dsift_r() {
i2cwritecmd(0x18);
}
再度マニュアルを確認し、L/Rビットが右シフトの場合0、左シフトの場合1に設定しました。
正しい関数は次のとおりです。
void i2clcd::dsift_l() {
i2cwritecmd(0x18);
}
void i2clcd::dsift_r() {
i2cwritecmd(0x1C);
}
ライブラリのi2clcd.cppの修正を行い、再度テスト・プログラムを実行すると次のようになりました。
7:が表示されます。
右に1文字分シフトしました先頭はスペースです。
左にシフトして元に戻りました。
●ライブラリのエラーの場合
ライブラリにエラーがありコンパイルできない場合、次のようなメッセージが表示されます。
メッセージ欄に、エラーの場所などが表示されますが、見やすくないので「エラーメッセージをコピーする」をクリックしてエラー・メッセージをWORDなどに貼り付け確認しています。エラー・メッセージは次のような内容です。
「 Arduino:1.8.5 (Windows 10), ボード:"Arduino/Genuino Uno" C:\Users\alps_\Documents\Arduino\libraries\i2clcd\i2clcd.cpp: In member function 'void i2clcd::init_lcd()': C:\Users\alps_\Documents\Arduino\libraries\i2clcd\i2clcd.cpp:76:2: error: expected ',' or ';' before 'delay' delay(145); ^ exit status 1 ボードArduino/Genuino Unoに対するコンパイル時にエラーが発生しました。 「ファイル」メニューの「環境設定」から 「より詳細な情報を表示する:コンパイル」を有効にすると より詳しい情報が表示されます。」 |
i2clcd.cppのエラーの場所はbyte powercmd = 0の最後の;を入れ忘れてしまったときのエラーです。プログラムの修正を行うとつい;を忘れてこのエラーに遭遇しました。
次回、i2clcd.cppとi2clcd.hをzipファイルにします。
(2017/11/4 V1.0)
<神崎康宏>