パラレル文字LCD(液晶表示)

液晶表示器(LCD)は現在TVやスマートフォンで主流になっている表示方法です。ここでは、小型の文字(英数字)を16文字2行を表示するLCDを利用して、自前で文字表示をする方法を紹介します。別の章で I2C接続のLCDを紹介しています。

  1. 液晶表示器とは

     液晶(Liquid Crystal Device)は液体(Liquid)の中に細長い結晶(Crystal)を封じ込めたデバイスで、細長い結晶の向きを外部の電界で変更することで、光の透過度を制御し文字を表示します。電界のみで制御できるため、LCD本体の消費電力は僅かです(このLCDの場合3mA)。ほとんどの電力はLCDのバックライトの光源(LED)で消費されます(30mW)。
     ここでは、16文字2行が表示できる小型のバックライト付き液晶表示器を利用します。

  2. SD1602液晶表示器

     液晶表示素子も各種販売されていますが、ここではブレッドボードで利用しやすい、 端子が一列になっている液晶文字表示器(LCD) SD1602 を利用します。文字は英数字のみが表示できます。液晶に 文字を表示するには、対応する文字コード(8bit)を送りこみます。この動作には、データを送るデータ線、データ線を制御する制御線、などが必要です。
     液晶には、文字以外に表示位置や表示モードを設定する必要があります。この設定にはコマンドと呼ばれるデータを送ります。文字コードとコマンドを区別するために、制御線 RS を利用します。
      
      SD1602
  3. パラレルとシリアル転送

     この LCD ではデータを4(8)本づつまとめて「並列」に送りますので、パラレル(並列)転送方式と呼びます。これに対し、データ線1本と数本の制御線で、「時系列」でデータを転送する方式をシリアル転送方式と呼びます。
     パラレル方式では、一般に複数のデータ信号と、データ送信のタイミングを示す ストローブ(イネーブル)信号を利用します。送信するときはデータ信号(複数)にデータを設定し、ストローブ信号を出します。受け取る方では、ストローブ信号に合わせて、データ信号の値を取り込みます。
     
  4. LCD表示回路(パラレル)

     SD1602の接続線は16本です。ピン配置は特殊で、左から14、13、..、2、1、と続き、最後にバックライト用の16,15 ピンとなります。7ピンから14ピンは8本のデータ線ですが、8本を接続するのは「手間」なので、半分の4本だけを接続し、4ビットづつ2回に分けて送る方法を利用します。これで、接続するデータ線を4本(DB7:14, DB6:13, DB5:12, DB4:11 )に節約できます。
     制御線には、データ/コマンドを選択するRS(4ピン)、read と write を区別するR/W(5ピン)、タイミングを指定する Enable 信号(6ピン)があります。ここではR/W は wite(0)側 に固定し(LCDの状態読み取り機能を利用しない) R/W 信号の接続を省力します。制御線は RS と Enable のみで、これを ArduinoのD12 と D10 に接続します。LCDのデータ線 D7-D4 をArduinoのD2-D5に接続します。
     1ピンと 2ピンを電源の GND と 5V に接続します。液晶のコントラスト(VO:3ピン)は抵抗 5.6k を通してGNDと接続します。コントラストが適正でない場合、この値を調整します。また、バックライトの照明用電源として、A:15ピンを150Ωを通して5V端子に、K:16 ピンを GND 端子に接続します。


     

      液晶の裏に配線                         液晶をはずして配線を見る

  5. 液晶文字表示プログラム

     LCDの表示には、LiquidCrystal.h ライブラリを利用します。このため、以下の # include でライブラリーを読み込みます。このライブラリは必要な初期設定を実行してくれます。
    #include <LiquidCrystal.h>
     LiquidCrystal lcd(12, 10, 5, 4, 3, 2); では液晶に接続する端子の番号と LCD の名前を指定します。端子は順に、RS、EN、DB7, DB6, DB5, DB4 の端子になります。この値を変更すれば、UNO と LCD の接続端子を変更できます。
     lcd.begin(16, 2)では表示できる文字数と行数を指定します。lcd.print("hello, world!"); で表示する文字を指定します。
     lcd.setCursor(0, 1); は表示を開始する文字の位置を指定します。0,1 は 0 列の第一行を指定します。数字は 0 から始まりますから、2行目の先頭の文字を意味します。millis()はプログラム開始後の時間をミリ秒単位で返す関数です。LCD の第2行には開始からの秒数を表示します。
     
    //LCD表示試験
    
    //接続
    /*LCD 4 pin to UNO pin 12
    * LCD 6 pin to UNO pin 10
    * LCD 11 pin to UNO pin 5
    * LCD 12 pin to UNO pin 4
    * LCD 13 pin to UNO pin 3
    * LCD 14 pin to UNO pin 2
    * VoはGND端子に接続
    * 表示が黒くなる場合 5.6K の抵抗の値を調整する
    */
    
    // include the library code:
    #include <LiquidCrystal.h>
    
    // 液晶(LiquidCrystal)のインスタンス(lcd)を作成する
    //数字はLCDの端子に対応するArduinoの端子番号
    LiquidCrystal lcd(12, 10, 5, 4, 3, 2);
    
    void setup() {
      pinMode(11, OUTPUT);//r/w
      digitalWrite(11, LOW);
    
      // LCDの行数(2)と文字数を指定する
      lcd.begin(16, 2);
      // LCD に文字列を送る
      lcd.print("hello, world!");
    }
    
    void loop() {
      // 文字カーソルを0列 1行に設定する(0行が先頭の行)
      lcd.setCursor(0, 1);
      // millis() はプログラム開始以後の時間(ミリ秒単位)
      lcd.print(millis()/1000);
    }

  6. 液晶に棒グラフ表示

     LCDでは文字を5列8行のドットパターンで表示しています。SD1602 は 0-9 までの文字コードに対して、表示するパターンを設定する機能があります(CGRAM)。
     
      ドットパターン

     この機能を利用して棒グラフの表示を行います。0-7 のコードに i に対し、下から i 行を塗りつぶしたパターンを定義します。上下の2行の文字を利用すると、合計16段階の棒グラフを表示できます。文字コードの定義には .createChar(cod,pat); を利用します。これは、cod に対し配列 pat[8] の文字パターンを定義します。lcd_makebarCode() は 8種の棒グラフ用のパターンを定義しています。

      棒グラフ表示

     下のプログラムは、2行の文字を連結して 0-16 段階の棒グラフを表示した例です。
    // include the library code:
    #include <LiquidCrystal.h>
    
    char cod,i;
    byte pat[9];
    char top[16],btm[16];
    char bar[16];
    
    // lcd の作成
    LiquidCrystal lcd(12, 10, 5, 4, 3, 2);
    
    void setup() {
    
      pinMode(11, OUTPUT);//r/w
      digitalWrite(11, LOW);
    
      // set up the LCD's number of columns and rows:
      lcd.begin(16, 2);
      // Print a message to the LCD.
      lcd.print("hello, world!");
      
      lcd_makebarCode();//棒グラフ表示用のコードを作成
    
       for(i=0;i<16;i++)//グラフデータを作成
        bar[i]= i;
    
      lcd_bar(bar,16);// bar配列の8個のデータを表示  
    }
    
    void loop() {
    
    }
    
    //棒グラフのパターン文字を作成
    void lcd_makebarCode(){
      for(cod=0;cod<8;cod++){
        for(i=0;i<=8;i++) pat[i]=0;
        for(i=0;i<=cod;i++) pat[7-i]=0x1F;
       //codのコードのパターンをpat[]で定義する
        lcd.createChar(cod,pat);
      }
      lcd.setCursor(0,0);
    }
    
    //bar[]の値をnum個棒グラフで表示する
    void lcd_bar(char bar[],int num){
      lcd.clear();
      for(i=0;i<num;i++){
       if(bar[i]<=8){
          top[i]=' ';
          btm[i]=bar[i]-1;
        }
        else{
          top[i]=bar[i]-9;
          btm[i]=7;
        }
       if(bar[i]==0) {
          btm[i]=' ';
        }
      }
       lcd.setCursor(0,0);
       //delay_us(20);
    //   lcd_cmd(0x80);
       for(i=0;i<num;i++)
         lcd.write(top[i]);
       lcd.setCursor(0,1);
       //delay_us(20);
    //   lcd_cmd(0xc0);
       for(i=0;i<num;i++)
         lcd.write(btm[i]);
    }

  7. 発展

     
    1. 他にどんな液晶表示がありますか?

      文字専用とグラフィック液晶があります。文字専用の場合、20文字4行の大型から8文字2行の小型まで各種あります。また、バックライト付きタイプでは、暗い場所でも読むことができます。

    2. 利用の仕方は同じですか?

       同じ端子は用意されていますが、端子の番号は異なります。

    3. グラフィック表示LCDの画素数は?

      小型では 128*32ドット、中型では 128*64 ドットがあります。多くは、縦8ビットずつ2-4段に分割して表示します。
      SPI 接続タイプもあります。