I2C LCDディスプレイ(16x2)の使い方:Arduino、ESP32、Pico
16x2のI2C LCDをArduinoにつなぐには?4本の配線、I2Cアドレス(0x27、0x3F)の調べ方、LiquidCrystal_I2Cライブラリ、コントラスト調整、カスタム文字、スクロール表示まで解説します。
16文字×2行を表示できる16x2 LCDは、Arduinoの世界でもっとも普及しているディスプレイです。温度や距離などの測定値、メニュー、時計、ゲームのスコアの表示に使われます。ディスプレイ本体には16本のピンがあり、単体では少なくとも6本のデジタルピンが必要ですが、裏にはんだ付けされた小さなI2Cモジュールのおかげで、データ線はたった2本で済みます。この記事では、I2C LCDのつなぎ方、アドレスの調べ方、好きな内容を表示する方法をステップごとに紹介します。

LCDディスプレイはどう動く?
これらのディスプレイはHD44780というドライバチップで動いています。1文字は5x8ピクセルの小さな枠に描かれ、チップには英字、数字、いくつかの記号を収めた文字テーブルが内蔵されています。Arduinoは「この位置にこの文字を書く」という命令を送るだけで、文字をピクセルに変えるのはディスプレイの仕事です。LEDバックライトのおかげで暗い場所でも文字が読め、液晶の層がピクセルを暗くすることで文字を形づくります。
I2Cとは?なぜ配線が楽になるのか
I2Cは、複数の機器が2本の線で通信するための方式です。SDAがデータを、SCLがクロック信号を運びます。各機器には固有のアドレスがあり、Arduinoはそのアドレスで目的の機器を呼び出します。LCDモジュールは通常、0x27か0x3Fのアドレスを使います。時計モジュール、OLEDディスプレイ、BME280などのセンサーも同じ2本の線を共有でき、アドレスが重ならなければすべて一緒に動きます。

