どうもメガネです。
今回はArduinoにてよく使われる表示器「LCDディスプレイモジュール」の最安クラス商品の紹介と、
ちょっと変わった表示をする方法を説明したいと思います。
現行(20210907現在)での最安商品のリンク等は一番下に作成したので、そちらだけを見たい人は以下の目次から参照してください。
LCDディスプレイについて
少しだけ超簡単な紹介をしておきます。
LCDディスプレイモジュールは以下のような小型のディスプレイで、Arduinoと接続して簡単に文字等を表示させることができます。
価格が液晶のくせにクソ安いのが特徴です。
結構いろいろな種類がありますが、「1602なんちゃら」とついていればほぼ同じしようと思っていいと思います。
上記画像では金属のカウルがあるものとないものがありますが、制御は同じコードで行うことができました。
(ピン配置が若干ものによって異なることがあるのでそこは注意です。)
金属製カウルが付いているものは若干サイズが大きくなりますが、ねじ穴などがM3のねじで止められたので結構便利でした。
Arduionoとの配線は多数の解説サイトにて紹介されているので詳細は省きます。
I2Cモジュールを必ず使おう
必ず、とは言ってますが、なくても使用することはできます。
ですがI2Cの通信をビット単位で操作したいというマニアや制御ハード製作をしたいというマニア以外はやめましょう。
ArduinoのI/Oポートと配線用コードが無駄になります。
無駄、は言い過ぎかもしれませんがまぁ、それくらい便利ってことです。
数十本の必要なコードが4本まで減ります。
今回は以下の商品を購入しました。
個人的に調べてお思いましたが、
I2Cモジュールを最初からLCDに接続して売っているタイプのものはコスパがだいぶ悪い傾向にあります。
2,3コ持っていたところで別に困るものでもないので私は複数個購入してストックしてますが、結構値段が二倍になったり半額になったりと変わってくるので確認しておきましょう。
プログラム
ArduinoとLCDディスプレイを表示した後に最低限設定として記述しなければならないコードを以下に載せます。
この手の記事で、「操作通り設定したのに動かない!」ということがあると思いますが、Arduinoの場合はライブラリが異なっていた、、
ということがよくあります。
ライブラリも確認しておきましょう。
使用したライブラリは<LiquidCrystal_I2C.h>です。違うと動きません。
最低限必要なプログラム
#include<LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,16,2); //ライブラリのインクルード
void setup() {
lcd.init(); //LCDディスプレイの初期化
Serial.begin(9600);
}
void loop() {
lcd.backlight(); //バックライトを点灯
lcd.setCursor(0,0); //カーソルを0,0にセット
lcd.print("Hello megane!"); //表示内容
}
上記のプログラムをアップロードし、無事「Hello megane!」が表示されれば問題ないです。
ただし一発でうまくいかない、というか表示がおかしかったりされなかったりする場合が以外に多くあります。
これについてはチップの番号とアドレスに組み合わせがあるのであとで記事にまとめたいと思います。
ネットでなかなか出てこなかったコマンド
わざわざ書くまでもないかもしれないんですが、探すのが大変だったのでここにメモしておきます。
そのコマンドとはLCDディスプレイのバックライトを消すコマンドです。
いやぁ、これマジでのってなかったよ。。文面を消すコマンドはのってるんですけどね。
Arduinoのライブラリの公式リファレンス見ても載ってなかったしマジで大変でした。
コマンドは
lcd.noBacklight();
です。
もともとバックライトを消すと超絶見にくいディスプレイなのでそんな使い方をする人はほとんどいないからか、なかなか出てきませんでした。
見つけたのはどっかのよくわからんデータシートだったかな?
これだけではつまらない
LCDディスプレイに文字が表示されると結構楽しいもんですが、マジで飽きます。
ただ文字を表示しているだけですからね、、
それだけではつまらないなぁ~と思いましたし、ただただ使用方法の解説記事を書いているのもつまらないので、いろいろ表示を可変させる方法を初心者なりに考えてみました。
単純なプログラムで結構いろいろと変わるので少しは用途の幅が広がるかもですね。
文字表示の際にひとつでも「あ、これやってみたかった!」というものがあればうれしいです。
(コードは無駄が多いので適宜直してください。<m(__)m>)
以下のプログラムは“void loop(){...}”の部分のみ記載しています。
文字を点滅させる
文字全体を点滅させるプログラムです。
for文で回数指定で動かします。これだと点滅中は他の動作ができません。
(そのループ内にとどまるので)
void loop() {
char ch1[]="Passcode clear!";
int char_count=0;
lcd.noCursor();
delay(3000);
lcd.backlight();
int i,n=3;
for(i=0;i<n;i++){
lcd.setCursor(0,0);
lcd.print(ch1);
delay(500);
lcd.clear();
delay(500);
}
}
なにかを動かしながら表示したい場合は、static変数を使って0なら表示1ならclearなんて言う風にすればいいと思います。
文字を一文字ずつ表示していく
流れるように文字を一文字ずつ表示していくプログラムです。
ナル文字“\0”でwhile文で条件をつけられるので、最後の文字が0になるまで配列を動かします。
表示したい文字をchar型の配列に入れてやります。
void loop() {
char ch1[]="Passcode clear!";
int char_count=0;
lcd.noCursor();
delay(3000);
lcd.backlight();
while(ch1[char_count]){
lcd.setCursor(char_count,0);
lcd.print(ch1[char_count]);
delay(200);
char_count++;
}
delay(2000);
lcd.clear();
}
文字の一部分だけを動かす
こういうの、やっすいおもちゃの液晶とかでよくありましたよね。
void loop() {
lcd.noCursor();
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("Please wait");
static int i=11; //カーソルを11から開始
lcd.setCursor(i,0);
delay(300);
lcd.print(".");
delay(300);
i++;
if(i==14){
i=11;
lcd.setCursor(11,0);
lcd.print(" ");
delay(300);
}
}
上記のプログラムでは文字の列のカーソルを指定し、
Please wait は空白も含めて11文字なので、0からカウントが始まる列カーソルにおいて、カーソル(11,0)が一行目の12文字目、ということになるので、
そこから「.」を表示させることで、文字列「Please wait」の後ろから上書きして表示させてます。
lcd.clear()は使わずに空白を出力している(カーソルは同じく11から)ので、消えるのは「. . .」のみになります。
関数ではなくstatic変数にしてloop内全体で回しているため、値の取得をしながら、といったことも一応できます。モーター等、別の関数に移った場合は無理ですが、、、(引数として指定すれば行けそう?)
文字を表示してその後表示した文字から順次消していく
表示した文字からフェードアウト、、みたいな感じです。
案外書かれていないんですが、
LCDディスプレイに何も表示したくないときは空白(スペース)を出力します。
void loop() {
char ch1[]="Passcode clear!";
int char_count=0;
lcd.noCursor();
delay(3000);
lcd.backlight();
while(ch1[char_count]){
lcd.setCursor(char_count,0);
lcd.print(ch1[char_count]);
delay(100);
char_count++;
}
delay(2000);
int i=0;
while(i<char_count){
lcd.setCursor(i,0);
lcd.print(" ");
delay(100);
i++;
}
lcd.clear();
}
文字をディスプレイモジュールの中で流す?
ぐるぐると液晶ディスプレイの中で流します。
setCursorコマンドで最初の表示位置をずらしてもよかったんですが、それだと最初の一回きりでその後の動作がおかしくなるので他の方法を考えてみました。
//※このプログラムは動きません。
static int row=0; //カーソル行用
static int col; //カーソル列用
//1文字目まで表示
lcd.setCursor(row,0);
lcd.print(ch[word_length-1]);
//2文字目まで表示
lcd.setCursor(row,0);
lcd.print(ch[word_length-1-1]);
lcd.setCursor(row+1,0);
lcd.print(ch[word_length-1]);
//3文字目まで表示
lcd.setCursor(row,0);
lcd.print(ch[word_length-1-1-1-1]);
lcd.setCursor(row+1,0);
lcd.print(ch[word_length-1-1]);
lcd.setCursor(row+1+1,0); //→setCursor(2,0)
lcd.print(ch[word_length-1]);
//続く...
これを延々とやっていくわけにもいきませんねぇ、、、
と思ったんですが、案外簡単にまとまりました。以下のプログラムです。
void loop() {
String putstring;
String s="loading...";
// 0123456789 10文字
lcd.backlight();
static int n_row; //カーソルのバイアス
static int row=s.length()-1; //文字数を入力、何文字目から表示するかの指標
//Serial.println(row);
lcd.setCursor(n_row,0); //空白が入らない内はカーソル0,0からスタートする。
putstring=s.substring(row); //表示する文字列(row文字目以降)
lcd.print(putstring);
delay(200); //待ち時間=流れの速度
if(row==0){
n_row++; //rowが0になった。つまり設定文字数を全部出力したらカーソルを移動
}else{
row--; //9文字目から、8文字目から、7文字目から、、、と、移動。
}
if(n_row==16){ //カーソルの設定値が15文字目、つまりn_row=16で
n_row=0; //lが15文字目に出力されているので、初期化してまた最初から
row=9;
}
lcd.clear(); //カーソル移動時“l”がllllloading、とならないように削除。
}
Arduinoだとloop関数がいちいち呼び出されている、ということを考えなくてはならないのでちょっとこういうところは面倒ですね。
まぁ、平行してモータを動かす、とかをやらなければfor文一つでまとまるので簡単ですが。。。
それだと「動作中」みたいな表示ができなくなるので使いどころが限られてしまいますよねぇ、、、
ひとまず完成しましたが、プログラム的に無駄が多いと思うので適宜変更してください。
案外LCDディスプレイで単純に文字を表示する以外のことをやっている人が少なかったので簡単にまとめてみました。
カーソルの動きを理解すればいろいろな表示ができるかと思いますのでやってみましょ~う。
単純なコードですが、Arduinoのエディタ上で表示されるのとは違った感動がありますよ。
まとめ
文字を簡単に動かす方法は以上です。
以下にお勧めのLCDモジュールおよびI2Cモジュールのリンクを掲載しておきます。
参考にしてください。
中華モジュールだと正規品に比べて異様に安いのが多いですが、
それに関してはあまり心配する必要はないかと思います。
以下の記事で中華モジュールを購入する際の個人的な注意点をまとめてみました。
説明は以上になります。
読んでいただきありがとうございました。
それでは。(人''▽`)