ラズパイでLCD1602の制御(I2C通信、4ビット)

 ソロギターのホームページですが、最近ラズパイの記事ばかりですいません。
 私の中では、PS4を買った時よりも、熱中して楽しんでいます^^
 余裕があれば、PS5も欲しいですがね!

16文字2行の液晶ディスプレイを堪能


 この液晶ディスプレイ、パーツセットに入っていたもので、前回の8*8LEDドットマトリクスの次の課題が、これのレッスンでした。ただ、そのレッスン内容を見ると、

 線を4本つなげて、制御用のオープンファイルをインポートして、ただ「hellow!」と打つだけ

 の内容でしたので、う~ん、面白みがないやつだなと思いましたが、なんと・・・

 制御用のオープンファイルをどこでダウンロードするのか書いていません!!

 import LCD1602 と打ち込んでもエラーで弾かれます。
 なので、自分で制御プログラムを組むことにしまして、まるっと正月休み2日分を消化しました。

躓きポイント

 私、ラズパイを興味津々で購入する、自他とも認める理系タイプですし、仕事柄ちょっとした電気関係の補修をしたりするので、苦手意識があるわけでもありませんが、

 LEDの抵抗なんで220Ω? 8*8LEDには抵抗つけなくてもいいの?

 と、電子工作の知識は、中学生?レベルです。なんとなくトランジスタの仕組みがわかるぐらい。ましてや、液晶パネルなんて組み立てたことありませんし、30年間は電子工作と無縁の生活です。
 そんな素人が、実際に組み立てしたときにツマズイタ所を記事にしてみます。だれかの役に立つことがくるでしょうか。

LCD1602の本体はたぶん1種類。しかし接続タイプが3種類は存在している。

 この手の小型液晶本体は恐らく、HD44780という制御IC、もしくはそれに準拠したICで制御されているもので、市場を占拠しているようです。
 サイトキャラクタLCDモジュールの使いかたこちらのサイトをとても参考にしました。
 問題なのは、売っているLCD1602液晶にドッキングしているI2Cインターフェイスでの制御方法が違う点と、I2Cを使わずに直接ラズベリーパイと接続できることです。
 なぜ問題かというと、先人の方のプログラムを参考にする際、この通信・制御方法が違うと、プログラムも記述している命令コードも使いまわしできないことです。
 パーツセットの説明書が微妙でしたので、書籍のLCDのページを見てプログラムを組んだのですが、文字が表示されませんでした。色々調べた結果、持っているLCDは4ビット制御、書籍で説明されているのは8ビット制御のLCDでした。
 私が調べた限りでは、LCDモジュールの裏側に可変抵抗が付いているのは4ビット制御(PCF8574)、その可変抵抗(液晶のコントラスト調整)を後付けするタイプのI2Cモジュール付きのLCD(ACM1602NIが書籍に紹介)は8ビット制御、少し古いネットの記事ではI2Cを使わず、直接GPIO制御と、情報が入り乱れていて、目的の情報を手に入れるのが大変でした。

そもそものI2C通信の仕組みがよくわからない

 いや~冗談抜きで、購入した書籍、「入門ガイド」と詠っているくせに、まったく役に立ちません。これに3000円も払ったのは後悔です。次、参考書が欲しくなったときは、都会の本屋に行って、実際に使えそうな本を探さないといけませんね。
 「入門ガイド」のくせに、肝心な所を省きすぎていて、とりあえず線をつなげて、制御ライブラリー入れて、表示してよしじゃ・・・いつまで経っても、スマホ制御のロボットなんて作れないぞ!!
 
 と、私が調べた結果の簡単な情報は、最後のソースコードの説明欄に書いています。

 基本的には、送信時は、「相手のデバイスアドレス、相手のデーター格納アドレス、入れたいデーター」。受信時は、「相手のデバイスアドレス、相手のデーター格納アドレス」を命令として出すようです。

 今回使用したもの(PCF8574)は、「相手のデバイスアドレス、1回目のデーター送信(パラレル化)、2回目のデーター送信(パラレル化)」となっているようです。これに関して、確証となる情報見つけれませんでしたが、たぶんあっていると思う。