モジュールに載っているPCF8574チップは、I2Cで届いた命令をディスプレイが必要とする8本のパラレル信号に変換します。I2Cモジュールなしでもディスプレイは使えますが、その場合は6本のピン、ポテンショメーター、たくさんの配線が必要です。モジュールを使えばピンを節約でき、回路もすっきりします。
仕様
| 項目 | 値 |
|---|---|
| 表示 | 16列×2行の文字 |
| 文字サイズ | 5 × 8ピクセル |
| ドライバチップ | HD44780(または互換品) |
| I2Cアダプター | PCF8574 / PCF8574A |
| 初期アドレス | 0x27(PCF8574)または0x3F(PCF8574A) |
| 電源 | 5 V、バックライト点灯時に約20〜30 mA |
| 接続 | GND、VCC、SDA、SCL |
I2C LCDの配線:Arduino、ESP32、Pico
配線はどのボードでも同じ4本で、変わるのはSDAとSCLがどのピンにあるかだけです。お使いのボードのI2Cピンはピン配置ツールで確認できます。
| LCDのピン | Arduino Uno / Nano | Arduino Mega | ESP32 | Raspberry Pi Pico |
|---|---|---|---|---|
| GND | GND | GND | GND | GND |
| VCC | 5V | 5V | VIN (5V) | VBUS (5V) |
| SDA | A4 | 20 | GPIO 21 | GP4 |
| SCL | A5 | 21 | GPIO 22 | GP5 |
I2Cアドレスを調べる:スキャナースケッチ
ディスプレイのアドレスがわからない場合は、下のコードを書き込んでください。1から126までのすべてのアドレスを試し、応答した機器のアドレスをシリアルモニタに表示します。このアドレスはディスプレイの設定で使います。
1#include <Wire.h>
2
3void setup() {
4 Wire.begin();
5 Serial.begin(9600);
6 Serial.println("I2C taranıyor / scanning...");
7 for (byte addr = 1; addr < 127; addr++) {
8 Wire.beginTransmission(addr);
9 if (Wire.endTransmission() == 0) { // cihaz cevap verdi / device answered
10 Serial.print("Bulundu / found: 0x");
11 Serial.println(addr, HEX);
12 }
13 }
14}
15
16void loop() {
17}ライブラリのインストールと文字の表示
ライブラリマネージャでLiquidCrystal I2Cを検索し、Frank de Brabander作のライブラリをインストールします。下のコードは1行目にあいさつを、2行目にArduinoが起動してからの秒数を表示します。
1#include <Wire.h>
2#include <LiquidCrystal_I2C.h>
3
4LiquidCrystal_I2C lcd(0x27, 16, 2); // adres, sütun, satır / address, columns, rows
5
6void setup() {
7 lcd.init();
8 lcd.backlight(); // arka ışığı aç / backlight on
9 lcd.setCursor(0, 0); // sütun 0, satır 0 / column 0, row 0
10 lcd.print("Merhaba Dunya!");
11}
12
13void loop() {
14 lcd.setCursor(0, 1); // ikinci satır / second row
15 lcd.print("Sure: ");
16 lcd.print(millis() / 1000); // saniye / seconds
17 lcd.print(" sn "); // eski rakamları sil / clear old digits
18 delay(200);
19}よく使うLCDの命令
| 命令 | 働き |
|---|---|
| lcd.init() | ディスプレイを初期化します。setup()で1回呼び出します。 |
| lcd.backlight()、lcd.noBacklight() | バックライトをオン・オフします。 |
| lcd.setCursor(列, 行) | 文字を書き始める位置を決めます。数え方は0から始まります。 |
| lcd.print(値) | 文字や数値を表示します。 |
| lcd.clear() | 画面全体を消し、カーソルを先頭に戻します。 |
| lcd.scrollDisplayLeft() | 画面全体を1文字ぶん左にずらします。 |
| lcd.blink()、lcd.cursor() | 点滅カーソルまたは下線カーソルを表示します。 |
| lcd.createChar(番号, 配列) | カスタム文字を0〜7番の枠に登録します。 |
スクロールする文字
16文字より長い文字列を表示するには、画面をスクロールさせます。下のコードは文字を表示したあと300ミリ秒ごとに左へずらすので、長いメッセージが電光掲示板のように流れていきます。
1#include <Wire.h>
2#include <LiquidCrystal_I2C.h>
3
4LiquidCrystal_I2C lcd(0x27, 16, 2);
5
6void setup() {
7 lcd.init();
8 lcd.backlight();
9 lcd.print("BlueGrays ile elektronik ogren"); // 16 karakterden uzun / longer than 16 chars
10}
11
12void loop() {
13 lcd.scrollDisplayLeft(); // bir adım sola / one step left
14 delay(300);
15}カスタム文字と特殊な文字
HD44780の文字テーブルにはş, ğ, ı, ö, ü, ç(あるいはéやñ)のようなアクセント付きの文字がなく、表示しようとすると意味のない記号が出ます。解決策は、最大8個の5x8ピクセルのカスタム文字を定義することです。各行を1バイトで書き、1にしたビットが点灯するピクセルになります。下の例ではハートを描いていますが、アクセント付きの文字も同じ方法で描けます。
1byte heart[8] = {
2 0b00000,
3 0b01010,
4 0b11111,
5 0b11111,
6 0b01110,
7 0b00100,
8 0b00000,
9 0b00000
10};
11
12// setup() içinde / inside setup()
13lcd.createChar(0, heart); // 0. yuvaya kaydet / store in slot 0
14lcd.setCursor(15, 0);
15lcd.write(byte(0)); // kalbi göster / show the heartESP32とRaspberry Pi PicoでI2C LCDを使う
ESP32では同じArduinoのコードとライブラリがそのまま動きます。Wire.begin()は標準でGPIO 21(SDA)とGPIO 22(SCL)を使います。別のピンを使いたい場合はWire.begin(SDA, SCL)と書きます。MicroPythonを使うRaspberry Pi Picoでは、lcd_api.pyとpico_i2c_lcd.pyという2つの小さなファイルをPicoにコピーし、次のように使います。
1from machine import I2C, Pin
2from pico_i2c_lcd import I2cLcd # Pico'ya kopyalanan dosya / file copied to the Pico
3
4i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)
5addr = i2c.scan()[0] # ilk bulunan adres / first found address
6lcd = I2cLcd(i2c, addr, 2, 16) # 2 satır, 16 sütun / 2 rows, 16 columns
7
8lcd.putstr("Merhaba Pico!")
9lcd.move_to(0, 1) # sütun 0, satır 1 / column 0, row 1
10lcd.putstr("BlueGrays")I2C LCDのプロジェクトアイデア
- デジタル温度計:温度と湿度をディスプレイに表示します。センサー側はDHT11温湿度センサーを参照してください。
- 距離表示器:HC-SR04で測った距離をセンチメートルで表示します。詳しくはHC-SR04距離センサーで解説しています。
- デジタル電圧計:アナログピンで読み取った電圧を表示します。
- 暗証番号ロック:キーパッドで入力したコードをアスタリスクで表示します。
- メニューシステム:ポテンショメーターや2つのボタンで画面上の選択肢を移動します。
- ミニゲーム:カスタム文字で描いたランナーに障害物をよけさせます。
よくあるミスと直し方
- ディスプレイは光るが文字が出ない:コントラストが合っていません。半固定抵抗(トリマー)を回してください。
- 上の行に黒い四角が並ぶ:電源は来ていますが、ディスプレイが初期化されていません。アドレスが違う、SDAとSCLが逆になっている、またはlcd.init()を呼んでいない可能性があります。
- アドレスが違う:コードは0x27なのにディスプレイは0x3F、というケースです。スキャナースケッチで本当のアドレスを調べてください。
- 古い数字が残る:100から99に減った数値が990と表示されます。数値のあとにスペースをいくつか表示してください。lcd.clear()でも直りますが遅く、ループの中で頻繁に呼ぶと画面がちらつきます。
- アクセント付きの文字が化ける:ディスプレイの文字テーブルにない文字です。カスタム文字を定義するか、使わないようにしてください。
- 文字がランダムに乱れる:長くたるんだ配線や、モーターのようなノイズの多い部品がI2Cバスを乱すことがあります。配線は短くし、モーターは別の電源から給電してください。
ディスプレイとセンサーを組み合わせるのが、初めての本格的なプロジェクトを作るいちばんの近道です。BlueGraysアプリには、回路図とすぐに使えるコードが付いたI2C LCDのプロジェクトが数十個あります。つまみで値を変えたいときはポテンショメーターとは?が役に立ちます。
よくある質問
LCDに黒い四角しか表示されないのはなぜですか?
上の行に黒い四角が並ぶのは、電源は来ているのにディスプレイが初期化されていない状態です。アドレスが違う、SDAとSCLが逆になっている、またはコントラストが高すぎる可能性があります。まずI2Cスキャナースケッチでアドレスを確認し、次に半固定抵抗(トリマー)を調整してください。
I2C LCDのアドレスは0x27と0x3Fのどちらですか?
PCF8574チップのモジュールは通常0x27、PCF8574Aのモジュールは0x3Fを使います。いちばん簡単な確認方法はI2Cスキャナースケッチで、あとはコードをLiquidCrystal_I2C lcd(0x3F, 16, 2)に変えるだけです。
1台のArduinoにLCDを2台つなげますか?
はい。モジュールのA0、A1、A2のはんだパッドをショートさせるとアドレスが変わるので、最大8台のLCDが同じ2本の線を共有できます。コードでは、ディスプレイごとにそれぞれのアドレスで別のオブジェクトを定義します。
20x4 LCDでも同じコードは動きますか?
はい。宣言をLiquidCrystal_I2C lcd(0x27, 20, 4)に変えるだけです。行は0〜3、列は0〜19になります。
LCDにアクセント付きの文字や特殊文字を表示するには?
ディスプレイの内蔵テーブルには、é、ñ、ş、ğのような文字は含まれていません。それぞれをlcd.createChar()で5x8ピクセルのカスタム文字として描き、lcd.write()で表示します。一度に定義できるカスタム文字は最大8個であることを覚えておきましょう。
LCDとOLEDディスプレイ、どちらを使うべきですか?
LCDは安く、日光の下でも読みやすく、文字や数値の表示に最適です。OLEDは小さくてコントラストが高く、グラフィックやアイコンも描けますが、同じ画像を長時間表示すると焼き付きが起きることがあります。文字ならLCD、グラフィックならOLEDを選びましょう。
この記事を読んだ後に作れるプロジェクト
全プロジェクトを見る
I2CでLCDディスプレイを使う
Arduinoにディスプレイを接続し、最初のメッセージを表示します。2行のLCDディスプレイは数本の配線だけで接続できます。まず上の行にあいさつを表示し、次に下の行にもう1つのメッセージを表示します。その後、表示を消去して最初から繰り返します。温度や時刻、スコアを表示するプロジェクトは、すべてこのステップから始まります。

