National Central University
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try an AI Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

3

Local AI

--

Uedu Code

--

中央大學 AQI 80 24°C PM2.5 21
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 10

顯示器:LCD 與 OLED

在 16x2 LCD 顯示文字與數值
Interaction 25 minute(s)

Learning Objectives

  • 說明 16x2 字元 LCD 與 I2C 轉接板的接法與位址
  • 用 RPLCD 在指定的列與行寫字、清除畫面、開關背光
  • 用 f-string 的寬度與對齊,讓數值變短時不會殘留舊字
  • 把 I2C 溫度感測器的讀值顯示在 LCD 上,並說明 LCD 與 OLED 的差別

不接螢幕,也看得到數值

到目前為止,感測器的讀值都用 print() 印在終端機上。可是作品做好後,樹莓派通常不會接螢幕、也不會一直開著 SSH, 這時候一塊小小的顯示器就很有用:溫度、IP 位址、目前的狀態,一眼就看得到。

這一課用最常見的 16x2 字元 LCD(俗稱 LCD1602):兩行、每行 16 個字。要回答的問題是:

  1. 它怎麼接到樹莓派?上一課的 I2C 怎麼派上用場?
  2. 怎麼在第二行的第 5 格寫字?
  3. 數字從 100 變成 99 時,為什麼畫面會顯示 990?

LCD1602 與 I2C 轉接板

LCD1602 的每一格是 5×8 個點組成的字,由一顆 HD44780 相容的控制晶片負責畫。這顆晶片內建的字形 主要是英文字母、數字、符號(常見的版本還有日文片假名),沒有中文字,所以 LCD 上的文字要用英文與數字。

LCD 原本要接十幾條線。市面上的模組背面通常焊了一塊 I2C 轉接板(使用 PCF8574 晶片),把它變成上一課的 I2C 裝置: 只要接 VCC、GND、SDA(GPIO2)、SCL(GPIO3)四條線。轉接板的位址常見是 0x27,使用 PCF8574A 的版本是 0x3F, 接好後用 sudo i2cdetect -y 1 確認。轉接板上通常還有一顆可變電阻調整對比,畫面一片空白或整排方塊時先轉轉看。

在 Python 裡用 RPLCD 套件:

from RPLCD.i2c import CharLCD
lcd = CharLCD(i2c_expander='PCF8574', address=0x27, port=1, cols=16, rows=2)

cols 與 rows 一定要寫:RPLCD 預設是 20x4 的顯示器,用在 16x2 上換行的位置會不對。

動作 寫法
從游標位置往右寫字 lcd.write_string("Hello")
移動游標到第 r 列第 c 行(從 0 數起) lcd.cursor_pos = (r, c)
清除畫面、游標回到 (0, 0) lcd.clear()
開關背光 lcd.backlight_enabled = False

逐步看:在 LCD 上寫兩行字

看電路上的 LCD:每次 write_string 之後,字會出現在游標所在的位置。cursor_pos 是(列, 行),第一個數字選第幾行字。

為什麼 99 會變成 990

LCD 不會自己清除舊的字:write_string 只會覆蓋它寫到的格子,沒寫到的格子維持原樣。 先寫「Count: 100」再從頭寫「Count: 99」,第 10 格的「0」沒有被蓋掉,畫面就變成「Count: 990」。

有兩種解法:

  1. 每次都 lcd.clear() 再重寫。簡單,但畫面會閃一下,而且清除比較花時間。
  2. 固定寬度:每次寫的字數一樣多,不夠的補空白。f-string 可以指定寬度與對齊:
寫法 結果(用 · 表示空白) 說明
f"{99:<4}" 99·· 4 格寬、靠左,右邊補空白
f"{99:>4}" ··99 4 格寬、靠右
f"{25.06:5.1f}" ·25.1 5 格寬、小數 1 位
"Hi".ljust(16) Hi 加 14 個空白 補滿一整行

逐步看:殘留的舊字

注意第 10 行執行後 LCD 的第一行:多出來的 0 就是上一次留下的。第 14 行用固定寬度把它蓋掉。

逐步看:溫度顯示在 LCD 上

TMP102(0x48)與 LCD(0x27)接在同一條 I2C 匯流排上。模擬的溫度從 9.5°C 升到 10.6°C, 看溫度從一位數變成兩位數時,:5.1f 讓第一行的字數維持不變。

LCD 與 OLED 的差別

另一種常見的小螢幕是 OLED(例如 128×64 點、SSD1306 控制晶片,I2C 位址常見 0x3C)。兩者的差別:

字元 LCD(1602) OLED(128×64)
畫面單位 32 個字格,每格 5×8 點 8192 個點,每個點可以單獨控制
能顯示 英數與符號 文字、線條、圖形、圖示(畫得出來就能顯示)
背光 需要背光,暗處也看得清楚 每個點自己發光,不需要背光,對比高
程式寫法 指定位置寫字 先在記憶體裡畫好,再一次送到螢幕

樹莓派上驅動 OLED 常用 luma.oled 這類套件;ESP32 軌第 09 課用 MicroPython 的 ssd1306 模組在 OLED 上顯示溫溼度, 可以對照「先畫好再送出」的寫法。

互動練習:溫度看板

LCD(0x27)與 TMP102(0x48)都接在 I2C 上。起始程式在第一行寫 Hello、第二行計數。依序完成任務:

  1. 直接執行起始程式,看第二行的計數。
  2. 改程式:第一行改成顯示溫度,格式像 Temp: 25.0 C,每次迴圈都更新。
  3. 把「輸入設定」的溫度開始與結束都設成 30°C,再執行一次:第一行要顯示 30.0 C。
  4. 回答一個問題。

小測驗:LCD 的位置與接線

1.

16x2 LCD 上,lcd.cursor_pos = (1, 3) 之後寫字,字會出現在哪裡?

2.

帶 I2C 轉接板的 LCD 接上樹莓派後,i2cdetect 沒有看到 0x27,最先該做什麼?

3.

想在 LCD1602 上顯示「溫度」兩個中文字,會怎樣?

第 1 次作答

小測驗:格式化

1.

下面的程式會印出什麼?(用方括號標出頭尾,看得到空白)

t = 9.46
print("[" + f"{t:5.1f}" + "]")
2.

下面的程式會印出什麼?

line = f"Count: {7:<3}"
print(len(line))
第 1 次作答

重點整理

  • LCD1602 是 16 行 × 2 列的字元顯示器,字形以英數符號為主,不能直接顯示中文。
  • 帶 PCF8574 轉接板的 LCD 走 I2C,位址常見 0x27(PCF8574A 是 0x3F),可以和其他感測器共用同一條匯流排。
  • RPLCD:CharLCD('PCF8574', 0x27, cols=16, rows=2);write_string 寫字、cursor_pos = (列, 行) 移動游標、clear() 清除、backlight_enabled 開關背光。
  • LCD 不會清掉沒寫到的格子:用固定寬度(f"{n:<4}"、f"{t:5.1f}")覆蓋舊字,比每次 clear 更穩定。
  • 需要圖形或中文時用 OLED 這類點陣螢幕:每個點可以單獨控制,先畫好再送出。

下一課讓東西動起來:伺服馬達轉到指定角度、用驅動板控制直流馬達的方向與速度。

這一課完成了!
Next lesson:馬達與伺服
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。