2013年1月23日 星期三

Raspberry Pi with 128x64 Graphic LCD

やっと出来ました。



16x2キャラクターLCDと比べて、グラフィックLCDはかなり手間がかかります。まずはピン数がキツイ。あとはグラフィックに画像データの書き込みは別の処理が必要です。(しないとバラバラになった)




配線

買ったLMG-SS12A64はバックライトないバージョンだから, Pin19とPin20は無視(予想とおりちょっと後悔していた -_- )

1   GND
2    5V
3   CONTRAST (*)
4   GPIO4
5   GPIO7
6   GPIO8
7   GPIO9
8   GPIO10
9   GPIO11
10   GPIO14
11   GPIO15
12   GPIO17
13   GPIO18
14   GPIO25
15   GPIO22
16   GPIO23
17   GPIO24
18   VEE (*)
19  --
20  --

(*)半固定抵抗の配線

コード
import time
import RPi.GPIO as GPIO
class LCD_GPIO(object):
    # Timing constants
    E_PULSE = 0.0000001
    E_DELAY = 0.0000005
    def __init__(self, RST,RS,RW,E,CS1,CS2, D0, D1, D2, D3, D4, D5, D6, D7):
        self.CS1=CS1
        self.CS2=CS2
        self.RST=RST
        self.E = E
        self.RS = RS
        self.RW = RW
        self.D0 = D0
        self.D1 = D1
        self.D2 = D2
        self.D3 = D3
        self.D4 = D4
        self.D5 = D5
        self.D6 = D6
        self.D7 = D7
        GPIO.setmode(GPIO.BCM)        # Use BCM GPIO numbers
        GPIO.setup(self.E, GPIO.OUT)  # E
        GPIO.setup(self.RW, GPIO.OUT) # RW
        GPIO.setup(self.RS, GPIO.OUT) # RS
        GPIO.setup(self.D0, GPIO.OUT) # DB0
        GPIO.setup(self.D1, GPIO.OUT) # DB1
        GPIO.setup(self.D2, GPIO.OUT) # DB2
        GPIO.setup(self.D3, GPIO.OUT) # DB3
        GPIO.setup(self.D4, GPIO.OUT) # DB4
        GPIO.setup(self.D5, GPIO.OUT) # DB5
        GPIO.setup(self.D6, GPIO.OUT) # DB6
        GPIO.setup(self.D7, GPIO.OUT) # DB7
        GPIO.setup(self.CS1, GPIO.OUT) # CS1
        GPIO.setup(self.CS2, GPIO.OUT) # CS2
        GPIO.output(self.RS, 0)
        GPIO.output(self.RW, 0)
        GPIO.output(self.E, 0)
        GPIO.output(self.CS1, 0)
        GPIO.output(self.CS2, 0)
        GPIO.setup(self.RST, GPIO.OUT) # RST
        GPIO.output(self.RST, 0)
        time.sleep(0.5)
        GPIO.output(self.RST, 1)
        time.sleep(0.03)
    def useDisp1(self):
        GPIO.output(self.CS1, 1)
        GPIO.output(self.CS2, 0)
    def useDisp2(self):
        GPIO.output(self.CS1, 0)
        GPIO.output(self.CS2, 1)
    def lcd_byte(self,value, mode):
        GPIO.output(self.RW,0)
        GPIO.output(self.RS,mode)
        GPIO.output(self.D0, (value) & 0x01)
        GPIO.output(self.D1, (value) & 0x02)
        GPIO.output(self.D2, (value) & 0x04)
        GPIO.output(self.D3, (value) & 0x08)
        GPIO.output(self.D4, (value) & 0x10)
        GPIO.output(self.D5, (value) & 0x20)
        GPIO.output(self.D6, (value) & 0x40)
        GPIO.output(self.D7, (value) & 0x80)

        # Toggle E
        time.sleep(self.E_DELAY)
        GPIO.output(self.E, True)
        time.sleep(self.E_PULSE)
        GPIO.output(self.E, False)
        time.sleep(self.E_DELAY)

        GPIO.setup(self.D7, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
        GPIO.output(self.RW,1)
        GPIO.output(self.RS,0)
        time.sleep(self.E_DELAY)
        GPIO.output(self.E, True)
        time.sleep(self.E_PULSE)
        GPIO.output(self.E, False)
        time.sleep(self.E_DELAY)

        while GPIO.input(self.D7):
          pass
        GPIO.setup(self.D7, GPIO.OUT) # DB7
class LCD12864(object):
    def __init__(self, driver):
        self.driver = driver
        self.lcd_init()
    def setPage(self, value):
        self.driver.lcd_byte(0xB8|(value&0x07),0) ;
    def setAddress(self, value):
        self.driver.lcd_byte(0x40|(value&0x3F),0) ;
    def lcd_cls(self):
        self.driver.useDisp1()
        for y in range(8):
          self.setPage(y)
          self.setAddress(0)
          for i in range(64):
             self.driver.lcd_byte(0x00,1)
        self.driver.useDisp2()
        for y in range(8):
          self.setPage(y)
          self.setAddress(0)
          for i in range(64):
             self.driver.lcd_byte(0x00,1)
    def lcd_init(self):
        self.driver.useDisp1()
        self.driver.lcd_byte(0x3F,0)
        self.driver.useDisp1()
        self.driver.lcd_byte(0x3F,0)
        self.lcd_cls()

        self.driver.useDisp1()
        self.setPage(3)
        self.setAddress(0)
        self.driver.lcd_byte(0x00,1)
        self.driver.lcd_byte(0xD0,1)
        self.driver.lcd_byte(0x30,1)
        self.driver.lcd_byte(0x93,1)
        self.driver.lcd_byte(0xDF,1)
        self.driver.lcd_byte(0xB7,1)
        self.driver.lcd_byte(0x77,1)
        self.driver.lcd_byte(0x17,1)
        self.driver.lcd_byte(0x17,1)
        self.driver.lcd_byte(0x77,1)
        self.driver.lcd_byte(0xB7,1)
        self.driver.lcd_byte(0xDF,1)
        self.driver.lcd_byte(0x33,1)
        self.driver.lcd_byte(0xD0,1)
        self.driver.lcd_byte(0x10,1)

        self.setPage(4)
        self.setAddress(0)
        self.driver.lcd_byte(0x04,1)
        self.driver.lcd_byte(0x0A,1)
        self.driver.lcd_byte(0x0B,1)
        self.driver.lcd_byte(0x07,1)
        self.driver.lcd_byte(0x0F,1)
        self.driver.lcd_byte(0xFF,1)
        self.driver.lcd_byte(0x71,1)
        self.driver.lcd_byte(0x71,1)
        self.driver.lcd_byte(0xF1,1)
        self.driver.lcd_byte(0xBF,1)
        self.driver.lcd_byte(0x7F,1)
        self.driver.lcd_byte(0x1F,1)
        self.driver.lcd_byte(0x0F,1)
        self.driver.lcd_byte(0x17,1)
        self.driver.lcd_byte(0x16,1)
        self.driver.lcd_byte(0x08,1)


def demo():
    driver = LCD_GPIO(RS=4,RW=7,E=8,D0=9,D1=10,D2=11,D3=14,D4=15,D5=17,D6=18,D7=25,CS1=22,CS2=23,RST=24)
    lcd = LCD12864(driver=driver)



    time.sleep(15);

def main():
    demo()
if __name__ == "__main__":
    main()


今後予定


  • チュートリアル動画を作る(進行中)
  • ライブラリを作る、基本の線、円を描くライブラリがあればと思います
  • 日本語/漢字表示、8x8美咲フォントはパッチリと思います
  • ピン数を減らすこと、Shift Registerとか使ってたら..?



おまけ

キャラクターLCDやグラフィックLCDのプログラムを執行終わって、GPIOが放置されるといろいろへんな結果が出てくる。


バーにいた、かみです。