2x16 LCDディスプレイにメッセージを表示
ディスプレイに文字を表示するための最初のステップです。2行のLCDディスプレイにまず待機メッセージを表示し、次に上の行にあいさつを表示します。下の行にはタイプライターのように単語を1文字ずつ表示し、その後ディスプレイを消去して最初から繰り返します。文字の表示位置を指定する方法を、実際の表示で確かめられます。

LCDで文字が左右に跳ね返るアニメーション
LCDディスプレイの上の行でBLUEGRAYSという文字が端から端へ動き、壁に当たるボールのように跳ね返る動きを繰り返します。必要なのはArduino、2x16 LCDディスプレイ、文字の見やすさを調整する可変抵抗だけです。文字のスクロールや簡単な表示アニメーションを作る最初のステップです。

ESP32 I2C LCDディスプレイ(16x2)
このプロジェクトでは、16x2文字のLCDをI2CでESP32に接続して文字を表示します。I2Cならデータ用の2本のピン(SDAとSCL)だけで制御でき、従来のパラレル接続のように6本以上のピンを使わずに済みます。コードでは1行目に固定メッセージ、2行目に毎秒増えるカウンターを表示します。また、起動時にI2Cスキャナーを実行し、ディスプレイのアドレス(通常は0x27または0x3F)をシリアルモニタに表示します。

