こんにちは、「メカのりまき」です。

この記事では、LCDモジュール(1602A)に文字を出力させる方法について、説明したいと思います。

本記事で使用するもの

本記事で私が使用した物は以下の通りです。

  • 「Arduino IDE2.0.4」をインストールしたPC(Windows11)
  • USBケーブル
  • Arduino Uno R3(ELEGOO UNO R3でも可)
  • LCDモジュール(1602A)
  • ブレッドボード
  • ポテンショメータ(可変抵抗器)
  • ジャンパーワイヤー

「Arduino Uno R3」の互換ボードであれば、「ELEGOO UNO R3」以外のボードでも、本記事と同様な手順で動作可能だと思われますが、動作検証はしていないので、その点はご了承ください。

また、LCDモジュール(1602A)については、以下で紹介するスターターキットに付属していたものを使用しています。

「1602」という名称で、電源の電圧が5[V]かつ、ピンの構成が同じようなものであれば、本記事と同様な手順で動作可能だと思われますが、動作検証はしていないので、その点はご了承ください。

以下のリンクのスターターキットを購入した場合、上記で述べた使用するものは、PC以外すべて入手することができます。

Arduinoをまだ購入していないという方やArduinoで動かすことができるたくさんのパーツが欲しいという方は、購入を検討してみてください。

LCDモジュールの説明

LCDモジュール(1602A)は、以下の画像のような見た目をした部品で、信号を送ることにより文字を表示させることができます。

LCDモジュール(1602A)の写真

本記事で使用するLCDモジュール(1602A)は、16個のピンを持っていて、それぞれ以下のような役割を持っています。

ピンの文字役割
VSSGND(電源)
VDD5V(電源)
V0コントラストの調整(可変抵抗に接続)
RSレジスタの選択
RW書き込み/読み出しの選択
Eデータの書き込み/読み出しの起動
D0~D7 データのやり取りを行う
Aバックライト(5V)
Kバックライト(GND)

ここで、LCDモジュールの設定やデータの書き込みは、上記の「RS」、「RW」、「D0~D7」ピンの「HIGH」と「LOW」を以下の表に示すように出力した状態で、「E」ピンにパルス信号を送ることによって行うことができます。

命令の内容RSRWD7D6D5D4D3D2D1D0
表示のクリア0000000001
カーソルをホームへ000000001X
カーソルの移動や表示のシフトの設定00000001I/DS
カーソルや表示のオン/オフを設定0000001DCB
カーソルの移動,表示のシフト000001S/CR/LXX
機能の設定00001DLNFXX
CG RAMのアドレスセット0001CG RAMのアドレス
DD RAMのアドレスセット001DD RAMのアドレス
(BF/アドレスの読み出し)01BFアドレスカウンタ
データの書き込み10書き込みデータ
(データの読み出し)11読み出しデータ
0 : LOWC=0 : カーソルをオフDL=0 : 4ビットモード
1 : HIGHC=1 : カーソルをオンDL=1 : 8ビットモード
X : 無効のビットB=0 : ブリンクをオフN=0 : 1/8か1/11デューティ
I/D=0 : デクリメントB=1 : ブリンクをオンN=1 : 1/16デューティ
I/D=1 : インクリメントS/C=0 : カーソル移動F=0 : 5×10ドットマトリクス
S=0 : 表示をシフトさせないS/C=1 : 表示シフトF=1 : 5×7ドットマトリクス
S=1 : 表示をシフトさせるR/L=0 : 左シフトBF=0 : 命令の受付可
D=0 : 表示をオフR/L=1 : 右シフトBF=1 : 命令の受付不可
D=1 : 表示をオン

なお、書き込み処理時に有効な信号のタイミングは、以下のようになっています。

有効な信号のタイミング

上の図を見ると「E」ピンを「HIGH」にした後に、「D0~D7」を変更しなければならないように見えますが、これは、「E」ピンを「HIGH」にした後で、「D0~D7」を変更しても良いが、最低でも「E」ピンを「LOW」に切り替える40[ns]前には、「D0~D7」の電圧を確定してくださいということを表したものであり、「D0~D7」の電圧をセットした状態で、「E」ピンにパルス信号を送っても、しっかり動作します。

また、上記の表では、「D0~D7」の8ピンを使用していますが、設定を4ビットモードにすることによって、「D4~D7」だけでLCDモジュールの制御を行うことができるようになります。

4ビットモードに設定すると使用するピンの数を減らすことができますが、データは2回に分けて送信する必要があります。

