LCD 1602 點矩陣液晶
1602 LCD 是市面上最常看到的矩陣顯示器. 雖說只能顯示16*2=32個英文文字,但對於一些只需顯示簡易訊息的工業機械控制已經是足夠超強的了,且價格便宜,不用台幣100元。底下是1602A的正反面圖。
I2C轉接板
由上可見,共有16支針腳,實在太恐怖了,所以市面上就有出一塊 I2C 轉接板,簡化成只有四支針腳
接線法
LCM1602 IIC V1 接腳 | Raspberry Pi GPIO 腳位 |
GND | 實體編號 6 (接地) |
VCC | 實體編號 4 (+5V) |
SDA | 實體編號 3 |
SCL | 實體編號 5 |
開啟RaspBerry I2C 功能
I2C,又稱 I²C(Inter-Interated Circuit),在 I2C 的通訊協定中,收發資料只靠兩條線就能完成,分別為 SCL(serial clock) 以及 SDA(serial data)1。
樹莓派的 I2C 功能預設沒有打開,需先執行 sudo raspi-config,然後選取 Interfacing Option
2. 選取 I5 I2C
3. 依序選取 YES/Finish 後即可。
安裝套件
請使用如下指令安裝系統級的 python 套件
sudo apt install python3-smbus i2c-tools
然後 python 專案下的 .venv 要重新設定
rm -rf .venv python3 -m venv --system-site-packages .venv
偵測 i2c 位址
i2c 的位址都不一樣,請使用如下指令偵測
i2cdetect -y 1
下圖是執行後的結果, 位址為 0x3f
使用RPLCD 套件
使用 RDLCD 套件相當的方便,請先在 Python 專案下安裝此套件
pip install RPLCD
然後撰寫如下代碼,即可顯示目前的時間。底下的 0x3f 就是上面偵測 I2C 的位址。
import time
from RPLCD.i2c import CharLCD
# 初始化 LCD1602
lcd = CharLCD('PCF8574', 0x3f)
# 顯示文字
try:
print('Press Ctrl-C To Stop')
while True:
lcd.clear()
lcd.cursor_pos=(0,0)#第0行
lcd.write_string(f"Date: {time.strftime('%Y/%m/%d')}")
lcd.cursor_pos=(1,0)#第一行
lcd.write_string(f"Time: {time.strftime('%H:%M:%S')}")
time.sleep(1)
except KeyboardInterrupt:
print('Close Program')
finally:
lcd.clear()
結果如下
使用底層方式
如果不使用 RPLCD 庫,則需自行撰寫一些函數,此法比較麻煩,不建議使用,在此僅作記錄用。
請新增 LCD1602.py,代碼如下
#!/usr/bin/env python import time import smbus BUS = smbus.SMBus(1) def write_word(addr, data): global BLEN temp = data if BLEN == 1: temp |= 0x08 else: temp &= 0xF7 BUS.write_byte(addr ,temp) def send_command(comm): # Send bit7-4 firstly buf = comm & 0xF0 buf |= 0x04 # RS = 0, RW = 0, EN = 1 write_word(LCD_ADDR ,buf) time.sleep(0.002) buf &= 0xFB # Make EN = 0 write_word(LCD_ADDR ,buf) # Send bit3-0 secondly buf = (comm & 0x0F) << 4 buf |= 0x04 # RS = 0, RW = 0, EN = 1 write_word(LCD_ADDR ,buf) time.sleep(0.002) buf &= 0xFB # Make EN = 0 write_word(LCD_ADDR ,buf) def send_data(data): # Send bit7-4 firstly buf = data & 0xF0 buf |= 0x05 # RS = 1, RW = 0, EN = 1 write_word(LCD_ADDR ,buf) time.sleep(0.002) buf &= 0xFB # Make EN = 0 write_word(LCD_ADDR ,buf) # Send bit3-0 secondly buf = (data & 0x0F) << 4 buf |= 0x05 # RS = 1, RW = 0, EN = 1 write_word(LCD_ADDR ,buf) time.sleep(0.002) buf &= 0xFB # Make EN = 0 write_word(LCD_ADDR ,buf) def init(addr, bl): # global BUS # BUS = smbus.SMBus(1) global LCD_ADDR global BLEN LCD_ADDR = addr BLEN = bl try: send_command(0x33) # Must initialize to 8-line mode at first time.sleep(0.005) send_command(0x32) # Then initialize to 4-line mode time.sleep(0.005) send_command(0x28) # 2 Lines & 5*7 dots time.sleep(0.005) send_command(0x0C) # Enable display without cursor time.sleep(0.005) send_command(0x01) # Clear Screen BUS.write_byte(LCD_ADDR, 0x08) except: return False else: return True def clear(): send_command(0x01) # Clear Screen def openlight(): # Enable the backlight BUS.write_byte(0x27,0x08) BUS.close() def write(x, y, str): if x < 0: x = 0 if x > 15: x = 15 if y < 0: y = 0 if y > 1: y = 1 # Move cursor addr = 0x80 + 0x40 * y + x send_command(addr) for chr in str: send_data(ord(chr))
再新增 1602.py 檔,執行此檔即可顯示日期及時間,完整代碼如下
#!/usr/bin/env python import LCD1602 import time LCD1602.init(0x3f, 1) # init(slave address, background light) LCD1602.write(0, 0, 'Hi....') LCD1602.write(1, 1, 'Cherish the time') time.sleep(2) try: print('Press Ctrl-C To Stop') LCD1602.clear() while True: LCD1602.write(0, 0,"Date: {}".format(time.strftime("%Y/%m/%d"))) LCD1602.write(0, 1,"Time: {}".format(time.strftime("%H:%M:%S"))) time.sleep(1) except KeyboardInterrupt: print('Close Program') finally: LCD1602.clear()