わかめの開発日記

ArduinoやRaspberry Pi で作ったものを紹介します

LCDモジュールに文字を表示させる

f:id:wakamelab:20201004132233j:plain

Arduinoを使って、液晶ディスプレイに文字を表示させる方法

こんにちは、wakamelabです。
Arduinoと1602AのキャラクLCDモジュールを使って文字を表示させる方法を紹介します。

使用するもの

Arduino UNO 本体:1個
・USBケーブル:1本
・液晶ディスプレイモジュール 1602A:1個
・ブレッドボード:1個
・ジャンパーワイヤ(オス-オス):16本
・20kΩ可変抵抗:1個

使用する液晶ディスプレイモジュールの紹介

液晶ディスプレイ(Liquid Crystal Display)、通称LCDについて説明します。
1602Aはキャラクタディスプレイという、英数字や記号を表示できるタイプのLCDです。
1602Aからは16個の端子が出ており、この端子に信号を送ることでLCDに文字を表示させることが出来ます。
それぞれの端子の意味は以下の表のとおりです。

f:id:wakamelab:20201004154343p:plain

PIN No.1 VSS : グランドです。ArduinoのGND端子と接続します。
PIN No.2 VDD : 電源端子です。Arduinoの5V端子と接続します。
PIN No.3 VO : コントラスト調整用の端子です。抵抗を介してグランドと接続しその抵抗値によって、コントラストを調整します。
PIN No.4 RS : レジスタ選択用の端子です。Highを与えることでデータレジスタLowを与えることで制御レジスタを選択します。LCDに表示させる文字を送信するときはデータレジスタを使いLCDを制御するコマンドを送信するときは制御レジスタを使います。
PIN No.5 R/W : 読み込み(Read)、書き込み(Write)の切り替え端子です。ArduinoからLCDに表示させる文字を制御するので、書き込みを使用します。
PIN No.6 E : コマンドやデータの読み書きのタイミングを計るための端子です。ここが、Low → Highとなることで、制御が実行されます。
PIN No.7 ~ 14 DB0 ~ DB7 : データを送受信するための端子です。8bitモードで制御する場合は全ての端子を使用しますが、今回は4bitモードで制御するため、上位4bit(DB4~7)を使用します。
PIN No.15 A : LCDのバックライトの電源です。5Vに接続して使用します。
PIN No.16 K : LCDのバックライトのグランドです。GNDに接続して使用します。

LCD制御のためのライブラリ

LCDに文字を表示させるためには、上で紹介した端子に対して、キッチリとタイミングを計って適切な信号を送る必要があり、制御はやや複雑です。
しかし、Arduinoではこの細かな制御を気にせずにLCDを制御することができるイブラリが用意されています。
ライブラリの豊富さがArduinoの良い所ですね。
ライブラリを使うことで、開発のスピードを飛躍的に上げることが出来ます。
ではライブラリの紹介していきます。
使用するライブラリは"LiquidCrystal.h"というライブラリです。

LiquidCrystal lcd (rs, enable, d4, d5, d6, d7)

LiquidCrystal型の変数を宣言するために使用します。
引数にはそれぞれ、rs : RSに接続したピン、enable : E に接続したピン
d4 ~ d7 : D4 ~ D7に接続したピン番号を指定します。

lcd.begin(cols, rows)

ディスプレイの桁数と行数を指定するために使用します。
引数にはそれぞれ、cols : 桁数、rows : 行数を指定します。
1602A は、横16文字の縦2行であるため、cols : 16、rows : 2 として使用します。

lcd.clear()

LCDの画面をクリアし、カーソルを左上の角に移動させるために使用します。

lcd.print(data)

LCDに文字を表示させるために使用します。
引数:data に指定した文字を表示させることが出来ます。

LCDに文字を表示させるプログラム

ライブラリの使い方も分かった所で、文字を表示させるプログラムを書いていきましょう。
紹介するプログラムは、シリアル通信を使いArduinoに送信した文字をLCDに表示させるプログラムです。

#include <LiquidCrystal.h>

#define RS 4
#define E  6
#define DB4 10
#define DB5 11
#define DB6 12
#define DB7 13
#define MAX_LEN 17

char char_buf[MAX_LEN];
byte cursol = 0;

LiquidCrystal lcd(RS, E, DB4, DB5, DB6, DB7);

void setup() {

  lcd.begin( 16, 2 );
  lcd.clear();
  lcd.setCursor(0, cursol);
  lcd.print("Wait for input");
  Serial.begin(9600);
}

void change_cursol(void) {
  cursol = 1 - cursol;
}

void clr_display(byte t_cursol) {
  lcd.setCursor(0, t_cursol);
  lcd.print("                ");  //16文字の空白を表示させることで1行消去
}