4ビットモードの説明

LCDモジュール(1602A)の説明は以上となります。

上記の説明やその他詳細について確認したいという方は、以下のリンク先からデータシートの確認をしてみてください。

データシート[openhacks.com]

文字を表示させる

上記で説明したLCDモジュールの仕組みは、少し難しい内容でしたが、実は完全に理解していなくても、文字の表示は行うことができます。

まずは、以下の画像のように文字を表示させる方法について説明したいと思います。

Hello! (^_^)/

空のスケッチを書き込む

回路を作成する前に、空のスケッチ(「ファイル」タブの「New Sketch」をクリックしたときに出てくる何の処理も書かれていないスケッチ)を書き込みます。

空のスケッチを書き込む

そうすることにより、前に書き込んだスケッチが、新しく作成しようとしている回路に影響を及ぼすことを防げます。

新しい回路を作成するときは、いつもこの作業をやっておくと、安全に回路を作成することができます。

回路を作成する

以下の回路を作成してください。

LCDモジュール(1602A)を制御する回路

今回は、4ビットモードでLCDの制御を行います。

よって、「D0~D3」ピンは使用しません。

さらに、LCDモジュールからデータを読み出すようなことは、行わないため、「RW」ピンは「GND」と接続し、常に「LOW」の状態にしています。

また、コントラストを調整させるための「V0」ピンには、10[kΩ]の可変抵抗を繋ぎ、後から、コントラストを変更できるようにしています。

その他データのやり取りを行うピンは、デジタル入出力ピン、電源関係のピンは、5[V]とGNDに接続しています。

間違った回路は部品の破損に繋がる可能性があります。

特に今回の回路は、線が多くさらに密集している部分が多いため、作成した回路が間違っていないか、よく確認をしてください。

スケッチを書き込む

LCDに文字を表示させるためには、上記で説明したように、ピンの出力を実行したい処理に合わせて切り替えて、設定や文字の書き込みを行う必要があります。

よって、初心者が一からスケッチを書いて、LCDに文字を表示させるのは容易ではないのですが、「Arduino IDE」に初めから付属している「LiquidCrystal」ライブラリを使用すれば簡単に文字を表示させることができます。

以下のスケッチを書き込んでください。

すると、先程の画像のように、LCDモジュールに文字が表示されます。

ここで、文字が表示されていない場合は、ポテンショメータを回してみてください。

すると、コントラストが調整され、文字が浮かび上がってくるのが確認できると思います。

もし、上記の方法で文字が表示されない場合は、もう一度回路とスケッチを確認してみてください。

スケッチの解説

今回のスケッチは「LiquidCrystal」ライブラリを使用することにより、LCDモジュールの表示を制御しています。

「LiquidCrystal」ライブラリは、登録されている関数を実行することにより、各ピンの出力を適切に切り替えてくれるというものであり、直観的にLCDモジュールを制御することができます。

では、「LiquidCrystal」の使い方についての説明をしながら、スケッチの解説を行いたいと思います。

まず、スケッチの2行目では、以下の文により、「LiquidCrystal」ライブラリの読み込みを行っています。

そして、5行目の以下の文により、「LiquidCrystal」クラス型の変数「lcd」を用意します。

この一連の流れは、「Servo」ライブラリを使用するときと似ています。

イメージとしては、「LiquidCrystal」ライブラリという設計図を読み込んだ後、「LiquidCrystal」クラス型の変数「lcd」を用意して、記述したピンを制御する関数を扱えるようにしたといった感じになります。

ライブラリの説明

今回、変数の名前を「lcd」としたため、以後、「LiquidCrystal」ライブラリに登録してある関数を利用するときは、「lcd.関数の名前」というように記述します。

次に、「void setup()」内について、説明していきたいと思います。

まず、10行目では、以下のような文が記述されています。

これは、LCDモジュールの初期設定を行う関数で、LCDの桁数と行数を指定します。

今回使用するLCDモジュール(1602A)は、16桁、2行のものであるため、引数の部分に、「16」と「2」を入れています。

LCDモジュールの桁数と行数

次に、13行目では以下のような文が記述されています。

この関数は、画面上の文字をクリアして、カーソルの位置を左上(0,0)に移動させる関数です。

ここまでの一連の流れで、文字を表示させる準備が整いました。

次に、文字を出力させる関数について説明します。

16行目では、以下のような文が記述されています。

この関数が、LCDモジュールに文字を表示させる関数です。

