I2C接続小型LCDモジュールに表示を行う

〔Arduinoの動かせ方入門に戻る〕


Arduino 日本語リファレンス”を見ると、LiquidCrystal標準ライブラリが有ります、
これは、SD1602SC2004等のHD44780とコンパチなコントローラを搭載しているLCDは利用可能です
ですがこれらは、最低でも6本の配線が必要です。

なのでWire(I2C)標準ライブラリを利用して、I2C接続LCDを使えば2本の配線で済みます。
I2C接続LCDは秋月電子[AQM0802A][AQM1602A]やストロベリー・リナックス[SB1602B][SB1602BW]
などの ST7032i 搭載コントローラであればここの記事で利用可能と思います。
但し、2行表示可能LCDを想定した記事です、1行の場合は設定を含め見直さないとダメでしょうね。
いずれにしてもピンを半田付けする必要が有ります。(秋月LCDは1.3mmピッチの半田付け有り)
尚、ST7032iコントローラのデータシートは、販売サイト(上記)の参考資料を見ましょう。

《配線》

配線図(SB1602B)  左図は、SB1602Bを使った配線図です。
 バックライト付きは端子番号9番(A)と10番(K)
 に接続ですが制限抵抗が必要らしい。

 LCDの"RST"端子はリセットです、
 LOWでリセットが掛かるので通常はVDDに
 接続します。

 回路の電源は3.3Vで、ArduinoのI/Oは
 5Vなので電圧レベル変換が必要です。
 左図では右側モジュールが、
 "I2C用電圧レベル変換モジュール"です。
 左図の変換モジュール上の方がVREF1側と
 なります。

 I2Cレベル変換モジュール

 I2C用プルアップ抵抗は変換モジュールに1KΩのプルアップ抵抗を内蔵しているので
 それを利用しています。

 外付けプルアップ抵抗を使う場合は、モジュール裏のジャンパーパターンをカットすれば良いです。

 尚、VPU端子は外部から通信可能不可能切り替えをする為の物ですが、今回利用していません。
 また、VREF2側に電圧の高い方(5V側)を接続する様にしましょう。

 あ、それとぉ、Arduino UNOの場合はデジタル端子側の方にSCL/SDA専用端子が有ります、
 そちらに接続しても良いでしょう。

LCDのI2Cアドレスについて

アドレス設定  アドレスは7ビットで表します、左図の1〜7ビットです。
 0ビット目はR/Wでこれはデバイスに対する読書き指示ビットです。
 R/W=0 : 書き込み要求です(デバイスは受信モード)
 R/W=1 : 読み込み要求です(デバイスは送信モード)

 今回のLCDアドレスは、"0111110"(0x3E)です。("0111110"+R/W)
 このLCDからはデータは読み出せないので、R/W=0書き込み"0111110"+"0"で0x7Cのみです。
 尚、ST7032i搭載コントローラであれば、どのLCDもアドレスはすべて同じ様です。

昇圧回路について

 ST7032iの電源は3.3V-5VまでOKで、液晶は7Vまでの様で有り、ST7032iの昇圧回路は2倍に
 液晶電源を上げるみたいです。
 ですのでVDD=3.3Vなら昇圧回路ONは良いのですが、VDD=5Vでの昇圧回路ONはダメです。
 VDD=5Vにするなら昇圧回路はOFFで使います電源5Vなら変換モジュールは必要ないですね。

その他LCDのピン構成

AQM0802ALCDピン構成図  I2C接続小型LCDモジュール(AQM0802A)です。

 この"RESET"端子もリセットです、LOWでリセットが掛かるので
 通常はVDDに接続します。
 電源は3.3Vとなっていますが、昇圧回路OFFで5Vも可能です、
 5Vでの動作実験は行っています。