LCD1602の命令一覧表が見にくい、分かりにくい

 購入したパーツセットの付録CDに、LCD1602のデーターシートが入っていましたが、英語。
 これを、ネットの無料PDF翻訳サイトで翻訳するも・・・、言葉足らずで理解できない所多数。
 ネットで色んな方の翻訳?を見ても、どれも似たような記述で、わかりにくい。
 結局、実際に命令を使って、その挙動を見て納得するしかありませんでした。

 これも、私が調べた結果&素人目線での説明を、最後のソースコードに書いています。

 私は、30年前にMSXで、「マシン語で直接VRAMの中にアドレス指定して文字を入れる」ことをしていたので、なんとなくデーターシートを見て仕組みが分かるのですが、それでも説明の意味が頭に入らないカタカナ語ばかりでした。
 なので、私の説明書きは少しだけ分かりやすくなっているかも・・・。

・ラズパイの3V出力(I2C)、そのままLCDにつなげていいのか・・・!?

 ネットで見る限り、3Vの信号線を5Vにアップさせないといけないみたい。単独なら問題ないけど、ほかのI2Cデバイスを同時に接続した際に、問題が出るよう。
 ただ、私はそのまま3Vで使用。何かアマゾンで購入する際に、ついでに購入予定ではあります。

・4ビット制御の初期設定が大変

 色んな先人の方のプログラムを参考にして、オリジナルで組み上げましたが、この初期設定がかなり曲者でした。
 データーシートには初期設定の方法が書いてなく、最初は単に4ビット制御の命令をセットアップ時に送ったけど、表示がバグりまくり。
 次にネットの情報を参考に、0x33,0x32と初回の命令を真似したら、表示できたけど、たまに表示がバグる。
 最終的に、0x33の初回の4ビット0b0011の命令後に4mSほど時間をあけないといけない仕様と判明。

命令によって処理時間が微妙に違う

 色んな命令を試すたびに、なぜか表示がバグります。このバグの原因も最終的には、4ビット制御(2回受け取って8ビットに変換)しているため、何かの拍子でその受け取りに失敗すると、次から全部命令が4ビットずつ入れ違いになってバグると理解したのですが、その原因がシビアな待機時間調整。
 全部長めにすれば問題解決するかと、安易に長くしてもダメでした。
 この辺りは、データシートにそれらしき図と表が載っているのですが・・・、適当な解読というか、もうなんとなくの数値入れています。

 これに関しても、先人の方のプログラムが0.00001sで制御してあったので、その数字を最初使っていたのですが、私の環境では、0.00002s必要で、画面クリアには0.00006sとか微調整が必要でした。

質問どんどん待ってます!

 え~ソロギターのサイトですが、楽しんで電子工作した過程を、誰が読むのか分からないけど、ひたすら書くのも楽しいです。自己顕示欲ですけどね~。
 ここで書ききれなかった事沢山ありますし、この4ビット制御のLCD1602に関しては、かなりマスターしたと自負しています^^
 どしどし質問お待ちしています~♪ & 何かプログラム上、おかしな点ありましたらご教授お願いします。

#I2Cを有効にする方法 ラズベパイの設定→インターフェイス→I2Cを有効
#もしくはコマンドで、sudo reapi-config を実行し、5 Interfacing Options ⇒ P5 I2C と進み, YESを選択

#I2Cで制御する相手のアドレスを確認する。
#コマンドで、sudo i2cdetect -y 1 を実行し確認。16進数表記。

#I2Cの制御の基本(I2Cデバイスからのデーター読み込み)
#コマンドで、sudo i2get -y 1 0x27 0x01   。0x27はデバイスのアドレス 0x01はデバイスのデータアドレス。
#           順番はデバイスアドレス 読み込みたいデータアドレス
#I2Cの制御の基本(I2Cデバイスへのデータ書き込み)
#コマンドで、sudo i2set -y 1 0x27 0x06 0xF0   。0x27はデバイスのアドレス 0x06はデバイスのデータア
#ドレス 0xF0は書き込みたいデータ。
#    順番はデバイスアドレス 書き込みたいデータアドレス 書き込みデータ