DHT11で温度と湿度を測定
部屋の温度は何度で、空気は湿っているでしょうか、それとも乾燥しているでしょうか?DHT11センサーが温度と湿度を測定し、Arduinoが2行のLCDディスプレイに値を表示して、数秒ごとに更新します。センサーに異常があればエラーメッセージが表示されます。自分だけの小さな気象観測装置を作る第一歩です。

LCDディスプレイ付きデジタル電圧計
自作の測定器で、電池や電源アダプターが出力する電圧を調べます。2つの抵抗で作る分圧回路が、高い電圧をボードで読み取れるレベルまで下げます。Arduinoが元の電圧を計算し、2行のLCDディスプレイにボルト単位で表示します。この回路では約55ボルトまでの直流電圧を測定できます。コンセントの商用電源には絶対に接続しないでください。

4x4キーパッドとLCDで暗証番号ロック
正しい暗証番号を知らないと開けられない、小さな電子ドアロックです。ハッシュキーを押してキーパッドから暗証番号を入力します。正しければ画面に入室許可が表示され、緑のLEDが点灯し、サーボモーターがドアを5秒間開けてから再び閉めます。間違っていれば赤のLEDが点灯します。建物や金庫のロックの仕組みを自分で作ります。

Arduino LCDランナーゲーム
16x2文字のLCDディスプレイで動作する横スクロール型のエンドレスランナーゲームです。キャラクターは自動で走り、ボタンを押すとジャンプして障害物を飛び越えます。障害物は上段と下段にランダムに現れます。パッシブブザーで開始時のメロディー、ジャンプ音、50点獲得を祝う音、ゲーム終了時のメロディーを鳴らします。起動時には「BlueGrays — Arduino Projects」の画面を表示します。スコアは画面右上でリアルタイムに更新されます。
ほかの記事
BlueGraysアプリ
この回路をスマホでステップごとに作る
回路図、コード、部品リストを1つの画面で確認できます。Arduino、ESP32、Picoのプロジェクトを200件以上用意しています。

