「Raspberry Pi」カテゴリーアーカイブ

【ラズパイ】【GLCD】倉田ましろを書いてみる。

こちらのネームクリップの絵がシンプルなデザインなので、この絵を表示させてみたいと思いました。

https://bang-dream.com/goods/1883

InkScapeで画像からトレースして線を書いて、

ドット絵ナニカのサイトで64×64ドットの画像に変換してExcelで出力。

http://dot-e-nanika.com

これを8×8に区分けして、16進数のドットパターンデータに変換(手作業)。

Array = [
    [
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
        0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x20, 0x20,
        0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    ],
    [
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
        0x20, 0x10, 0x08, 0x04, 0x02, 0x82, 0x81, 0x40,
        0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x03, 0x00,
        0x80, 0x41, 0x3B, 0x20, 0x20, 0x20, 0x20, 0x40,
        0x40, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    ],
    [
def drowMashiro():
    for page in range(8):
        for addr in range(64):
            if addr < 32:
                SelectIC(1)
                SetPage(page)
                SetAddress(addr + 32)
            else:
                SelectIC(2)
                SetPage(page)
                SetAddress(addr - 32)
            WriteData(mashiro.Array[page][addr])

で、表示できました。

なかなか良い感じに映っております。

【ラズパイ】GLCDに時刻・気温・湿度・天候情報を表示する

前回までやっていたGLCDをライブラリ化して、gitHubを更新しました。

https://github.com/takishita2nd/GLCD

このGLCDライブラリを使ってGLCDに時刻、気温、湿度、天候情報を表示させたいと思います。

まず、温度、湿度を表示させるために、AM2320周りもライブラリ化しました。

import time
import smbus

i2c = smbus.SMBus(1)
address = 0x5c

def GetTemp():
    loop = True
    block = []
    while loop:
        try:
            i2c.write_i2c_block_data(address, 0x00,[])
            i2c.write_i2c_block_data(address, 0x03,[0x02, 0x02])

            time.sleep(0.05)

            block = i2c.read_i2c_block_data(address, 0, 4)
            loop = False
        except IOError:
            pass
    temp =  block[2] << 8 | block[3]
    return format(temp / 10)

def GetHum():
    loop = True
    block = []
    while loop:
        try:
            i2c.write_i2c_block_data(address, 0x00,[])
            i2c.write_i2c_block_data(address, 0x03,[0x00, 0x02])

            time.sleep(0.05)

            block = i2c.read_i2c_block_data(address, 0, 4)
            loop = False
        except IOError:
            pass
    hum =  block[2] << 8 | block[3]
    return format(hum / 10)

天候データはopenWeatherのWebAPIを利用します。

https://openweathermap.org

openWeatherにした理由は、今のGLCDが半角アスキー文字しか表示できないので、どうしても英語で表示させる必要があります。

なので、海外の英語のAPIを利用させて貰いました。

アクセス回数を絞れば無料で利用できます。

import json
import urllib.request

weather = ""
temp_min = 0
temp_max = 0
temp = 0

def RequestAPI():
    global weather
    global temp_max
    global temp_min
    global temp

    url = 'http://api.openweathermap.org/data/2.5/weather?lat=XXX&lon=XXX&units=metric&appid=XXXXXXXX'
    req = urllib.request.Request(url)
    with urllib.request.urlopen(req) as res:
        body = json.load(res)
        weather = body['weather'][0]['main']
        temp_min = body['main']['temp_min']
        temp_max = body['main']['temp_max']
        temp = body['main']['temp']

def GetWeather():
    return weather

def GetTemp():
    return temp

def GetTempMin():
    return temp_min

def GetTempMax():
    return temp_max

個人情報を含んでいるので、クエリパラメータは書き換えてあります。

これらを使って、GLCDに表示させます。

import RPi.GPIO as GPIO
import time
import datetime
import calendar
import GLCD
import AM2320
import Weather


def __main__():
    GLCD.PinsInit(20, 7, 8, 9, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17)
    GLCD.GLCDInit()
    GLCD.GLCDDisplayClear()

    roop = 10 * 60 * 60
    try:
        while True:
            if roop >= 10 * 60 * 60:
                Weather.RequestAPI()
                weather = Weather.GetWeather()
                temp = Weather.GetTemp()
                roop = 0

            GLCD.GLCDPuts(1, 0, "Date :")
            GLCD.GLCDPuts(10, 8, datetime.datetime.now().strftime('%Y:%m:%d %A'))
            GLCD.GLCDPuts(1, 16, "Weather :")
            GLCD.GLCDPuts(10,24, weather)
            GLCD.GLCDPuts(10,32, "Temp : " + format(temp) + 'C')
            GLCD.GLCDPuts(1, 40, "Time : " + datetime.datetime.now().strftime('%H:%M:%S'))
            GLCD.GLCDPuts(1, 48, "Humidity    : " + AM2320.GetHum() + '%')
            GLCD.GLCDPuts(1, 56, "Temperature : " + AM2320.GetTemp() + 'C')

            roop += 1
            time.sleep(0.1)
    except KeyboardInterrupt:
        GLCD.GLCDDisplayClear()
        GPIO.cleanup()

__main__()

フーフーって聞こえているのは、AM2320に息を吹きかけています。

なんか良い感じだぞ。

配線の見た目をなんとかすれば、そのままインテリアとして使えるかもしれない。

【ラズパイ】【温湿度計】温湿度計AM2320を使用する。

さて、GLCDもある程度やり尽くしたので、新しいデバイスを使用することにしました。

温湿度計AM2320です。

設置。

配線はこんな感じ。

このデバイスはI2Cバスを使用して温湿度を取得することができます。

I2Cバスってなんぞや?ということなんですが、SDL/SDAの2ピンを使ってデータを送受信できるみたいです。

具体的には、SDLにクロック信号と組み合わせてSDAにデータを送信して・・・

って難しいことを考えなくても、ラズパイにはI2Cに対応したモジュール・ライブラリがあるんです。

ちょっと設定を弄るんですけどね。

こちらのサイトを参考にさせて頂きました。

https://qiita.com/twinoze/items/c960eea23c57e342ea4b

先人の知恵を借りるのは大事。

sudo raspi-config

でコンフィグメニューが出るので、

これでI2Cが有効になります。

i2cdetect -y 1

5cと表示できれば認識しているとのことです。

が、100%認識できるかというと、大体50%ぐらいの確立で認識できないケースがありました。

バスリピータを使えば回避できるとのことですが、こう何度も発注を繰り返すと送料が高く付いてしまうので、プログラム側で回避することにしました。

このようにサンプルコードを作成しました。

import time
import smbus

i2c = smbus.SMBus(1)
address = 0x5c

loop = True
block = []
while loop:
    try:
        i2c.write_i2c_block_data(address, 0x00,[])
        i2c.write_i2c_block_data(address, 0x03,[0x00, 0x04])

        time.sleep(0.05)

        block = i2c.read_i2c_block_data(address, 0, 6)
        loop = False
    except IOError:
        pass

hum = block[2] << 8 | block[3]
temp = block[4] << 8 | block[5]

print('hum : ' + format( hum/10) + ' %Rh')
print('temp: ' + format(temp/10) + ' digC')

smbusというライブラリを使えば、I2Cバスへのアクセスが簡単になります。

タイミングチャートとか意識する必要なく、全部ライブラリでやってくれます。

やるべきことは、

  • 初期化
  • ファンクションコード0x03にスタートアドレスとレジスタ数を書き込み
  • データを読み取り

これだけ。

これはデータシートにある、

この部分に合致しています。

そして、I2Cにアクセスできない場合がある問題はtry/catch処理で回避させました。

エラーが発生したら、アクセスが成功するまで再試行を繰り返します。

これで100%アクセスに成功できます。

さて、次回はこれをライブラリ化させてGLCDに表示させましょうか。

【ラズパイ】【GLCD】画面に時刻を表示する

前回までの状況はこちら。

最新ソースをgitHubにアップしました。

https://github.com/takishita2nd/GLCD

ここまで来たら、時刻を表示するくらい簡単にできると思うんよ。

def __main():
    PinsInit(20, 7, 8, 9, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17)
    GLCDInit()
    GLCDDisplayClear()
    GLCDBox(0, 0, 127, 62)
    GLCDLine(0, 15, 127, 15)

    try:
        while True:
            GLCDPuts(30, 38, datetime.datetime.now().strftime('%H:%M:%S'))
            time.sleep(0.1)
    except KeyboardInterrupt:
        GLCDDisplayClear()
        GPIO.cleanup()

うん、これでラズパイで時計が作れる。

【ラズパイ】【GLCD】画面に直線を引く

前回までの状況はこちら。

最新ソースをgitHubにアップしました。

https://github.com/takishita2nd/GLCD

今回は画面に直線を引きます。

始点と終点の座標を与えると、直線を引くようにします。

傾きがあった場合でも引けるようにします。

といっても、サンプルをPythonに書き換えただけですが。

def GLCDLine(Xp0, Yp0, Xp1, Yp1):
    #差分の大きい方を求める
    steep = (abs(Yp1 - Yp0) > abs(Xp1 - Xp0))
    #X,Yの入れ替え
    if steep == True:
        x = Xp0
        Xp0 = Yp0
        Yp0 = x
        x = Xp1
        Xp1 = Yp1
        Yp1 = x
    if Xp0 > Xp1:
        x = Xp0
        Xp0 = Xp1
        Xp1 = x
        x = Yp0
        Yp0 = Yp1
        Yp1 = x
    #傾き計算
    deltax = Xp1 - Xp0
    deltay = abs(Yp1 - Yp0)
    er = 0
    y = Yp0
    ystep = 0
    #傾きでステップの正負を切り替え
    if Yp0 < Yp1:
        ystep = 1
    else:
        ystep = -1
    #直線を点で描画
    for x in range(Xp0, Xp1 + 1):
        if steep == True:
            GLCDPutPixel(y, x)
        else:
            GLCDPutPixel(x, y)
        er += deltay
        if (er << 1) >= deltax:
            y += ystep
            er -= deltax

まずどちらの方向に描画していくか(縦or横)を判定します。

基本的に絶対値が大きい方向に描画していきます。

縦方向に描画していく場合はx/yを入れ替えます。

あとは傾きに応じてy/xを加算しながらx/y方向に描画していきます。

def __main():
    PinsInit(20, 7, 8, 9, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17)
    GLCDInit()
    GLCDDisplayClear()
    GLCDBox(0, 0, 127, 63)
    GLCDLine(0, 15, 127, 15)

    try:
        while True:
            time.sleep(1.0)
    except KeyboardInterrupt:
        GLCDDisplayClear()
        GPIO.cleanup()
def __main():
    PinsInit(20, 7, 8, 9, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17)
    GLCDInit()
    GLCDDisplayClear()
    GLCDBox(0, 0, 127, 63)
    GLCDLine(0, 15, 127, 18)

    try:
        while True:
            time.sleep(1.0)
    except KeyboardInterrupt:
        GLCDDisplayClear()
        GPIO.cleanup()

【ラズパイ】【GLCD】画面に四角の線を引く※追記あり

前回までの状況はこちら。

最新ソースをgitHubにアップしました。

https://github.com/takishita2nd/GLCD

画面に四角を書きます。

これもこちらのAudiunoのサンプルコードをPython用に書き換えた物です。

def GLCDBox(Xp0, Yp0, Xp1, Yp1):
    for i in range(Xp0, Xp1 + 1):
        GLCDPutPixel(i, Yp0)
        GLCDPutPixel(i, Yp1)
    for i in range(Yp0 + 1, Yp1):
        GLCDPutPixel(Xp0, i)
        GLCDPutPixel(Xp1, i)

def GLCDPutPixel(Xp, Yp):
    #ラインの選択処理
    L = 1 << (Yp % 8)
    #LCDに表示するアドレスの位置をセットする
    SetLocation(Xp, Yp)
    #LCD画面の現在表示内容に指定位置のビット(L)をON(XOR)させ、そのデータをLCDに送る
    L = ReadData() | L
    SetAddress(SetCol)
    WriteData(L)

def ReadData():
    #データピンを入力に設定
    for i in range(8):
        GPIO.setup(DATA_p[i], GPIO.IN)
    #読み込みモードにする
    GPIO.output(RW_p, GPIO.HIGH)
    GPIO.output(RS_p, GPIO.HIGH)
    #データを読み込む
    GPIO.output(E_p, GPIO.HIGH)
    GPIO.output(E_p, GPIO.LOW)
    ans = 0
    GPIO.output(E_p, GPIO.HIGH)
    for i in range(8):
        ans = ans | (GPIO.input(DATA_p[i]) << i)
    GPIO.output(E_p, GPIO.LOW)
    #書き込みモードにする
    GPIO.output(RW_p, GPIO.LOW)
    #データピンを出力に設定
    for i in range(8):
        GPIO.setup(DATA_p[i], GPIO.OUT)
    return ans

ピクセルを置く際には、一度表示させているデータを取得し、そのデータのORをとって表示させます。

※サンプルではここがXORになっていたけど、どっちが正しいんだろ?

READする時は、ピンのモードを出力から入力に切り替える必要があります。

実行結果はこうなりました。

んんー?なんかおかしいぞ?

もしかして、信号の読み取りでおかしなデータを読み込んでいるんじゃ無いか?

タイミングチャートを確認する。

ここを確認すると、E信号のHIGHにしてからLOWにするまでの時間(tWH、tWL)が最低450nsと書かれています。

なので、この間に0.5ms(500ns)をsleepを入れてみます。※追記あり

EWAIT = 0.0005
def ReadData():
    #データピンを入力に設定
    for i in range(8):
        GPIO.setup(DATA_p[i], GPIO.IN)
    #読み込みモードにする
    GPIO.output(RW_p, GPIO.HIGH)
    GPIO.output(RS_p, GPIO.HIGH)
    #データを読み込む
    GPIO.output(E_p, GPIO.HIGH)
    time.sleep(EWAIT) #★
    GPIO.output(E_p, GPIO.LOW)
    ans = 0
    GPIO.output(E_p, GPIO.HIGH)
    time.sleep(EWAIT) #★
    for i in range(8):
        ans = ans | (GPIO.input(DATA_p[i]) << i)
    GPIO.output(E_p, GPIO.LOW)
    #書き込みモードにする
    GPIO.output(RW_p, GPIO.LOW)
    #データピンを出力に設定
    for i in range(8):
        GPIO.setup(DATA_p[i], GPIO.OUT)
    return ans

def command(value, mode):
    GPIO.output(RS_p, mode)
    for i in range(8):
        GPIO.output(DATA_p[i], (value >> i) & 0x01)
    GPIO.output(E_p, GPIO.HIGH)
    time.sleep(EWAIT) #★
    GPIO.output(E_p, GPIO.LOW)

モッサリしてる。

もう一度タイミングチャートを確認。

tNはEをHIGHにしてからデータ端子0-7が出力されるまでの時間です。

この表を見れば最大25nsと書いてあります。

なので、E信号のsleep時間を0.03ms(30ns)まで縮めてみましょう。※追記あり

EWAIT = 0.00003

だいぶマシになったのではないでしょうか

動作も安定してオールOKです。

いやーすごい濃いことやってるなー

※追記

ああああ!

単位間違えてるじゃん!

これじゃあμsじゃん!

正しくnsに修正。

EWAIT = 0.0000005

【ラズパイ】【GLCD】ASCII文字列を表示する

前回までの状況はこちら。

今回は複数の文字を表示させます。

これもサンプルコードをPython用に書き換えました。

def GLCDPuts(Xp, Yp, text):
    x = Xp
    for s in text:
        GLCDPutc(x, Yp, s)
        x += 6

やってることはそんなに難しくはありませんでした。

文字と文字の間隔は1ドット空けています。

def __main():
    PinsInit(20, 7, 8, 9, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17)
    GLCDInit()
    GLCDDisplayClear()
    GLCDPuts(40, 10, "ABCDE")

    try:
        while True:
            time.sleep(1.0)
    except KeyboardInterrupt:
        GPIO.cleanup()

【ラズパイ】【GLCD】ASCII文字を表示する

前回までの状況はこちら。

PythonコードをgitHubにアップしました。

https://github.com/takishita2nd/GLCD

サンプルソースにフォントのビットパターンデータがありましたので、これを置換処理を使ってPython用に書き換えました。

https://github.com/takishita2nd/GLCD/blob/master/Font.py

これを使用して、ディスプレイにアスキー文字を表示させます。

    [ 0x7e, 0x11, 0x11, 0x11, 0x7e ], # A   0x41

1文字8×5のサイズになっているようです。

お試しで表示させてみました。

chara = [0x7e, 0x11, 0x11, 0x11, 0x7e]

def __main():
    PinsInit(20, 7, 8, 9, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17)
    GLCDInit()
    GLCDDisplayClear()
    addr = 0
    SelectIC(1)
    SetPage(0)
    for c in chara:
        SetAddress(addr)
        WriteData(c)
        addr += 1

    try:
        while True:
            time.sleep(1.0)
    except KeyboardInterrupt:
        GPIO.cleanup()

このデータを表示するサンプルコードをPython用に書き換えました。

def GLCDPutc(Xp, Yp, c):
    code = ord(c)
    #ページ内のラインを選択
    L = Yp % 8
    #8×5のキャラクター文字を描画する
    for i in range(5):
        SetLocation(Xp + i, Yp)
        f = Font.Array[code - 0x20][i] << L
        WriteData(f)
        if (L != 0) & (SetPg < 7):
            SetPage(SetPg + 1)
            SetAddress(SetCol)
            f = Font.Array[code - 0x20][i] >> (8 - L)
            WriteData(f)
def SetLocation(Xp, Yp):
    global SetPg
    global SetCol
    cs = 0
    #チップの選択とカラムのアドレスの処理を行う
    if Xp < 64:
        #左側(IC1)を選択
        cs = 1
        SetCol = Xp
    else:
        #右側(IC2)を選択
        cs = 2
        SetCol = Xp - 64
    #ページとラインの選択
    SetPg = Yp // 8
    #LCDに描画するアドレスの位置を設定
    SelectIC(cs)
    SetPage(SetPg)
    SetAddress(SetCol)

好きな場所に文字を書くことができます。

ページ跨ぎとか、チップ跨ぎにも対応しているようです。

def __main():
    PinsInit(20, 7, 8, 9, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17)
    GLCDInit()
    GLCDDisplayClear()
    GLCDPutc(20, 5, "B")

    try:
        while True:
            time.sleep(1.0)
    except KeyboardInterrupt:
        GPIO.cleanup()

【ラズパイ】【GLCD】ディスプレイのいろんなところに表示させてみる。

前回までの状況はこちら。

前回でLCDディスプレイの初期化も終わってますし、データを書き込む関数も一通り揃っています。

なので、いろいろ書いてみましょうか。

とはいっても、今の状態では、ドット単位で表示する/しないの設定しかできませんが。

def __main():
    PinsInit(20, 7, 8, 9, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17)
    GLCDInit()
    GLCDDisplayClear()
    SelectIC(1)
    SetPage(0)
    SetAddress(0)
    WriteData(0xFF)
    try:
        while True:
            time.sleep(1.0)
    except KeyboardInterrupt:
        GPIO.cleanup()

ICチップ1番、ページ0、アドレス0に0xFF(全点灯)を設定します。

左上一列が点灯しました。(分かるかな・・・)

ICチップ1番、ページ1、アドレス1に書き込みました。

ICチップ1番、ページ7、アドレス63に書き込みました。

ICチップ2番、ページ0、アドレス0に書き込みました。

ICチップ2番、ページ7、アドレス63に書き込みました。

右下の4ドットは右上に表示するアイコンに対応しています。

なので、LCDを全点灯した場合、右下4ドット分は欠けて見えます。

まぁ、ここまでをまとめると、

こういうことですな。

ここまで分かれば、後はデータさえ用意できれば、いろいろ表示できそうだ。

【ラズパイ】【GLCD】LCDモジュールを初期化して使用できるようにする

前回までの状況はこちら。

さて、このLCDディスプレイを実際にPythonで動かすのですが。

やっぱり、自分一人の力ではなかなか難しかったので、

こちらのサイトのサンプルソースコードを参考にさせて貰いました。

http://zattouka.net/GarageHouse/micon/Arduino/GLCD/GLCD.htm

こちらはArduinoで使用した物で、ソースコードもC言語に似た独自言語を使用しています。

これをラズパイ/Python用に落とし込みます。

import RPi.GPIO as GPIO
import time

RS_p = 7
RW_p = 8
E_p = 9
CS1_p = 18
CS2_p = 19
DATA_p = [0] * 8
SetPg = 0
SetCol = 0

def PinsInit(rst, rs, rw, enable, cs1, cs2, d0, d1, d2, d3, d4, d5, d6, d7):
    GPIO.setmode(GPIO.BCM)

    #データピンの番号セット
    DATA_p[0] = d0
    DATA_p[1] = d1
    DATA_p[2] = d2
    DATA_p[3] = d3
    DATA_p[4] = d4
    DATA_p[5] = d5
    DATA_p[6] = d6
    DATA_p[7] = d7
    #制御ピンの番号をセット
    RS_p = rs
    RW_p = rw
    E_p = enable
    CS1_p = cs1
    CS2_p = cs2
    #指定の制御ピンをデジタル出力に設定
    GPIO.setup(RS_p, GPIO.OUT)
    GPIO.setup(RW_p, GPIO.OUT)
    GPIO.setup(E_p, GPIO.OUT)
    GPIO.setup(CS1_p, GPIO.OUT)
    GPIO.setup(CS2_p, GPIO.OUT)
    #指定のデータピンをデジタル出力に設定
    for i in range(8):
        GPIO.setup(DATA_p[i], GPIO.OUT)
    #信号線をLOWに設定しておく
    GPIO.output(RS_p, GPIO.LOW)
    GPIO.output(RW_p, GPIO.LOW)
    GPIO.output(E_p, GPIO.LOW)
    GPIO.output(CS1_p, GPIO.LOW)
    GPIO.output(CS2_p, GPIO.LOW)
    #LCDモジュールのリセットを解除する
    GPIO.setup(rst, GPIO.OUT)
    GPIO.output(rst, GPIO.HIGH)

ここでは、ラズパイのGPIOの入出力設定と信号線の対応を行っています。

ちなみに、今のブレッドボードでは以下の様に接続されています。

設定が終わったらRSTの信号をHIGHにすることでLCDディスプレイが使用可能になります。

def GLCDInit():
    #30ms待機
    time.sleep(0.03)
    #左側ICを初期化
    SelectIC(1)
    command(0xC0, GPIO.LOW)
    command(0x3F, GPIO.LOW)
    #左側ICを初期化
    SelectIC(2)
    command(0xC0, GPIO.LOW)
    command(0x3F, GPIO.LOW)

def SelectIC(value):
    if value == 1:
        GPIO.output(CS1_p, GPIO.HIGH)
        GPIO.output(CS2_p, GPIO.LOW)
    else:
        GPIO.output(CS1_p, GPIO.LOW)
        GPIO.output(CS2_p, GPIO.HIGH)

def command(value, mode):
    GPIO.output(RS_p, mode)
    for i in range(8):
        GPIO.output(DATA_p[i], (value >> i) & 0x01)
    GPIO.output(E_p, GPIO.HIGH)
    GPIO.output(E_p, GPIO.LOW)

LCDディスプレイの初期化を行います。

ここでは、マニュアルに書いてあるとおりの手順を行います。

このディスプレイはICチップが2枚使用されていて、SelectIC()でコマンドを送信するICチップの番号を設定します。

command()でコマンドを送信します。

第2パラメータはLOW(制御コマンド)、HIGH(表示データ)を選択します。

(もっとわかりやすくした方が良いな・・・)

あと、サンプルを見て気がついたのは、信号をインプットするのに、E信号をHIGHにしなくちゃいけない、ということ。

HIGHでRSやデータ信号が実際にLCDモジュールに入ります。で、終わったらLOWに戻します。

タイミングチャートにしっかり書いてあった・・・

def GLCDDisplayClear():
    for i in [1, 2]:
        SelectIC(i)
        for y in range(8):
            SetPage(y)
            SetAddress(0)
            for x in range(64):
                WriteData(0)

def SetPage(value):
    command(0xB8|(value&0x07), GPIO.LOW)

def SetAddress(value):
    command(0x40|(value&0x3F), GPIO.LOW)

def WriteData(value):
    command(value, GPIO.HIGH)

ディスプレイの表示を全て非表示に設定します。(画面クリア)

def __main():
    PinsInit(20, 7, 8, 9, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17)
    GLCDInit()
    GLCDDisplayClear()
    try:
        while True:
            time.sleep(1.0)
    except KeyboardInterrupt:
        GPIO.cleanup()

__main()

これで、一通りの初期化処理ができました。

データを書き込む関数もあるから、次回はちょっといろいろ表示させてみようか。