#Pythonでの基本操作
    #import smbus
    #import time
    
    #SMBusの引数に1を指定する。Raspberry Piのi2cバスの番号
    #i2c = smbus.SMBus(1)
    #デバイスのアドレス 0x68
    #addr = 0x68

    #1バイト データの書き込み
    #コマンドフォーマット アドレス 書き込みたいデータのアドレス 書き込むデータ
    #i2c.write_byte_data(addr, 0x06, 0xF0)

    #複数バイト データ書き込み
    #コマンドフォーマット アドレス 書き込みたいデータのアドレス 書き込むデータ(配列)
    #i2c.write_i2c_block_data(addr, 0x07, [0x02, 0x01])

    #1バイト データ読み込み 
    #コマンドフォーマット アドレス 読み込みたいデータのアドレス
    #data = i2x.read_byte_data(addr, 0x05)
    #print(data)

#ラズパイのI2Cは3.3V。制御機器が5Vの場合、信号を5Vにアップする必要があり。


#LCD1602の説明(I2Cの部分除く 命令コード)
#7654 3210b hex
#0000 0001  01 DDRAM(液晶に表示される字のコードが、表示される場所に対応したアドレスに格納されている。)
#をすべて空白(コード0x20)で埋め、アドレスカウンターに1桁目1行目のDDRAMアドレス0x00をセットする。
#              液晶の字を空白に埋めて、左上にカーソル待機(アドレスカウンタ=カーソルの位置)。
#0000 0010  02 アドレスカウンターにDDRAMアドレス0x00をセット。カーソル左上に。
#0000 0011  03 未使用(不明)
#0000 01**     カーソルの動きを設定表示シフトONの場合、文字を表示した際自動でシフトする。
#      100  04 表示シフトOFF(カーソル左へ)実用性?
#      101  05 表示シフトON (カーソル左へ)実用性?
#      110  06 カーソル右(文字の表示方向右に設定) 表示シフトOFF
#      111  07 カーソル右(文字の表示方向右に設定) 表示シフトON
#0000 1***  表示の設定 1DCB D=文字 C=カーソルの表示 B=下線かブロックか
#     1000  08 文字OFFのため
#     1011  0B 08~0Bの使用?
#     1100  0C 文字ON カーソルOFF 
#     1101  0D 文字ON カーソルOFF 
#     1110  0E 文字ON カーソルON  下線カーソル
#     1111  0F 文字ON カーソルON  ブロックカーソル点滅
# この下線カーソルと、ブロックカーソルの指定が、データーシートと違う・・・読み方が違うのか。
#0001 **xx  カーソルの移動、表示シフトの命令(後ろ2ビット未使用)
#   1 0000  10 カーソルが左移動 (字は消えない)
#   1 0100  14 カーソルが右移動(字は消えない)
#   1 1000  18 表示シフト 左 (強制的にシフトできるが、次の文字を入れたらもとに戻る)
#   1 1100  1C 表示シフト 右(強制的にシフトできるが、次の文字を入れたらもとに戻る)
#001d nfxx  設定(4ビットか8ビット、液晶の行数、字の大きさ)
#           d=0 4bit d=1 8bit。n=1 2ライン n=0 1ライン。f=0 通常の5*7 f=1 5*10
#         (特殊な液晶画面で qとかgを表現)
#           4ビットか8ビットかは、I2Cの使用するIC回路で違う。(LDCとの中継が4本か8本か)
#           ラインは、液晶によっては、1行40文字(2行なし)とかあるため。
#0010 1000  28 4ビット、2行表示、通常文字サイズ
#0011 1000  38 8ビット、2桁表示、通常文字サイズ
#01** ****  オリジナル文字の格納アドレスを指示。指示したあとにドットデーターを書き込めれる。
#1*** ****  80~ 一行一文字目 0x80    文字コードの格納アドレスを指定、カーソル位置セット

#上の命令は RS とR/W が 0のとき
#RS=0 R/W=1 で、カーソル位置のアドレス取得とビジー状態取得 多分PCF8574ではできない。
#RS=1 R/W=0 で、文字コード書き込み(文字のアスキー番号、カタカナは指定)
#   事前にオリジナル文字のアドレス設定していた場合は、ドットデータ書き込み
#RS=1 R/W=1 で、文字コード読み込み(今何が液晶に表示されているか、文字コード取得)
#  PCF8574というI2Cシリアルインターフェイスで可能か不明