文字列を表示させたい場合は、文字列をダブルクォーテーション( ” )で囲います。

また、今回は文字列の表示のみ行っていますが、「Serial.print()」と同じように、変数の値を表示させることも可能です。

最後に、19行目の以下の文について説明します。

この関数は、カーソルの位置を移動させる関数です。

一番左上を(0,0)とし、列と行を指定します。

これにより、次に表示される「(^_^)/」は以下のような位置になります。

カーソルの位置

カタカナや特殊文字を表示する

次は、以下の画像のようにカタカナを表示させる方法について、説明をしたいと思います。

コンニチハ! (^_^)/

LCDモジュール(1602A)は、文字に関するデータを受け取り、それを以下のような文字コードと照らし合わせることによって、文字の表示を行っています。

文字コード表

例えば、「A」という文字を表示させる場合は、「D4~D7」で、「01000001」という2進数のデータを受け取っているということです。

Aの文字コード

つまり、先程のスケッチで使用した「print()」は、ダブルクォーテーション( ” )で囲った文字たちを2進数で表し、「D4~D7」でそれらの情報を送っているということになります。

ここで、Arduinoの場合、アルファベットや数字、半角の記号などは、上記の表と同じような数値で表されるのですが、カタカナや特殊文字については、上記の表と異なる数値で表されているため、「print()」の( )内にカタカナを入力しても正しく表示させることができません。

カタカナの表示が上手くいかない理由

正しく表示させるためには、表示させたい文字に対応した数値を、送る必要があります。

スケッチを書きこむ

以下のスケッチを書き込んでください。

すると、先程の画像のように、カタカナを含んだ表示が行われるのが確認できます。

スケッチの解説

先程のスケッチと異なるのは、16行目の以下の文だけです。

暗号のように、良く分からない文字列ですが、これが、「コンニチハ!」と表示をさせる文となっています。

では、何故、上記の文字列が、「コンニチハ!」を表しているのか、順番に説明していきたいと思います。

先程、「print()」は、ダブルクォーテーション( ” )で囲った文字たちを2進数で表し、「D4~D7」でそれらの情報を送っていると説明しました。

つまり、人間の視点で考えると、文字から2進数への変換が行われているという見方ができます。

文字が送られるまでの変換

今回の場合、送りたい2進数のデータは、先程の表から分かっているので、任意の2進数のデータを送るように指示を与えれば良いということになります。

任意の2進数のデータを送る

そこで、任意の2進数のデータを送るために、利用しているのが、16行目の文で何度も記述されている「\x~」です。

少し話がややこしくなりますが、「\x~」は文字列の中で「16進数」を表現するためのものです。

16進数は、数値を「0」~「9」の数字と「A」~「F」のアルファベットで表したもので、「9」の次の数字が「A」、「F」の次は桁が上がって、「10」といった表現をします。

ここで、10進数と16進数の関係は以下のようになります。

16進数と10進数

上記の説明だけでは、16進数が何の役に立つのか全く分かりませんが、2進数との関係を見てみると、この表現がとても役に立つことが分かります。

2進数と16進数の関係は以下のようになります。

16進数と2進数

ここまでの関係を見ると、2進数では4桁分の数値が、16進数では1桁で表せていることが分かります。

また、16進数で桁の上がる「10」のとき、2進数では「10000」となっていて、何だか切りの良い数字になっています。

さらに続きの関係は以下のようになります。

16進数と2進数その2

ここで、2進数の下4桁と、16進数の下1桁の数字関係が先程と全く変わっていないことが分かります。

また、16進数で2桁の数字が変わる「20」のとき、2進数では「100000」となっていて、またまた、切りの良い数字になっています。

16進数の下4桁と2進数の下1桁の関係

さらに続きの関係は以下のようになります。

16進数と2進数その3

堪の良い人は、お気付きかと思いますが、ここから先も2進数の下4桁と、16進数の下1桁の数字関係は変わりません。

また、数字を以下のように4桁で区切った場合、2進数の4桁より上の数字と16進数の2桁目の数字の関係も見えてくると思います。

16進数と2進数の関係

実は、2進数の数字は、4桁ずつ分けて、16進数に対応する数字に変換すれば、簡単に16進数で表現できます。

例えば、「100110101001110」という2進数も4桁ずつ分けて、16進数に対応する数字に変換すれば、簡単に、「4D4E」という16進数に変換することができます。

2進数を16進数に変換する方法

