MicroPythonを入れたESP32でモノクロ反射型TFTメモリ液晶LS027B4DH01を表示してみる(GPIOで制御)
2020/08/09 categories:ESP32| tags:ESP32|MicroPython|LS027B4DH01|
ESP32でグラフィック液晶を扱ってみるためにLS027B4DH01に表示するプログラムをMicroPythonで書いてみました。とりあえず表示してみるだけなので、ESP32のSPI通信機能ではなく、GPIOをON/OFFするだけで表示してみました。
LS027B4DH01の電気的特性
特性は下記の通りで、電源は5V、入力信号は2.7V~電源電圧までとなっています。入力のHiは3V付近が推奨みたいなので、マイコンは3.3Vで動作させて液晶の電源は5Vに昇圧した電源を用意するのが良さそうです。
項目 | Min | Typ | Max |
---|---|---|---|
アナログ電源 | 4.8 | 5 | 5.5 |
ロジック電源 | 4.8 | 5 | 5.5 |
Hi | 2.7 | 3 | ロジック電源 |
Low | VSS | VSS | VSS+0.15 |
LS027B4DH01のピンアサイン
液晶を裏から見たときに左から1番ピンのようです。
ピンに対する機能は下記の通りです。
端子 | 記号 | I/O | 機能 |
---|---|---|---|
1 | SCLK | INPUT | シリアルクロック信号 |
2 | SI | INPUT | シリアル入力信号 |
3 | SCS | INPUT | チップセレクト信号 |
4 | EXTCOMIN | INPUT | 外部COM反転信号入力(H:有効) |
5 | DISP | INPUT | ディスプレイON/OFF信号 |
6 | VDDA | POWER | アナログ電源 |
7 | VDD | POWER | デジタル電源 |
8 | EXTMODE | INPUT | COM反転モード切替端子です。 |
9 | VSS | POWER | ロジックGND |
10 | VSSA | POWER | アナログGND |
ESP32とLS027B4DH01の接続
下記のように接続しました。今回はESP32のSPI通信機能は使わないのですが、次回はSPI通信機能を使って表示してみたいと思うのでSPIのデフォルトピンに接続することにしました。
初期化
初期化のフローは下記の通りです。
DISPオフ → SIオフ → SCLKオフ → SCSオフ → Clear all → DISPオン
コードにすると下記のような感じです。
def initialize(self):
self.disp.off()
utime.sleep_us(500)
self.si.off()
self.sclk.off()
self.scs.off()
self.clear_all()
utime.sleep_ms(5)
self.disp.on()
データの更新
LS027B4DH01にはデータの更新モードが2種類あり、1ライン更新するモードと複数ライン更新するモードがあるようです。今回は1ライン更新するモードでプログラムを作成してみました。このモードでは以下の手順でデータを送信します。
SCSピンオン → データ送信 → SCSピンオフ
データの送信内容は下記の通りです。
モード選択 | アドレス選択 | データ書き込み | ダミーデータ転送 |
---|---|---|---|
8ビット | 8ビット | 400ビット | 16ビット |
1ラインのデータ更新モードのコードは下記の通りです。関数の引数のlineがライン番号で、data_arrayが1ライン分のデータの50バイトの配列としました。
def update_one_line(self, line, data_array):
self.scs.on()
# send mode
self.send_one_byte(0b00000001)
# send gate line address
self.send_one_byte(line)
# send data
for data in data_array:
self.send_one_byte(data)
# dummy data
self.send_one_byte(0)
self.send_one_byte(0)
self.scs.off()
動作イメージ
5の倍数のラインを黒く塗る動作をしてみました。
ソースコード
import utime
from machine import Pin, PWM
class LS027B4DH01():
def __init__(self):
self.data = None
self.array = bytearray(12000)
self.sclk, self.si, self.scs = None, None, None
self.extcomin, self.disp = None, None
def send_one_byte(self, buffer):
for i in range(8):
self.si.value( buffer & 0x01 )
buffer = buffer >> 1
self.sclk.on()
self.sclk.off()
self.si.off()
def update_one_line(self, line, data_array):
self.scs.on()
# send mode
self.send_one_byte(0b00000001)
# send gate line address
self.send_one_byte(line)
# send data
for data in data_array:
self.send_one_byte(data)
# dummy data
self.send_one_byte(0)
self.send_one_byte(0)
self.scs.off()
def clear_all(self):
self.disp.off()
self.scs.on()
utime.sleep_us(3)
self.send_one_byte(0x04)
self.send_one_byte(0x00)
utime.sleep_us(3)
self.scs.off()
utime.sleep_us(5)
self.disp.on()
def initialize(self):
self.disp.off()
utime.sleep_us(500)
self.si.off()
self.sclk.off()
self.scs.off()
self.clear_all()
utime.sleep_ms(5)
self.disp.on()
def main():
print('hello')
lcd = LS027B4DH01()
lcd.sclk = Pin(18, Pin.OUT)
lcd.si = Pin(23, Pin.OUT)
lcd.scs = Pin(32, Pin.OUT)
lcd.extcomin = Pin(33, Pin.OUT)
lcd.disp = Pin(25, Pin.OUT)
lcd.initialize()
lcd.disp.on()
print('initialized')
white_line = [0xFF] * 50
black_line = [0] * 50
while True:
print('update array')
for y in range(240):
if int( (y / 10) % 2 ) == 1:
lcd.update_one_line(y, white_line)
else:
lcd.update_one_line(y, black_line)
print('clear all')
lcd.clear_all()
print('update array')
for y in range(240):
if int( (y / 10) % 2 ) == 0:
lcd.update_one_line(y, white_line)
else:
lcd.update_one_line(y, black_line)
print('clear all')
lcd.clear_all()
if __name__ == "__main__":
main()