#よって、LCD1602を制御するには、10本の信号線と、タイミング線、
#      計11本の信号線画必要(8ビットの場合)
#4bビットの場合 2+4本の信号線、1本のタイミング線で7本の信号線必要

#PCF8574というI2Cシリアルインターフェイスを使う場合、
# 2+4本の信号線、1本のタイミング線、残り1本はバックライト制御となっている。

import smbus
import time

I2C = smbus.SMBus(1) #1番のI2Cバスを指定 ラズパイに2があるかは?
I2C_add = 0x27 #LCDに付属のインターフェイスのアドレス 
CODE_RS0 = 0b0000000 #LCDのRS (レジスタの選択 0=命令用)
CODE_RS1 = 0b0000001 #LCDのRS (レジスタの選択 1=書き込み用)
#          0b0000010 #LCDからカーソルの位置とビジー状態習得
#             PCF8574というI2Cシリアルインターフェイスで可能か不明
#          0b0000011 #LCDから表示している文字コード取得 PCF8574でできるかは不明
CODE_E = 0b0000100 #LCD Enable 1から0になると、LCDの制御ICがデータ処理実行
CODE_LED = 0b00001000 #LCDのバックライト 1点灯 0消灯
mojisuu = 16 #ディスプレイの横文字数 (空白で埋めるために使用)
LINE1 = 0x80 #上段の左端アドレス 0x80 ~ 0x8f までの16文字分
LINE2 = 0xC0 #下段の左端アドレス 0xc0 ~ 0xcf までの16文字分
LIN8C = 0x80 #文字表示任意の場所を指定用 上段の5番目 0x85 下段の12番目 0xcc等 


def I2C_write(bits,mode):#bits=各命令,文字コード mode=制御用(RS R/W E LED点灯)
    #変数bitsの命令(8bit)を半分の4bitづつ送る。
    #DB7 DB6 DB5 DB4 LED E R/W RS の情報を送る。
    #I2C.write_byte_data(I2Cアドレス,1回目のシリアルデーター、2回目のシリアルデーター)と処理
    #1回目のシリアルデーターにEN信号を入れ、2回目のデーターにEN信号がないため読み込まれる。
    #data = (bits & 0xF0) | mode | CODE_LED # & F0 によって変数bitの右側4ビットを0に
    #  |mode で変数modeの4ビット加える
    I2C.write_byte_data(I2C_add,(data | CODE_E),(data))
    time.sleep(0.0002)#0.0001だとLCD側の処理が間に合わない。

    #残り半分の転送
    #DB3 DB2 DB1 DB0 LED E R/W RS の情報を送る。
    data = ((bits << 4) & 0xF0) | mode | CODE_LED # << 4 4ビット左に移動
    I2C.write_byte_data(I2C_add,(data | CODE_E),(data))
    time.sleep(0.0002)

def LCD_set():#初期設定 4ビットへの設定
    data = (0x33 & 0xF0) | 0x00 | CODE_LED
    I2C.write_byte_data(I2C_add,(data | CODE_E),(data))
    time.sleep(0.005)#0.004以上あける。    
    I2C.write_byte_data(I2C_add,(data | CODE_E),(data))
    time.sleep(0.0002)#0.00001以上あける
    startcom = [0x32,0x28,0x0c,0x01,0x02]
    for command in startcom:
        I2C_write(command,CODE_RS0)
    I2C_write(0x06,CODE_RS0)
        #0x33 LCD側の8ビットと4ビット通信初期化のため 0b0011 0b0011 0b0011を3回連続で流す
        #仕様的には、1回目の0011→4ms以上あける→2回目の0011→100us以上あける→3回目の0011
        #0x32 3回目の0b0011のあとに 0b0010を流すことによって、4ビットモードになる
        #0x28 4ビット2桁通常文字
        #0x0c 文字ON カーソル表示OFF
        #0x01 空白で埋めて、カーソル左上に固定される(なにか表示するまで固定)
        #0x02  これを入れないと、シフトで文字移動したあと、カーソルと表示位置がずれる(詳細不明)
        #0x06 カーソル右向き 表示シフトOFF これを最後にしないと、
        #最初に下段表示(カーソルの位置)ができない。
        #ここまでの各処理に間があくと、4ビットモードにならない。
        #time.sleep(0.0003)とか入れると4ビットモードにならない→バグる

