0. はじめに
aitendo製『I2CキャラクタLCDモジュール★16x2★[ATD1602C-P]』を組み立て、ArduinoとRaspberry Pi Zeroに接続するまでの流れをまとめておく。
価格は税別550円とリーズナブルで、いちいちシリアルモニタに出さなくてもLCD出力で用が足りる時のために購入した。
1. 組み立て

このLCDモジュールは組み立てキットのため、ハンダ付けが必要である。組み立てに関する説明書等は一切ないため、商品ページの説明及び商品写真だけで組み立てる必要がある。とはいえ、部品は全部で5点だけのため普段からハンダ付けしている方にとっては、難しくは無いだろう。
部品リスト
- I2CキャラクタLCDモジュール
- LEDバックライトユニット
- キャリー基板
- FFCコネクタ
- チップコンデンサ(2個)
ハンダ付けで一番厄介なのが、12ピンFFCコネクタである。おそらくリフローが一番楽だと思うが、リフロー炉(ホットプレート)を持っていないので、手ハンダで行った。

ちょっとハンダがもっこりしているが、無事にハンダ付けできた。上記の写真では影になって見えにくいが、コネクタ両サイドの基板に固定させる爪部分はそれほど横に出ていないので、ここのハンダ付けの際にコテ先がコネクタに触れてしまってコネクタ横を少し溶かしてしまった。反対側は気を付けたので大きな失敗なくできた。このモジュールの組み立て時の最大の難所だと思う。
続いて、1206サイズのチップコンデンサ2個もハンダ付けする。LEDバックライトユニットの電源の配線は、LCDユニットを基板に取り付けてから最後に行う。
(後述するが、ピンヘッダーのハンダ付けはここのタイミングで行うと楽だと思う。)
次はLEDバックライトユニットにLCDモジュールを取り付ける。LCDを取り付ける側には、薄いプラスチックフィルムが貼られているので、まず、これを剥がす。(下記写真)ピンセットでつまんで剥がした時の様子。
続いて、両面テープが上下に貼ってあるので、その剥離紙を剥がしLCDモジュールを置いて貼り付ける。(下記写真)上部の両面テープの幅は非常に狭い。
裏返して基板に貼る側の剥離紙を剥がし、基板に固定する。(下記写真)上下の両面テープの幅は同じぐらい。
(下記写真)基板に貼り付けた様子。LCDのフラットケーブルとバックライトの電源ケーブルは、基板裏側に通しておく。
(下記写真)基板裏側の様子。最後にバックライトの電源ケーブル赤黒の2本を基板のランドにハンダ付けする。

最後にLCDのフラットケーブルをFFCコネクタに接続する。さらに、手持ちのピンヘッダをハンダ付けして組み立ては完了。ピンヘッダは付属していなかったので忘れていた。本来なら、ピンヘッダのハンダ付けは、コンデンサの半田付け後がよい。