AQM1602ALCDピン構成図  I2C接続小型キャラクタLCDモジュール(AQM1602A)です。
 この様に接続端子側を上に配置で使います。

 あまり意味がなかったのか端子からリセットが無くなっていますね。
 変換基板内では接続はされている様です。

 尚、”電源電圧は3.1〜5.5Vで、Arduinoとの接続が可能です”
 って謳っています、で、付いてくるデータシートに5Vでのスケッチが
 記載されていますがぁ昇圧回路ONのままです、大丈夫ぅ?

 この液晶は耐電圧が上がっているのでしょうか?(ここでは5Vで昇圧回路OFFの実験は行っています)

 基板の裏には半田を盛ればプルアップ可能な半田ジャンパーパッドが有ります。
 液晶ガラス(2mm厚)のみなので取り扱いは要注意でしょう。

《Display Data RAM (DDRAM)》

通常LCDのDDRAMアドレスを指定してそこに文字データを書き込めば画面に表示されます。
(以下は8文字x2行と16文字x2行のLCDにて説明しますが、1行LCDは少し異なります、
 ここでは"2-line display"ですよ)

DDRAM構成図
DDRAM構成図
緑枠が8文字x2行のLCDで、青枠が16文字x2行のLCDです。

この様に実際は表示している場所以外もDDRAMエリアが有り、その場所に対しても文字データを
書き込めますが表示はされません。(表示させる方法は有ります)
でぇ、その隠れているエリアを表示させる為に、ページ画面と言う概念を用いて私独自の方法で
表示できる機能を提供します、ってこんな機能必要なの?みたいなぁ。

ページ画面機能

下記の様にDDRAMをページ単位に分けて、そのページを指定する事により表示させます。
16文字x2行LCDは[20H]/[60H]以上は使いません。(もったいない人はご自分で行いましょう)

8文字x2行LCDのページ画面DDRAM構成図
8文字x2行LCDのページ画面DDRAM構成図

16文字x2行LCDのページ画面DDRAM構成図
16文字x2行LCDのページ画面DDRAM構成図

《ダウンロードスケッチについて》

↓ここからArduino用サンプルスケッチファイルをダウンロードして下さい。
skI2CLCDlib.lzh(2015/02/25)
skI2CLCDlib.zip(2015/03/29:32-bit MCU に対応しました)

解凍すると下の様に展開されます。
[skI2CLCDlib]─┬─[examples]───┬─[LCD8x2]----- LCD8x2.ino
        ├ skI2CLCDlib.cpp ├ [LCD16x2]---- LCD16x2.ino
        ├ skI2CLCDlib.h  └ [LCD16x2I]--- LCD16x2I.ino
        └ keywords.txt
ArduinoIDE 1.0.5-r2 がインストールされているフォルダー、インストール先を変更していないなら
[C:\Program Files\arduino\libraries]です。
この場所に上記解凍ファイルを[skI2CLCDlib]ディレクトリ丸ごと移動します。
また、ライブラリの登録や利用方法などの話はこちらを参考にして下さい。

LCD16x2I.ino ・・・・・・本体のサンプルスケッチ(16文字x2行のアイコン付LCD)
LCD16x2.ino  ・・・・・・本体のサンプルスケッチ(16文字x2行のLCD)
LCD8x2.ino  ・・・・・・本体のサンプルスケッチ(8文字x2行のLCD)
skI2CLCDlib.cpp ・・・・I2C接続LCD関数ライブラリソース
skI2CLCDlib.h ・・・・・・ヘッダファイル
keywords.txt ・・・・・・・キーワードファイル

サンプルスケッチは全て電源電圧VDD=3.3V(昇圧回路ON)で設定されています

LCD16x2I.ino

LCD16x2I.inoを開くには、
IDEを起動して、メニューバーの「ファイル」→「スケッチの例」→「skI2CLCDlib」→[LCD16x2I]を
クリック操作すればファイルが開かれます。
次に、IDEツールバーの「Upload」ボタンをクリックしてコンパイルとarduinoボードに書込みを行います。