def LCD_clear():#画面クリア
    clearcom = [0x0c,0x01,0x02,0x06]
    for command in clearcom:
        I2C_write(command,CODE_RS0)
        time.sleep(0.0006)
        #消去するのに処理落ちするため、長めに間をあける。0.0004でバグ発生(4ビットの通信がずれるから?)。
        #0x0c 文字ON カーソル表示OFF
        #0x01 空白で埋めて、カーソル左上
        #0x02  これを入れないと、シフトで文字移動したあと、カーソルと表示位置がずれる(詳細不明)
        #0x06 カーソル右向き 表示シフトOFF
        
def LCD_text(message,line):#指定した行にまとめてmessage書き込み
    message =message.center(mojisuu," ") #左,右寄せ、中央 ほかを空白で埋める rjust, ljust, center
    I2C_write(line,CODE_RS0)#行を指定 上0x80 か 下0xc0 で左端から
    for i in range(mojisuu):
        I2C_write(ord(message[i]),CODE_RS1)#LCDのRSを1、文字コード指定
        #文字コードを送る前に、カーソルの位置を知らせる命令を出す必要あり。

def LCD_moji(message,line):#指定した場所にmessage書き込み(上書き)
    I2C_write(0x0f,CODE_RS0)#カーソルon ブロック 0x0e下線
    I2C_write(line,CODE_RS0)#位置を指定 上0x80 か 下0xc0 で左端から
    for i in range (len (message)):
        I2C_write(ord(message[i]),CODE_RS1)

def LCD_katakana(message,line):#指定した場所にmessage書き込み(上書き)カタカナ指定文字
    I2C_write(0x0f,CODE_RS0)#カーソルon ブロック 0x0e下線
    I2C_write(line,CODE_RS0)#位置を指定 上0x80 か 下0xc0 で左端から
    for i in range (len (message)):
        I2C_write(message[i],CODE_RS1)
        
def LCD_tuiki(message):#LED_mojiのあとの追記用
    for i in range (len (message)):
        I2C_write(ord(message[i]),CODE_RS1)

def LCD_l_move(kazu,hayasa):#文字を左へスクロール 変数kazu分 早さは変数hayasa
    I2C_write(0x0c,CODE_RS0)#カーソル表示OFF
    I2C_write(0x07,CODE_RS0)#シフト機能ON
    for i in range (kazu):
        I2C_write(0x18,CODE_RS0)
        time.sleep(hayasa)
    I2C_write(0x06,CODE_RS0)#シフト機能OFF
    I2C_write(0x02,CODE_RS0)#カーソル戻す
    
def LCD_r_move(kazu,hayasa):#文字を右へスクロール 変数kazu分 早さは変数hayasa
    I2C_write(0x0c,CODE_RS0)#カーソル表示OFF
    I2C_write(0x07,CODE_RS0)#シフト機能ON
    for i in range (kazu):
        I2C_write(0x1C,CODE_RS0)
        time.sleep(hayasa)
    I2C_write(0x06,CODE_RS0)#シフト機能OFF
    I2C_write(0x02,CODE_RS0)#カーソル戻す

def LCD_back(kazu):
    for i in range (0,kazu):
        I2C_write(0x10,CODE_RS0)#左にカーソルを移動する(字は消えない)
        
def LCD_insert(message,hayasa):#入力した際に、文字を左へスクロール カーソルの位置固定
    I2C_write(0x07,CODE_RS0)#シフト機能ON
    for i in range (len (message)):
        I2C_write(ord(message[i]),CODE_RS1)
        time.sleep(hayasa)
    I2C_write(0x06,CODE_RS0)#シフト機能OFF
    I2C_write(0x02,CODE_RS0)#カーソル戻す        

