LCD1602は、従来から最も利用されている表示器です。最近は、配線数の少ないパラレルシリアルインターフェース付きのI2C用LCD1602が主流になってきました。
今回は、そのインターフェース付きのI2C LCD1602の表示テストをします。今回もライブラリーを使わずにスクリプトを作ってみます。以前、Raspberry Piでテストしたスクリプトを元にしています。記事はこちら。
Raspberry Pi PicoにこのI2C LCD1602を接続する場合に問題点があります。Picoの電圧が3.3Vなのに対し、I2C LCD1602の電源電圧は、5Vなのです。ネット上のサイトや動画では、直接接続している例が多いのですが、LCD1602側で5VでプルアップされているI2Cラインを見てみました。ピークで約4.3Vの電圧がPicoにかかることが分かりました。
Picoの入力電圧は、-0.5V~+4.13Vで、Picoが入力となる場合(スレーブ側になる場合)最大定格電圧を越えてしまいます。今回の場合、Picoはマスターとしてだけの動作ですので、大丈夫だと思うのですが、どうも精神衛生上よくありません。そこで、秋月電子のI2Cバス用の双方向電圧レベル変換モジュールPCA9306をPicoとLCD1602の間に入れることにしました。
接続回路図です。PicoのI2Cポートは、id=1,SDA=GP14,SCL=GP15を使いました。
スクリプトです。
---------------------------------------------------------------------------------------
"""
I2C LCD1602 test
2021.11.19
JH7UBC Keiji Hata
"""
from machine import I2C,Pin
from utime import sleep
i2c=I2C(1,sda=Pin(14),scl=Pin(15),freq=100000)
LCD_addr=0x27
LCD_EN=0x04 #LCD Enable
LCD_BL=0x08 #Back Light
CMD=0x00 #command mode
CHR=0x01 #character mode
LINE1=0x80 #Line1 top address
LINE2=0xC0 #Line2 top address
buf=bytearray(2)
def LCD_write(bits,mode):
I2C LCD1602 test
2021.11.19
JH7UBC Keiji Hata
"""
from machine import I2C,Pin
from utime import sleep
i2c=I2C(1,sda=Pin(14),scl=Pin(15),freq=100000)
LCD_addr=0x27
LCD_EN=0x04 #LCD Enable
LCD_BL=0x08 #Back Light
CMD=0x00 #command mode
CHR=0x01 #character mode
LINE1=0x80 #Line1 top address
LINE2=0xC0 #Line2 top address
buf=bytearray(2)
def LCD_write(bits,mode):
#High 4bits
data=(bits & 0xF0)|mode
buf[0]=data|LCD_EN|LCD_BL
buf[1]=data|LCD_BL
i2c.writeto(LCD_addr,buf)
sleep(0.0001)#wait 100us
#Low 4bits
data=((bits<<4)&0xF0)|mode
buf[0]=data|LCD_EN|LCD_BL
buf[1]=data|LCD_BL
i2c.writeto(LCD_addr,buf)
sleep(0.0001)#wait 100us
def LCD_init():
LCD_write(0x33,CMD)#8bit mode 0x03を2回送る
LCD_write(0x32,CMD)#8bit mode,4bit mode 0x02を送る
LCD_write(0x06,CMD)#Entry modeセット
LCD_write(0x0C,CMD)#表示ON,カーソルOFF,カーソル点滅OFF
LCD_write(0x28,CMD)#2桁表示,7ドットモード
LCD_write(0x01,CMD)#Display clear
sleep(0.002)#waite 2ms
def LCD_clear():
LCD_write(0x01,CMD)
sleep(0.002)#waite 2ms
def LCD_home():
LCD_write(0x02,CMD)
sleep(0.002)#waite 2ms
def LCD_cursor(x,y):
if y==0:
LCD_write(LINE1+x,CMD)
if y==1:
LCD_write(LINE2+x,CMD)
def LCD_print(str):
for c in str:
LCD_write(ord(c),CHR)
LCD_init()
LCD_clear()
LCD_home()
LCD_cursor(1,0)
LCD_print("Hello World!")
count=0
while True:
LCD_cursor(1,1)
LCD_print(str(count))
count=count+1
sleep(1)
buf[0]=data|LCD_EN|LCD_BL
buf[1]=data|LCD_BL
i2c.writeto(LCD_addr,buf)
sleep(0.0001)#wait 100us
#Low 4bits
data=((bits<<4)&0xF0)|mode
buf[0]=data|LCD_EN|LCD_BL
buf[1]=data|LCD_BL
i2c.writeto(LCD_addr,buf)
sleep(0.0001)#wait 100us
def LCD_init():
LCD_write(0x33,CMD)#8bit mode 0x03を2回送る
LCD_write(0x32,CMD)#8bit mode,4bit mode 0x02を送る
LCD_write(0x06,CMD)#Entry modeセット
LCD_write(0x0C,CMD)#表示ON,カーソルOFF,カーソル点滅OFF
LCD_write(0x28,CMD)#2桁表示,7ドットモード
LCD_write(0x01,CMD)#Display clear
sleep(0.002)#waite 2ms
def LCD_clear():
LCD_write(0x01,CMD)
sleep(0.002)#waite 2ms
def LCD_home():
LCD_write(0x02,CMD)
sleep(0.002)#waite 2ms
def LCD_cursor(x,y):
if y==0:
LCD_write(LINE1+x,CMD)
if y==1:
LCD_write(LINE2+x,CMD)
def LCD_print(str):
for c in str:
LCD_write(ord(c),CHR)
LCD_init()
LCD_clear()
LCD_home()
LCD_cursor(1,0)
LCD_print("Hello World!")
count=0
while True:
LCD_cursor(1,1)
LCD_print(str(count))
count=count+1
sleep(1)
---------------------------------------------------------------------------------------
1行目に「Hello World!」が表示され、2行目に数字が0からカウントアップされます。
ブレッドボードです。コントラストはインターフェース基板のボリュームで調整します。