LCD実行画面1  LCD実行画面2  LCD実行画面3
まず実行すれば左側の画面(0ページ画面)が表示されます。
次に真ん中の画面(1ページ画面)に、5秒後に切り替わります、更に5秒後に右画面が表示されますが、
この画面は1ページ目の画面を書き換えています。
それから5秒後に左側0ページ画面に戻ります。

skI2CLCDlib.h

I2C接続LCD関数ライブラリのインクルードファイルです。
関数ライブラリを利用する場合は、メニューバーの「スケッチ」→「ライブラリを使用」→「skI2CLCDlib」を
クリック操作すれば、"#include &#skI2CLCDlib.h>"がスケッチに追加されます。
まぁ、手動でキー入力しても良いんですけどね。

skI2CLCDlib.cpp

まず利用する場合は下記2行をスケッチの最初に記述します。
#include <Wire.h>
#include <skI2CLCDlib.h>

※ デバイスのI2C通信速度は100/400KHzまでの様ですがArduinoは100KHzで初期化されます。

I2C接続LCD用関数の使い方を説明します。

skI2CLCDlib
 I2C接続LCD用関数ライブラリを使用する為に必要な宣言(初期化)を行います。
 skI2CLCDlib LCD(address, colsu) ;
  address :LCDのI2Cアドレスを指定します(0x3E)
  colsu    :画面カラム数を指定します(8/16)
  "LCD"の名前は任意に変更可能です。
 例
  skI2CLCDlib LCD(0x3E,16) ;              // LCDのアドレス、画面カラム数16文字
 以下はこの宣言例で記述します。

LCD.Init(icon,contrast, bon)
 LCDの初期化を行う処理です。
 アイコンが無いLCDは使用しないと設定します。
 電源を5V回路にする場合は、必ず、昇圧回路の利用はしない"0"と設定します
  icon      :アイコンを使用するのかを指定します(1=使う 0=使わない)
  contrast:LCDのコントラストを指定します(0−63)
  bon       :昇圧回路の利用有無を指定 1=有り(VDDは3.3V) 0=無し(VDDは5.0V)

LCD.Contrast(contrast)
 LCDのコントラスト調整を行う処理です。
 数値が小さすぎると表示がされませんので注意が必要かもね。
  contrast:LCDのコントラストを指定します(0−63)

  コントラストの指示を説明します。
     command(0x70) ;     // Contrast set           : コントラスト調整データ(下位4ビット)
     command(0x50) ;     // Contrast set           : コントラスト調整データ(上位2ビット)
  コントラストは6ビットデータで0〜63を設定、今回は32(0b100000)を設定しています。
  0x70=0111xxxx → 下位4ビット(0b0000)をxxxxに設定
  0x50=0101??xx → 上位2ビット(0b10)をxxに設定(??は他の機能用Bit)

LCD.Clear( )
 LCDモジュールの画面を消し初期状態に戻す処理です。
 画面全体(DDRAM全て)が0x20のスペースで消され、カーソルは1行目の1桁目に移動します。
 ページ画面も初期状態(0ページ)に戻ります。

LCD.SetCursor(col, row)
 LCDモジュール画面内のカーソル位置を設定する処理です。
 この関数のカーソル位置指定はDDRAM全てに有効ですが、
 表示領域以外だと、文字データは書き込まれますが表示はされません。
  col :横(列)方向のカーソル位置(0-39)を指定
  row:縦(行)方向のカーソル位置(0-1)を指定

LCD.Putc(c)
 LCDにデータを1バイト出力する処理です。
  c :出力する文字データを指定

LCD.Puts(*s)
 LCDに文字列データを出力する処理です。
 文字列は、NULL(0x00)まで繰返し出力します。
  *s :出力する文字列のデータを格納した場所のアドレスを指定

  例)
  char mes[5]= {0xca,0xdb,0xb0,0x21,0x00} ; // "ハロー!"

      LCD.SetCursor(0,0) ;      // カーソルは1行目の1桁目に移動
      LCD.Puts(mes) ;           // 文字列を表示する