def LCD_original():
    I2C_write(0x40,CODE_RS0) #オリジナル文字 1文字目のアドレス指定
    #2文字目は0b01001000 0x48  #3文字目は0b01010000 0x50、以降0x58 0x60 0x68 0x70 0x78 の計8文字
    #      0bxxx00000  左3ビット使わない 5*7ドット
    I2C_write(0b00000,CODE_RS1)
    I2C_write(0b00010,CODE_RS1)
    I2C_write(0b00101,CODE_RS1)
    I2C_write(0b01000,CODE_RS1)
    I2C_write(0b01100,CODE_RS1)
    I2C_write(0b00110,CODE_RS1)
    I2C_write(0b00001,CODE_RS1)
    I2C_write(0b00000,CODE_RS1)#カーソル用の空白使えない。続けて文字を作成するためには、0で書き込み
    I2C_write(0b01110,CODE_RS1)
    I2C_write(0b10001,CODE_RS1)
    I2C_write(0b00000,CODE_RS1)
    I2C_write(0b00000,CODE_RS1)
    I2C_write(0b01010,CODE_RS1)
    I2C_write(0b00000,CODE_RS1)
    I2C_write(0b00000,CODE_RS1)
    I2C_write(0b00000,CODE_RS1)#カーソル用の空白使えない。続けて文字を作成するためには、0で書き込み
    I2C_write(0b00100,CODE_RS1)
    I2C_write(0b01010,CODE_RS1)
    I2C_write(0b10011,CODE_RS1)
    I2C_write(0b00001,CODE_RS1)
    I2C_write(0b00010,CODE_RS1)
    I2C_write(0b01100,CODE_RS1)
    I2C_write(0b10000,CODE_RS1)
    I2C_write(0b00000,CODE_RS1)#カーソル用の空白使えない。続けて文字を作成するためには、0で書き込み
    I2C_write(0b00111,CODE_RS1)
    I2C_write(0b01000,CODE_RS1)
    I2C_write(0b00011,CODE_RS1)
    I2C_write(0b01110,CODE_RS1)
    I2C_write(0b00001,CODE_RS1)
    I2C_write(0b00110,CODE_RS1)
    I2C_write(0b00000,CODE_RS1)
    I2C_write(0b00000,CODE_RS1)#カーソル用の空白使えない。続けて文字を作成するためには、0で書き込み
    I2C_write(0b10001,CODE_RS1)
    I2C_write(0b10101,CODE_RS1)
    I2C_write(0b01110,CODE_RS1)
    I2C_write(0b10001,CODE_RS1)
    I2C_write(0b01110,CODE_RS1)
    I2C_write(0b00000,CODE_RS1)
    I2C_write(0b00000,CODE_RS1)
    I2C_write(0b00000,CODE_RS1)#カーソル用の空白使えない。続けて文字を作成するためには、0で書き込み
    I2C_write(0b11110,CODE_RS1)
    I2C_write(0b00001,CODE_RS1)
    I2C_write(0b11100,CODE_RS1)
    I2C_write(0b00110,CODE_RS1)
    I2C_write(0b11011,CODE_RS1)
    I2C_write(0b01000,CODE_RS1)
    I2C_write(0b00110,CODE_RS1)
    I2C_write(0b00000,CODE_RS1)#カーソル用の空白使えない。続けて文字を作成するためには、0で書き込み

def LCD_led():#LEDライトの消灯
    CODE_LED = 0
    data = (0 & 0xF0) | CODE_RS0 | CODE_LED
    I2C.write_byte_data(I2C_add,(data | CODE_E),(data))
    time.sleep(0.0002)
    #命令を2回流さないと、4ビットのずれが出てバグる
    data = (0 & 0xF0) | CODE_RS0 | CODE_LED
    I2C.write_byte_data(I2C_add,(data | CODE_E),(data))
    time.sleep(0.0002)
      
