iT邦幫忙

2023 iThome 鐵人賽

DAY 26
1
AI & Data

AIoT的藍藥丸與紅藥丸,你選哪個?系列 第 49

ASCII之謎:閃爍的LED密碼之光

  • 分享至 

  • xImage
  •  

前情提要

  在Day 26:繼電器的控制悖論中,你的室友們想要潛入女生宿舍送宵夜,還拉你下水,但當室友A──眼鏡仔破解門禁系統時,卻觸發了保護機制,結果你、眼鏡仔、毛帽男三人被困在一個女生房間裡。
  你們發現房間裡有一個盆栽,上面的樹莓正閃爍著紅色LED亮光,裡面還有一條線連接到DHT22溫溼度感測器。你們發現如果溫度跟濕度達到一定的標準,就會觸發繼電器。你們想盡辦法成功觸發繼電器後,發現這個繼電器連接到風扇的插頭,然後風扇開始緩緩轉動。
  你們在風扇後面找到一張紙條,上面寫著要你們用WebCam攝影機拍照,然後用Python程式把照片轉換成ASCII碼,再用GPIO4接腳控制LED燈,讓它閃爍出ASCII碼。這是大漂亮給你們的下一個提示。

Step 1:需求分析

輸入 / Input

  • (1) 使用者輸入ASCII字元(例如: “@” 或 “?”)
  • (2) LED 燈連接的 GPIO 接腳號(例如 17)

處理 / Process

  • (1) 根據使用者輸入的字元,查找 ASCII 碼的字典,獲取該字元對應的二進位代碼(例如: “@” 對應 “01000000”)。
  • (2) 對每個位元進行迴圈,如果是 1 就讓 LED 燈亮起,如果是 0 就讓 LED 燈熄滅,並且每次切換狀態後暫停 0.5 秒。
  • (3) 使用者輸入的字元不在列表中,就印出錯誤訊息

輸出 / Output

  • (1) LED 燈閃爍出使用者輸入的 ASCII 字元的二進位表示法(例如 “@” 就會閃爍出 “01000000” 的模式)。
  • (2) 如果使用者輸入的字元無法顯示,就會在終端機上顯示“Invalid character!”的訊息。

Step 2:演算法/流程圖

目的

  • 讓樹莓派的 GPIO 接腳控制一顆 LED 燈
  • 讓 LED 燈閃爍出一個 ASCII 字元的二進位表示法

步驟

    1. 引入了 gpiozerotime 這兩個模組,分別用來操作GPIO 接腳控制時間
    1. 建立一個LED 物件,並且指定使用GPIO17這個接腳來連接LED燈。
    1. 建立一個ASCII 字元列表和一個ASCII 碼字典,分別用來儲存不同亮度等級的字元和它們對應的二進位代碼
    1. 輸入一個想要閃爍的 ASCII 字元,並且檢查是否在列表中。
    • (1) 如果在列表中,程式碼就會獲取該字元對應的 ASCII 碼,並且對每個位元進行迴圈。
      • a. 在迴圈中,程式碼會判斷位元是 1 還是 0
        如果是 1 就讓 LED 燈亮起;如果是 0 就讓 LED 燈熄滅。
      • b. 每次切換 LED 燈的狀態後,程式碼會暫停 0.5 秒,讓 LED 燈保持一段時間的亮度。
      • c. 迴圈結束後,程式碼會關閉 LED 燈,結束閃爍。
    • (2) 如果不在列表中,程式碼就會印出錯誤訊息,告訴使用者該字元無法顯示。

Step 3:程式撰寫

1. 引入了 gpiozerotime 這兩個模組,分別用來操作GPIO 接腳控制時間

pip install PIL numpy opencv-python
# 引入gpiozero和time模組 就像是打開工具箱
from gpiozero import LED
from time import sleep

2. 建立一個LED 物件,並且指定使用GPIO17這個接腳來連接LED燈

# 建立一個LED物件 就像是拿出一顆LED燈
# 參數17表示使用GPIO17接腳 就像是把LED燈插到第17號小孔
led = LED(17)
# 建立一個ASCII字元的列表 就像是一個密碼表
# 從最暗到最亮 就像是不同的亮度等級
chars = ["@", "#", "S", "%", "?", "*", "+", ";", ":", ",", "."]

3. 建立一個ASCII 字元列表和一個ASCII 碼字典,分別用來儲存不同亮度等級的字元和它們對應的二進位代碼

# 建立一個ASCII碼的字典 就像是一個對應表
# 對應每個字元和它的二進位表示法 就像是把每個字元轉換成0和1的組合
codes = {"@": "01000000", "#": "00100011", "S": "01010011", "%": "00100101", "?": "00111111", "*": "00101010", "+": "00101011", ";": "00111011", ":": "00111010", ",": "00101100", ".": "00101110"}

4. 輸入一個想要閃爍的 ASCII 字元,並且檢查是否在列表中

# 輸入你想要閃爍的ASCII字元 就像是選擇你想要顯示的字元
char = input("Enter a character: ")
# 檢查字元是否在列表中 就像是看看密碼表裡有沒有這個字元
if char in chars:
    # 獲取字元對應的ASCII碼 就像是查找對應表得到0和1的組合
    code = codes[char]
    # 對每個位元進行迴圈 就像是把0和1的組合一個一個讀取
    for bit in code:
        # 如果位元是1,就讓LED燈亮起 就像是把電流通過LED燈
        if bit == "1":
            led.on()
        # 如果位元是0,就讓LED燈熄滅 就像是把電流斷開LED燈
        else:
            led.off()
        # 暫停0.5秒 就像是讓LED燈保持一段時間的亮度
        sleep(0.5)
    # 關閉LED燈 就像是把電流完全斷開LED燈
    led.off()
else:
    # 如果字元不在列表中,就印出錯誤訊息 就像是告訴你這個字元無法顯示
    print("Invalid character!")

參考資料

  • 超圖解Python程式設計入門(趙英傑, 2019, p.5-2, p.14-2)
  • Day14 閃爍LED燈(實驗1)(dick, 2019)
    • 介紹如何用樹莓派和 gpiozero 模組來控制 LED 燈的亮滅。
    • 列出所需的材料,並且提供了電路圖和程式碼。
    • 說明程式碼的功能,展示實際結果。
  • 第 06 章 - 認識 GPIO 與 LED 燈測試(蔡德明助理教授, 2022)
    • 6.2: 使用 gpiozero 的 python 模組控制 LED
      • 如何用 gpiozero 這個 python 模組來控制 LED 燈的亮滅和亮度。
      • 如何安裝 gpiozero,以及如何用不同的方式來指定 LED 的連接腳位。
      • 如何用 while 迴圈、on()、off()、blink()、value() 和 pulse() 等函數來讓 LED 燈產生不同的效果。
      • 如何用 input() 函數來讓使用者輸入指令來控制 LED 燈的開關。

上一篇
Day 26:繼電器的控制悖論(Paradox: Relay Control)
下一篇
Day 27:Flask 與 Docker 的密室大逃殺
系列文
AIoT的藍藥丸與紅藥丸,你選哪個?62
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言