LCD.CreateChar(p, *dt)
 オリジナルのキャラクタ(5x7ドット)を登録する処理です。
 キャラクタコードの0x00〜0x05に登録可能です。
  p :登録する場所の指定(0〜5の6ヶ所のみ)
  *dt:登録したいキャラクタのデータを格納したバッファを指定

 注意) この関数をコールした後はLCDのアドレスカウンターがCGRAMになっているので
     この後に表示を行う場合は、DDRAMにアドレスを設定する必要が有ります
     表示する前に"LCD_SetCursor( )"関数を呼び出せば良いでしょう。
 例)
 char heart[7] = {
   0b01010,
   0b11011,
   0b11111,
   0b11111,
   0b01110,
   0b00100,
   0b00000,
 } ;

      LCD.CreateChar(2,heart) ; // 2番に登録する
      LCD.SetCursor(0,1) ;      // この行がないと表示しない
      LCD.Putc(0x02) ;          // 2番に登録したキャラを表示する
 ※ I2C接続小型キャラクタLCDモジュール(AQM1602A)のLCDは0x00〜0x07の8個登録可能です
 ※ ストロベリー・リナックス[SB1602B][SB1602BW]のLCDは0x00〜0x0Fの16個登録可能です

 ※ 良く使いそうなキャラクタはEEPROMとかに登録して利用する様な事を行えば良いかもね。

LCD.IconOnOff(flag, dt)
 指定アイコンの表示ON/OFFを行う処理です。
 アイコン表示が有るLCDのみですよ。
  flag:指定したアイコンの表示をするしない(1=表示する 0=消す)
  dt :アイコンのアドレスとビットを指定します、"skI2CLCDlib.hのdefine宣言で指定します。
 例
  LCD.IconOnOff(1,LCD_ICON_PHONE) ;   // 電話を表示します。

 ※ 消すのはアドレス単位なので、△▽又は、電話関連アイコンは全て消えます。
 ※ アイコンの絵柄等の説明内容は、ストロベリー・リナックスのこちらを参照下さい。

LCD.IconClear( )
 全部のアイコン表示を消す処理です。
 表示したままでLCD電源を切っても、電源を入れたら再表示してしまいます。
 なので、立ち上げ処理(setup関数辺り)で一度この処理を実行させないとダメですよ。

 注意) LCD.IconOnOff( )/LCD.IconClear( )の関数をコールした後はLCDのアドレスカウンターが
     ICON RAMになっているので、この後に表示を行う場合は、DDRAMにアドレスを設定する
     必要が有ります、表示する前に"LCD_SetCursor( )"関数を呼び出せば良いでしょう。

ans = LCD.PageSet(no)
 ページ画面の切り替えを行う処理です。
 単純にページを切り替えるだけなので、切り替える前のページデータは残ったままです。
 又、切り替えには画面のシフトコマンドを使っているのでぇ、パッとは切り替わりません。
  no :表示するページ画面の番号を指定(8x2なら0-4/16x2なら0-1)
  ans:0=正常 −1=指定したページ番号がおかしい

LCD.PageClear( )
 現在表示中のページ画面単位での消去を行う処理です。
 カーソル位置も現在表示中のページ画面内、1行目の1桁目に移動します。

LCD.PageSetCursor(col, row)
 現在のページ画面内でのカーソル設定を行う処理です。
 現在表示中の画面内でのカーソル位置指定ですが、領域外の数値入力はチェックしていないので
 注意しましょう、又は、ご自分でロジックを追加しましょう。
  col :横(列)方向のカーソル位置(8x2なら0-7/16x2なら0-15)を指定
  row:縦(行)方向のカーソル位置(0-1)を指定

ans = LCD.PageNowNo( )
 現在表示中のページ画面番号を返す処理です。

《その他》