2. Arduinoで動作確認
ここで注意が必要なのは、このLCDモジュールの電源及びロジックレベルは3.3V仕様であることである。5V仕様のArduino Uno等に普通に接続すると、このモジュールを破壊する可能性がある。その場合は、ロジックレベル変換が必要。
今回は、ロジックレベルが3.3VであるSeeeduino XIAOを使用する。
ピンアサインは次の通り。
LCDモジュール | Seeduino XAIO |
---|---|
LED_A | D6 |
RST | D6 |
SCL | SCL (A5) |
SDA | SDA (A4) |
GND | GND |
VIN | 3V3 |
テスト用のスケッチは、このLCDモジュールの商品ページで紹介されている、Sim's blogさんのスケッチを参考にさせていただいき、下記のコードで確認した。
#include <Wire.h>
int resetPin = 6;
int i2cadr = 0x3e;
byte contrast = 40; // 0-63
void lcd_cmd(byte x) {
Wire.beginTransmission(i2cadr);
Wire.write(0x00);
Wire.write(x);
Wire.endTransmission();
delay(2);
}
void lcd_data(byte x) {
Wire.beginTransmission(i2cadr);
Wire.write(0x40);
Wire.write(x);
Wire.endTransmission();
delay(2);
}
void lcd_puts(const char *s) {
while (*s) lcd_data(*s++);
}
void lcd_init() {
// reset
delay(500);
pinMode(resetPin, OUTPUT);
digitalWrite(resetPin, LOW);
delay(10);
digitalWrite(resetPin, HIGH);
delay(10);
// LCD initialize
delay(40);
Wire.begin();
lcd_cmd(0x38); // function set
lcd_cmd(0x39); // function set
lcd_cmd(0x14); // interval osc
lcd_cmd(0x70 | (contrast & 15)); // contrast low
lcd_cmd(0x5c | (contrast >> 4 & 3)); // contrast high / icon / power
lcd_cmd(0x6c); // follower control
delay(300);
lcd_cmd(0x38); // function set
lcd_cmd(0x0c); // display on
delay(2);
}
void lcd_move(byte pos) {
lcd_cmd(0x80 | pos);
}
void setup() {
lcd_init();
}
void loop() {
lcd_cmd(0x01); // clear display
delay(1000);
lcd_puts("Hello, Arduino!");
lcd_move(0x40);
lcd_puts("i2c LCD module");
delay(1000);
}
下記写真のように、無事に表示できた。しかし、最初は上手くいかず、色々調べる中でいくつか分かったことがあるので記しておく。
注)バックライトは相当明るい。
a) SDA/SCLのプルアップ抵抗が必要な場合がある
このLCDモジュールの商品説明ページには、『プルアップ抵抗はなくても使用可能』と明記されているが、今回使用したSeeeduino XIAOでは、SDA/SCLと3v3との間に10KΩのプルアップ抵抗を入れないと動かなかった。これは、使用するArduinoボードに依るところが大きいと思うが、キャリー基板上にプルアップ用のチップ抵抗をハンダ付けするためのランドが用意されている。(下記写真)パターンを調べたところ、R1がSDA用、R2がSCL用。固定的に使用するなら、ここにプルアップ抵抗をハンダ付けするのが配線上は楽だと思う。
なお、このArduino互換機では、プルアップ抵抗不要で表示できた。このフォーラムの記事によると、Arduino Unoは、回路上のプルアップ抵抗はないが、マイコンの内部プルアップが有効になっているそうだ。
b) SPLC792A信号
LCDコントローラに使用しているSPLC792Aのデータシートと公開されている接続回路図から、次のことが分かった。
- VOUTとVSSの間にコンデンサを接続している。(内蔵ブースターを使用)
- VINはVDDに接続している。(ブースター用電源入力)
- EXT=1(追加の命令セットを選択)
このLCDモジュールは↑そういう使い方をしているということである。
c) 表示方向が不安定
キャリー基板上に表示方向を決める2つの信号(DIRC/SHL)のジャンパランドが用意されているので、ここをハンダ付けして向きを固定するのが良い。先ほどはこの信号をオープンにしていたため、表示方向が不安定になったと思われる。
色々な向きで使用するのであれば、ここにワイヤーをハンダ付けして適用なデジタルピンに接続すればプログラムから動的に決めることもできる。
SEG \ COM |
SHL:L | SHL:H |
---|---|---|
DIRC:L | ![]() |
![]() |
DIRC:H | ![]() |
![]() |
上記の通りの表示となったが、両信号ともLOWの時が正面通常の向きでないことが気になる。勝手な想定だが、テストスケッチのLCDイニシャル処理で送信しているコマンドと関係があるのでないかと考え、今後、使用しているコマンドを解析して解明したい。
3. Raspberry Pi Zeroに接続
Raspberry PiのSDA/SCLは、基板上で1.8KΩの抵抗でプルアップされているそうだ。このため、このLCDはそのままでは接続できないようだ。事実、このLCDをRaspberry Pi Zeroに接続してi2cdetectコマンドを叩いてもi2cのスレーブアドレスは検出できなかった。
こちらの記事に対処法が載っていた。
どうやら、標準のI2CとRasPiが採用しているSMBusでは、HIGH/LOWの電圧レベルに違いがあるため、そのままではお互いは通信できないそうだ。
対処法
1) 3KΩの抵抗でSDAをプルダウンする
手持ちに3KΩの抵抗がなかったので、3.3KΩの抵抗を使って試したが上手くいかず(2.2KΩでもNG)
2) バスリピータを入れる
I2Cバスリピータを経由して相互を接続すると解決するとのことであった。さっそく、部品を調達しハンダ付けしてDIP化した。

その結果、下記写真のように無事にRaspberry Piからも表示できることが確認できた。
プログラムは、既出のArduinoスケッチをPythonに書き直しただけだ。
import smbus
import time
import RPi.GPIO as GPIO
i2c = smbus.SMBus(1) # 1 is bus number
GPIO.setmode(GPIO.BOARD)
resetPin = 7
i2cadr = 0x3e
contrast = 40
def delay(ms):
time.sleep(ms / 1000)
def lcd_cmd(cmd):
i2c.write_byte_data(i2cadr, 0x00, cmd)
delay(2)
def lcd_data(char):
i2c.write_byte_data(i2cadr, 0x40, char)
delay(2)
def lcd_puts(str):
for char in str:
lcd_data(ord(char))
def lcd_init():
# reset
delay(500)
GPIO.setup(resetPin, GPIO.OUT)
GPIO.output(resetPin, False)
delay(10)
GPIO.output(resetPin, True)
delay(10)
# LCD initialize
delay(40)
lcd_cmd(0x38) # function set
lcd_cmd(0x39) # function set
lcd_cmd(0x14) # interval osc
lcd_cmd(0x70 | (contrast & 15)) # contrast low
lcd_cmd(0x5c | (contrast >> 4 & 3)) # contrast high / icon / power
lcd_cmd(0x6c) # follower control
delay(300)
lcd_cmd(0x38) # function set
lcd_cmd(0x0c) # display on
delay(2)
def lcd_move(pos):
lcd_cmd(0x80 | pos)
lcd_init()
while True:
lcd_cmd(0x01) # clear display
delay(1000)
lcd_puts("Hello, RasPi!")
lcd_move(0x40)
lcd_puts("i2c LCD module")
delay(1000)
Wifi接続時の自IPアドレスの表示や、デジタル時計等で簡単に使えるように、今後、LCD出力処理をコマンド化しておこうと思う。
おわりに
今回も先人が残してくれた情報をもとに当初の目的を達成することができた。毎度思うことだが本当にありがたい。
この記事も誰かの何かの役に立てれば幸いである。
以上