Color LCD(2)

aitendo1.8インチ液晶withキャリーボードをPythonで制御する場合は、既存のSPI用拡張モジュールを使用するのが手っ取り早い。

Raspberry Pi用のモジュールは何種類か存在しているようだが、今回は spidev をインストールして使ってみた。例によってパッケージ管理ツールpipを使って、以下のようにインストールする。

% sudo pip install spidev

ちなみに既にインストールされているパッケージを表示する場合は、以下のようにfreezeオプションを付けて実行する。

% sudo pip freeze

spidevモジュールを使ったSPI接続液晶のテストプログラムは、以下のようになる。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import RPi.GPIO as GPIO
import spidev           # sudo pip install spidev
import time

class ST7735:
    def __init__(self):
        self.spi = spidev.SpiDev()
        self.spi.open(0, 0)
        self.spi.max_speed_hz = 16000000
        GPIO.setmode(GPIO.BCM)
        GPIO.setwarnings(False)
        GPIO.setup(24, GPIO.OUT)
        GPIO.setup(25, GPIO.OUT)
        self.reset()
        self.write_cmd(0x11)
        time.sleep(0.12)
        self.write((0xB1, 0x01, 0x2C, 0x2D))
        self.write((0xB2, 0x01, 0x2C, 0x2D))
        self.write((0xB3, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D))
        self.write((0xB4, 0x07))
        self.write((0xC0, 0xA2, 0x02, 0x84))
        self.write((0xC1, 0xC5))
        self.write((0xC2, 0x0A, 0x00))
        self.write((0xC3, 0x8A, 0x2A))
        self.write((0xC4, 0x8A, 0xEE))
        self.write((0xC5, 0x0E))
        self.write((0x36, 0xC8))
        self.write((0xE0, 0x02, 0x1C, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2D, 0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10))
        self.write((0xE1, 0x03, 0x1D, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D, 0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x10))
        self.write((0x2A, 0x00, 0x02, 0x00, 0x81))
        self.write((0x2B, 0x00, 0x01, 0x00, 0xA0))
        self.write((0x3A, 0x05))
        self.write_cmd(0x29)
    def reset(self):
        GPIO.output(25, False)
        time.sleep(0.1)
        GPIO.output(25, True)
        time.sleep(0.1)
    def write_cmd(self, cmd):
        GPIO.output(24, False)  # RS=0
        self.spi.xfer2([cmd])
    def write_data(self, data):
        GPIO.output(24, True)   # RS=1
        self.spi.xfer2([data])
    def write(self, cmd):
        if len(cmd) == 0:
            return
        GPIO.output(24, False)  # RS=0
        self.spi.xfer2([cmd[0]])
        GPIO.output(24, True)   # RS=1
        self.spi.xfer2(list(cmd[1:]))
    def write_rgb(self, r, g, b):
        self.write_data(r & 0xF8 | g >> 5)
        self.write_data(g & 0xFC << 3 | b >> 3)
    def fill(self, r, g, b):
        self.write((0x2A, 0x00, 0x02, 0x00, 0x81))
        self.write((0x2B, 0x00, 0x01, 0x00, 0xA0))
        self.write_cmd(0x2C)
        for i in range(160):
            for n in range(128):
                self.write_rgb(r, g, b)
        
if __name__ == "__main__":
    lcd = ST7735()
    lcd.write_cmd(0x2C)
    try:
        while True:
            lcd.fill(0, 0, 0)   # Fill Black
            for i in range(160):
                for n in range(128):
                    if i < 22:
                        lcd.write_rgb(0xFF, 0xFF, 0xFF) # White
                    elif i < 44:
                        lcd.write_rgb(0xFF, 0xFF, 0x00) # Yellow
                    elif i < 66:
                        lcd.write_rgb(0x00, 0xFF, 0xFF) # Cyan
                    elif i < 88:
                        lcd.write_rgb(0x00, 0xFF, 0x00) # Green
                    elif i < 110:
                        lcd.write_rgb(0xFF, 0x00, 0xFF) # Magenta
                    elif i < 132:
                        lcd.write_rgb(0xFF, 0x00, 0x00) # Red
                    else:
                        lcd.write_rgb(0x00, 0x00, 0xFF) # Blue
            time.sleep(3)
    except KeyboardInterrupt:
        print '\nbreak'
    GPIO.cleanup()

実行すると黒一色で画面が塗りつぶされて、そのあと白、黄色、シアン、緑、マゼンタ、赤、青のカラーバーが表示されるはず。

2013-12-04 14.46.53

液晶モジュールで使用されているST7735コントローラチップは、1バイトのコマンドの後に複数バイトのデータを続けて送信する方式になっていて、コマンドとデータはRSピンによって切り替える。RSピンがL(0)の時はコマンド、H(1)の時はデータとして認識される。

コントローラの初期化時に画面の描画領域を0x2Aと0x2Bコマンドで設定していて、液晶の画素数が128×160なのにも係わらず、横が2~129、縦が1~160で設定しているのでずれているように思えるが、これはサンプルプログラムの初期化処理をそのまま持ってきたからで、実際に試してみると画面の左上隅のピクセル座標は(0,0)ではなく、(2,1)という値になっていた。

なぜそうなっているのか、理由は良く分からない。製造上の理由?

ちょっと面白いのが、この液晶コントーラはメモリへの書き込みコマンドにアドレス指定のパラメータが無く、事前に設定されている表示領域に対して、自動的に順次書き込まれるような動きをする。設定領域の右端まで書き込んだら、自動的に次のラインの左端から書き込まれる。

ブラウン管の走査線と似たようなイメージだと思ったが、それを意識しているのかは不明。おかげで画像ファイルを表示させるのは非常に簡単だった。

画像ファイルの表示にはPythonのイメージ処理モジュールを使用してみた。そのあたりは次回に。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中