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()

Share post

Related Posts

コメント