Raspberry Pi 筆記(53):I2C連接LCD1602顯示日期時間

大約在2014年時開始研究樹莓派相關的應用與實做,這些年來對於部落格更新的幅度很小,可是Raspbian的作業系統已經從當時的Wheezy,歷經Jessie、Stretch到現在的Buster版本。樹莓派的開發板,也從當時的 Pi1B到現在的Pi4B。最近利用一段空檔時間,打算更新一下先前的部落格,可是那是一個過程,我不想將過去的歷史刪除,而是改寫實做或重新實做新的規格或應用,就從這篇文章開始。

先從簡單的開始,過去寫過一篇 Raspberry Pi 筆記(5):2x16 LCD顯示字元,那時直接將線路接到Pi 1B的各接腳,後來我買了一個I2C介面的轉接板,已經在 Arduino中實做過接法,今天也來試一下如何在樹莓派透過I2C連接LCD 1602。

[線路與連接]

Pi 接腳LCD1602 I2C接腳
Pin 4(+5V)VCC
Pin 6(GND)GND
Pin 3SDA
Pin 5SCL



[準備工作]

以下的LCD1602.py程式會用到smbus,執行以下指令進行安裝smbus模組。安裝前,要先確定系統是否已經安裝 pip程式,如果還沒安裝,請執行 sudo apt-get install pip進行安裝。安裝smbus指令:
$ pip install smbus
執行結果如下:

[程式]

將以下程式儲存成 LCD1602.py,記得檔名 LCD要大寫,且要跟主程式放在同一個目錄。
#!/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))
以下程式命名為lcd_show.py。執行前要用以下指令查詢目前LCD連接的位址:
$ i2cdetect -y 1
查得I2C的位址後,在以下主程式修改第五行函數LCD1602.init()的位址,從0x27改成您目前連接的設備位址。
#!/usr/bin/env python
import LCD1602
import time

LCD1602.init(0x27, 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()

執行程式的指令如下:
$ python lcd_show.py

[結果]


等待 2 秒後,會顯示目前日期及時間。

[參考資料]

2 留言

  1. if y <0: if="" y=""> 1:
    ^SyntaxError: invalid syntax

    回覆刪除
    回覆
    1. 您好, 這段程式碼是在轉成Google Code Prettify時,要將大於或小於符號改成html語法,這段沒有改到到,放到Code Prettify時出現錯誤。已經更新這段程式,謝謝告知。

      刪除

張貼留言

較新的 較舊