def main():
    LIN8C = 0xC3 #下段の3番目から表示
    kanacode = [0xca,0xbc,0xde,0xd2,0xcf,0xbc,0xc3,0x21]
    LCD_katakana(kanacode,LIN8C)
    time.sleep(1)
    LCD_text('Hello!',LINE1)
    time.sleep(1)
    LCD_l_move(13,0.5) #13文字分左にスクロール
    LCD_clear()
    LCD_led()
    time.sleep(2)
    
    LIN8C = 0x83
    kanacode = [0xd0,0xb7,0xde,0xc6,0xb2,0xc4,0xde,0xb3]
    LCD_katakana(kanacode,LIN8C)
    time.sleep(1)
    LCD_tuiki(">>>")
    time.sleep(1)
    LCD_back(12)
    time.sleep(1)
    LCD_tuiki("right move!")
    time.sleep(3)
    LCD_insert(">>>>",1)
    LCD_r_move(13,0.5)
    LCD_clear()

  
    LCD_original()
    I2C_write(0x85,CODE_RS0)
    I2C_write(0x00,CODE_RS1)
    I2C_write(0x01,CODE_RS1) 
    I2C_write(0x02,CODE_RS1)
    LCD_moji('Dog?',0x8a)
    I2C_write(0xc5,CODE_RS0)
    I2C_write(0x03,CODE_RS1) 
    I2C_write(0x04,CODE_RS1)
    I2C_write(0x05,CODE_RS1)
    LCD_moji('Cat?',0xca)    
    time.sleep(5)
    LCD_l_move(16,0.8)
    LCD_clear()
   
    LCD_text("END",LINE2)
    time.sleep(2)
    LCD_clear()
    LCD_led()
    
try:
    LCD_set()
    main()

except KeyboardInterrupt:
    pass

コメント

  1. UME より:

    こんにちは。UMEです。

    うひょー! 出たHD44780!
    昔々、制御プログラムを作ったことがあり、とても懐かしいです。
    組み込み系のCPUでGPIOでI2Cを模倣して制御したかなぁ。。。
    やっぱり初期化でどハマりして苦しんだ覚えがあります。
    プログラム上に書いたウエイト時間が、信号線の動き上はどこからどこまでの時間か、という辺りに着目したら解決したかなぁ。
    あと、IC内の全レジスタと全バッファに、全て初期値を書き込んだ覚えがあります(ICの初期値を信頼しない)。

    このテのハナシを書き込めるところが出来て嬉しいです。
    本年もよろしくお願いします。

  2. コン太郎 より:

    UMEさん、こんにちわ^^
    今日アップした記事には書いていませんが、コロナの濃厚接触者の濃厚接触者となりまして、自宅でまったりラズパイとギターを楽しんでいます。
    感染爆発の影響をヒシヒシと感じています。

    そっか、信号線の長さや品質も影響しますよね~。
    今日、東海地方もめちゃ寒いですが、その影響もあるのか、少しLCD液晶が不安定(なぜか表示されなくなる)だったりしますし。
    なんか、全クリアリセット時の挙動が怪しいのは、やはり全部を0で埋めたいところですね。

    この電子工作のパーツ、ネタ、沢山ありすぎるので、さすがにYoutubeのチャンネル分けてみました。

    こちらこそ、よろしくお願いします!

  3. J minor より:

    (あれ?数日前に書き込んだつもりなんだけれども、もう一度)

    コン太郎さん、新年おめでとうございます。

    ラズパイとはまた奇妙なもののはまっていますね。私は名前すら知りませんでした。

    正直今回の動画も、演奏内容よりも猫たちが気になってしょうがないです(笑)。
    2匹とも元気そうですね。

    こっちも元気ですが、そろそろ避妊手術の時期なのに、かわいそうなんで引き伸ばしてばかりいます・・・。

    • コン太郎 より:

      おはようございます。
      すいません、もう片方のラズパイの記事です、コメント。
      「君をのせて」のほうです。

      とまあ、今年もよろしくお願いします。
      猫たちは今日も元気に朝からゴハン頂戴攻撃してきます^^

  4. 林遠 より:

    失礼致しました。Amazonで日本のラズベリーパイを販売している林遠です。
    ブログを拝見しました。弊社のラズベリーパイカメラレビューブログ記事を書きしてくれませんか。
    こちらは無料でサンプルを提供します。
    連絡メールはjp02@vertue.cnです。
    御返事お待ちしております。どうぞよろしくお願いします。

  5. コン太郎 より:

    林遠さん、初めまして。
    大変興味深いし、ペットの見守りカメラとかを作ってみたいとは思っていますが、
    すでにラズベリーパイで遊ぶのに飽きているのと、
    カメラの制御プログラムを組むのに現状自信がないのと、時間的な余裕もないため、今すぐこちらから連絡しませんのでご了承ください。
    正月休みやら、時間に余裕が出て、ラズパイいじりを再開したら声おかけしますかも!

タイトルとURLをコピーしました