I2C接続のキャラクタLCDを動かしてみる
Seeeduino XIAOを使ってI2C接続のキャラクタLCDを動かします。
キャラクタLCDはHD44780というドライバを使っているものがほとんどなので
16文字2行でも8文字2行でも、何色の液晶でも、大体動かし方は同じです。
LCDのライブラリも存在しますがあえて使わずに
LCDドライバHD44780とLCDのデータシートを読みながら作っていきます。
HD44780はシンプルなインターフェースなので勉強によい。かも。
必要なもの
- I2C接続のキャラクタLCD
秋月電子などで300円くらいから購入できます。
今回はACM0802C-NLW-BBW-IICを使います。 - Seeeduino XIAO
今回はSeeeduino XIAOを使いますが、I2Cが使えるマイコンなら何でもOK。 - 10kΩの半固定抵抗
バックライトの明るさ調整に使います。
バックライトがないLCDを使う場合は不要です。 - レベル変換モジュール
Seeeduino XIAOのI/O電圧は3.3Vに対し、
LCDのIO電圧は5Vなのでレベル変換モジュールを挟んで接続します。
マイコンとLCDでI2CのI/O電圧が同じ場合は不要です。
接続を確認する
まずは使用するLCDのデータシートを確認してみてください。
今回はLCDが5V、マイコンが3.3VのI/Oなのでレベル変換モジュールを使います。
続いて秋月の商品ページのよくある質問をチェック。
このLCDは基板上にすでにI2Cのプルアップ抵抗が実装されているようです。

以上から回路図を書いてみました。

回路図中の「+5V」「+3.3V」「SDA」「SCL」「GND」は
Seeeduino XIAOの対応する端子と接続します。
LCDのSA0, SA1をHigh/LowどちらにするかでI2Cアドレスを調整できます。

ブレッドボード上で接続するとこんな感じになりました。
プログラムをつくる

まずはLCDドライバHD44780の
データシートから確認していきます。
左図が初期化の流れになっているので
起動後まずはこれに沿って順番に
コマンドを発行していきます。
データシートには
コマンドの一覧も載っているので
合わせてチェックしておきます。

LCDに表示する文字は、
文字コードから
1バイトで指定します。
CGRAMにデータを書き込むことで
自分の好きな文字を
表示させることもできますが
ここでは割愛します。

文字を表示する場所のアドレス(DDRAM address)は上図のようにマッピングされています。

具体的なI2Cを使った制御方法はLCDのデータシートに書いてあります。
コントロールバイト(1バイト)とデータバイト(1バイト)で1セットのようです。
A0はコマンドを送るときは0、DDRAMに書き込むときは1です。
まずはコマンド用の関数を作っておきます。
今回はLCDのSA0, SA1をHighに接続したのでI2Cアドレスは0x3Fになります。
void send_command(byte command_data)
{
Wire.beginTransmission(0x3F); //I2C Address
Wire.write(B00000000); //controll byte
Wire.write(command_data); //data byte
Wire.endTransmission();
}
ちなみに Wire.write() でこまめにデータを送っているのではなく、
データは溜めておいて Wire.endTransmission() でまとめて送信しているようです。
次にDDRAM書き込み用(文字表示用)の関数を作っておきます。
void send_char(byte char_data)
{
Wire.beginTransmission(0x3F); //I2C Address
Wire.write(B01000000); //control byte
Wire.write(char_data); //data byte
Wire.endTransmission();
}
作った関数を使ってメインのコードを書くとこんな感じ。
void setup()
{
Wire.begin();
delay(100);
send_command(B00111100); //Function set
delay(100);
send_command(B00111100); //Function set
delay(100);
send_command(B00111100); //Function set
delay(100);
send_command(B00111100); //Function set
send_command(B00001000); //Display off
send_command(B00000001); //Display clear
send_command(B00000111); //Entry mode set
send_command(B00001100); //Display on
send_command(B10000000); //set DDRAM address
send_char(B11000010); // ツ
send_char(B10111000); // ク
send_char(B10101111); // ッ
send_char(B11000011); // テ
send_char(B11010000); // ミ
send_char(B11011001); // ル
send_command(B11000000); //set DDRAM address
send_char(B01001000); // H
send_char(B01000100); // D
send_char(B00110100); // 4
send_char(B00110100); // 4
send_char(B00110111); // 7
send_char(B00111000); // 8
send_char(B00110000); // 0
send_command(B00001100); //Display on
}
実行する

プログラムをマイコンに書き込んで実行してみると文字が表示されました。
表示のコントラストは半固定抵抗をドライバーで回して調節します。
一番文字が見やすくなるところで止めます。
今回のコード全文は以下。
#include <Wire.h>
void send_command(byte command_data);
void send_char(byte char_data);
void setup()
{
Wire.begin();
delay(100);
send_command(B00111100); //Function set
delay(100);
send_command(B00111100); //Function set
delay(100);
send_command(B00111100); //Function set
delay(100);
send_command(B00111100); //Function set
send_command(B00001000); //Display off
send_command(B00000001); //Display clear
send_command(B00000111); //Entry mode set
send_command(B00001100); //Display on
send_command(B10000000); //set DDRAM address
send_char(B11000010);
send_char(B10111000);
send_char(B10101111);
send_char(B11000011);
send_char(B11010000);
send_char(B11011001);
send_command(B11000000); //set DDRAM address
send_char(B01001000);
send_char(B01000100);
send_char(B00110100);
send_char(B00110100);
send_char(B00110111);
send_char(B00111000);
send_char(B00110000);
send_command(B00001100); //Display on
}
void send_command(byte command_data)
{
Wire.beginTransmission(0x3F);
Wire.write(B00000000);
Wire.write(command_data);
Wire.endTransmission();
}
void send_char(byte char_data)
{
Wire.beginTransmission(0x3F);
Wire.write(B01000000);
Wire.write(char_data);
Wire.endTransmission();
}
void loop()
{
// put your main code here, to run repeatedly:
}
あとがき
パラレル接続のキャラクタLCDについても以下の記事で解説しました。
ここで使っているSeeeduino Nanoを使うと
レベル変換モジュールも必要なく接続が簡単になります。
(シリアル編でもSeeeduino Nano使えばよかった。)
コメント