また、16進数は少ない桁数で数値を表現できるため、大きな2進数のデータを見やすくまとめる場合、とても便利な表現になります。

16進数の話がだいぶ長くなりましたが、ここで、LCDモジュールの文字コードの話に戻りたいと思います。

まず、「コ」というカタカナについて、見てみると先程の表より、対応する2進数のデータは「10111010」となっています。

これを16進数に変換すると、「BA」になります。

文字コード表16進数バージョン

ここで、もう一度16行目の文を見てみると、文字列の一番初めに「\xba」と記述されていることが分かります。

「\x~」は、文字列の中で、16進数の値を表現するものです。

そして、「print()」は、ダブルクォーテーション( ” )で囲った文字たちを2進数で表し、「D4~D7」でそれらの情報を送信しています。

つまり、人間の視点で考えると、「\xba」は以下のように、16進数から2進数に変換されて、データが送られているということになり、「コ」という文字が表示されるということになります。

\xbaの転送

続けて表示させている「ン」、「ニ」、「チ」、「ハ」も同じ理論で表示させています。

ここで、「!」は16進数ではないので、ダブルクォーテーション( ” )の囲いを分けています。

実は「!」の場合は、ダブルクォーテーション( ” )の囲いを分けなくてもしっかり表示されるのですが、例えば、続けて「a」という文字を出力させようとすると、「a」が最後の「\x~」の一部として認識されてしまうため、ダブルクォーテーション( ” )の囲いを分ける必要があります。

カタカナや特殊文字を表示させるための理論についての説明は以上となりますが、正直、文字コードの表と照らし合わせて、対応する16進数を探すのが、面倒くさいと思った方もいらっしゃるのではないでしょうか。

ということで、LCDモジュール(1602A)における、カタカナや特殊文字と「\x~」についての対応表を作成しましたので、ご活用ください。

カタカナ、特殊文字対応表

カタカナ大文字

\xb1 \xb2 \xb3 \xb4 \xb5
\xb6 \xb7 \xb8 \xb9 \xba
\xbb \xbc \xbd \xbe \xbf
\xc0 \xc1 \xc2 \xc3 \xc4
\xc5 \xc6 \xc7 \xc8 \xc9
\xca \xcb \xcc \xcd \xce
\xcf \xd0 \xd1 \xd2 \xd3
\xd4    \xd5    \xd6
\xd7 \xd8 \xd9 \xda \xdb
\xdc \xa6 \xdd

カタカナ小文字、濁点、半濁点

\xa7 \xa8 \xa9 \xaa \xab
\xac \xad \xae \xaf
\xde \xdf

その他記号

\xa1 \xa2 \xa3 \xa4 \xa5
\x7e \x7f \xb0
\xe0 \xe1 \xe2 \xe3 \xe4
\xe5 \xe6 \xe7 \xe8 \xe9
\xea \xeb \xec \xed \xee
\xef \xf0 \xf1 \xf2 \xf3
\xf4 \xf5 \xf6 \xf7 \xf8
\xf9 \xfa \xfb \xfc \xfd
\xff

シリアルモニタで入力した文字を表示する

次は、以下の動画のように、シリアルモニタで入力した文字を、LCDモジュールに次々と表示させる方法について、説明したいと思います。

スケッチを書き込む

以下のスケッチ書き込んでください。

スケッチの書き込みが終わりましたら、シリアルモニタを開き、右下に表示されている設定が「改行なし」、「9600baud」になっているのを確認して、メッセージを送信してみてください。

すると、先程の動画のように、シリアルモニタで送った文字が、表示されていくのが確認できます。

スケッチの解説

今回のスケッチでは、送信された文字が、何処に表示されるのかを分かりやすくするために、カーソルの表示を制御する関数を使用しています。

まずは、それらの関数について、説明したいと思います。

まず、31行目では、以下のような文が記述されています。

これは、カーソルを表示させるための関数で、この関数が実行されると、カーソルの位置にアンダーバーが表示されるようになります。

アンダーバーの表示

次に、34行目では以下のような文が記述されています。

これは、カーソルの位置を点滅させるための関数で、この関数が実行されると、カーソルの位置が点滅するようになります。

カーソルの点滅

新しく使用した、カーソルの表示を制御する関数についての説明は以上となります。

続いて、「void loop()」内の文について、説明したいと思います。

まず、40行目のif文では、シリアルモニタによって、文字が送られているかを確認し、次の41行目の「input_char=Serial.read()」で、一文字分のデータを変数「input_char」に入れています。