void get_char(void) {
  int data_size;
  int i;

  delay(100); // データ受信待ち
  clr_display(cursol);  // 書き込み前に前の文字を消去
  data_size = Serial.available();  // 文字数を取得

  if (data_size <= MAX_LEN) {
    for (i = 0; i < data_size; i++) {
      char_buf[i] = Serial.read();
      if (i != (data_size - 1)) {
        lcd.setCursor(i, cursol);
        lcd.print(char_buf[i]);
      }
    }
    change_cursol();
  } else {
    lcd.setCursor(0, cursol);
    lcd.print("too long");
    for (i = 0; i < data_size; i++) {
      Serial.read(); // 受信データを削除
    }
  }
}

void loop() {
  if (Serial.available() != 0) {
    get_char();
  }
  delay(500);
}

ではここからはプログラムの内容を説明します。

  #include <LiquidCrystal.h>

LiquidCrystal.h ライブラリのインクルードを宣言しています。
インクルードすることで、指定したライブラリを使用することができます。

  #define RS 4
  #define E  6
  #define DB4 10
  #define DB5 11
  #define DB6 12
  #define DB7 13

LCDの制御に使用するピンを定義しています。
上で紹介したLCDの端子と対応しており、それぞれ
Arduinoの4番ピン:LCDのRS端子と接続
Arduinoの6番ピン:LCDのE端子と接続
Arduinoの10~13番ピン:LCDのDB4~DB7端子と接続しています。

  #define MAX_LEN 17

受信可能な最大文字数を定義しています。
1602Aは16行表示できるため、16文字+改行コード1つで17文字を最大文字数としています。

LiquidCrystal lcd(RS, E, DB4, DB5, DB6, DB7);

ライブラリの紹介で説明した通り、LiquidCrystal型の変数 lcd を宣言しています。

void setup() {

  lcd.begin( 16, 2 );
  lcd.clear();
  lcd.setCursor(0, cursol);
  lcd.print("Wait for input");
  Serial.begin(9600);
}

ここではArduinoの初期設定を行っています。
lcd.begin( 16, 2 )で16×2のLCDを使用する宣言を行い、lcd.clear()でディスプレイを一度初期化します。
lcd.setCursor(0, cursol)でカーソルの位置を左上に移動し(変数cursolの初期値は0のため、カーソルは左上に行きます)、lcd.print("Wait for input")でLCDにWait for inputと表示します。
シリアル通信を使って表示させる文字を入力するために、Serial.begin(9600)で9600bpsの通信を開始します。

void change_cursol(void) {
  cursol = 1 - cursol;
}

カーソルの位置を上下変更するための関数です。

void clr_display(byte t_cursol) {
  lcd.setCursor(0, t_cursol);
  lcd.print("                ");  //16文字の空白を表示させることで1行消去
}

指定した1行の表示内容を消すための関数です。lcd.clear()を使うと、LCD全体を消してしまいますがこの関数を使うことで指定した行数のみの内容を消すことができます。

void get_char(void) {
  int data_size;
  int i;

  delay(100); // データ受信待ち
  clr_display(cursol);  // 書き込み前に前の文字を消去
  data_size = Serial.available();  // 文字数を取得

  if (data_size <= MAX_LEN) {
    for (i = 0; i < data_size; i++) {
      char_buf[i] = Serial.read();
      if (i != (data_size - 1)) {
        lcd.setCursor(i, cursol);
        lcd.print(char_buf[i]);
      }
    }
    change_cursol();
  } else {
    lcd.setCursor(0, cursol);
    lcd.print("too long");
    for (i = 0; i < data_size; i++) {
      Serial.read(); // 受信データを削除
    }
  }
}

受信した文字を取得し、LCDに表示させるための関数です。
まず先頭のdelay()関数で、文字を完全に取得するまでの間待機します。
次にclr_display()関数によって、これから文字を表示させようとしている行に今書かれている内容を消します。
Serial.available()関数を使い受信した文字数を確認し、文字数が最大文字数の16文字以下であれば受信した文字を表示し、最大文字数を超えていれば"too long"と表示します。
受信した文字の末尾には改行コードが入っているため、LCDに表示させるのは受信した文字の最後から1つ前までです。

void loop() {
  if (Serial.available() != 0) {
    get_char();
  }
  delay(500);
}

Arduinoのループ処理で、シリアル通信から文字を受信するのを待っています。受信すると先ほど紹介した上の処理に入ります。

配線図の紹介

f:id:wakamelab:20201011161530j:plain

配線はこのような形です。

プログラムの実行

プログラムをArduinoに書き込み、シリアルモニタを開いてください。
シリアルモニタ上に文字を入力し、それがLCDに表示されれば成功です。

f:id:wakamelab:20201018133433p:plain

Arduino デジタル時計製作キットの紹介

当社では、Arduinoを使用した、プログラミング、電子工作初心者向けの学習キットを販売しております。
この記事に記載したLCDを使ってデジタル時計を作製するキットもありますので、ご興味あればご購入をお願い致します。

ホームページ:
www.wakamelab.com

販売サイト:https://wakamelab.thebase.in/items/28202226

メルカリ:https://www.mercari.com/jp/u/170119900/