そして、42行目の「lcd.print(input_char)」でLCDモジュールに表示を行っているという流れになります。

また、右端まで文字が入力されたら、左端にカーソルを戻すため、以降の文で、出力された文字の数をカウントし、16回文字を出力したら、左端にカーソルを戻すような処理を行っています。

「void loop()」の処理の流れをまとめると以下のようになります。

シリアルモニタで送った文字を表示させるスケッチの流れ

シリアルモニタで送られた文字をLCDモジュールに表示させる流れについては、以下のリンク先の、シリアルモニタでPCと文字のやり取りを行うスケッチとほとんど同じです。

シリアルモニタでPCと文字のやり取りを行う仕組みについて、もう少し詳しく知りたいという方は、以下のリンク先の記事で説明していますので、是非、ご覧になってください。

文字を左右に動かす

次は、以下の動画のように、表示された文字を左右に動かす方法について、説明をしたいと思います。

スケッチを書き込む

以下のスケッチを書き込んでください。

すると、先程の動画のように、カニっぽい文字が左右に移動していく様子が確認できます。

スケッチの解説

今回新しく使用した関数は、29行目と35行目の以下の文です。

「scrollDisplayRight()」では、表示している文字全体を右に1つシフトし、「scrollDisplayLeft()」では表示している文字全体を左に1つシフトします。

今回のスケッチでは、for文により、それぞれの関数と「delay()」を11回ずつ繰り返しているので、文字が画面端までゆっくり動いているように見えるということになります。

ここで、「for文」が分からないという方は、以下のリンク先の記事で説明していますので、是非、ご覧になってください。

オリジナルの文字を作成する

最後に以下の動画のように、オリジナルの文字を作成して、それを表示させる方法について、説明をしたいと思います。

LCDモジュール(1602A)はあらかじめ登録された文字以外に、オリジナルの文字を8つまで登録し、表示させることができます。

スケッチを書き込む

以下のスケッチを書き込んでください。

すると、先程の動画のように、文字コード表には無い、文字たちが表示されているのが、確認できます。

スケッチの解説

新しく文字を作成するためには、まず、新しい文字のデータを作成する必要があります。

文字のデータを作成する際は、「byte型」の「配列」を利用します。

「byte型」というのは、8ビット分のデータを入れることができる型で、今回のスケッチでは「B~」という形で、5ビット分のデータ指定して値を入れています。

byte型の説明

そして、「配列」というのは同じ型の変数をまとめたようなものです。

今回は、「byte型」の変数を8個分まとめています。

配列の説明

次に、これらのデータは、109~116行目の「lcd.createChar()」により、LCDモジュールに送信され、文字の登録が行われます。

このとき、引数には登録番号(0~7)と文字のデータを入れた配列の名前を記述します。

また、文字とデータの関係は以下のようになります。

データとその表示

登録された文字は、文字コードの表の以下の部分に登録されているため、カタカナや特殊文字を表示させたときのように、「\x~」を使って表示させることができます。

文字の保存場所

ただし、「\x00」は文字列の終わりを表すのに利用されているため、「0番」に登録した文字を利用する際は、「\x08」を使用します。

終わりに

今回は、「LiquidCrystal」ライブラリを使用して、LCDモジュール(1602A)に文字を表示させる方法を説明しました。

皆さん上手く表示させることができたでしょうか。

実は今回「LiquidCrystal」ライブラリの関数をすべて紹介したわけではありません。

また、今回4ビットモードでデータのやり取りを行いましたが、「LiquidCrystal」ライブラリは8ビットモードにも対応しています。

「Arduino IDE」に付属しているライブラリの情報は、Arduinoの公式ホームページで確認することができます。

Arduinoの公式ホームページへのリンク

また、Arduinoの公式ホームページは英語で記述されていますが、それらの情報を日本語に直してまとめてくれているサイトも存在します。

「Arduino 日本語リファレンス」へのリンク

もし、今回の説明で、もっとこういうことがしたいという希望やもう少しこの関数について知りたいという疑問があれば、上記のリンク先を見てみると解決できるかもしれません。

色々と調べ、そして実験をしてみてください。

次回の記事では、「7セグメントLED」と「シフトレジスタ(74HC595)」の使用方法について、説明したいと思います。

本記事はここまでです。ご清覧ありがとうございました。

広告

楽天モーションウィジェットとGoogleアドセンス広告です。

気になる商品がございましたら、チェックをしてみてください。