import machine # 引入 machine 模組,用於控制硬體
from HCSR04 import HCSR04 # 從 HCSR04 模組中引入 HCSR04 用於超聲波測距
import network # 引入 network 模組,用於連接 Wi-Fi
import time # 引入 time 模組,用於延遲
import urequests # 引入 urequests 模組,用於發送 HTTP 請求
from umqtt.robust import MQTTClient # 引入 MQTTClient 模組,用於 MQTT 通訊
from machine import SoftI2C, Pin # 引入 SoftI2C 和 Pin 模組,用於 I2C 通訊和控制引腳
from lcd_api import LcdApi # 引入 LcdApi 模組,用於 LCD 控制
from i2c_lcd import I2cLcd # 引入 I2cLcd 模組,用於 I2C LCD 控制
# 連接到 Wi-Fi 網絡
sta = network.WLAN(network.STA_IF) # 建立 Wi-Fi station(STA) 物件
sta.active(True) # 啟用 Wi-Fi 介面
sta.connect('Wokwi-GUEST', '') # 連接到指定的 Wi-Fi 網絡,請替換成你的 Wi-Fi SSID 和密碼
print('Linking...') # 輸出連接狀態信息
while not sta.isconnected(): # 等待直到連接成功
pass
print('Link OK') # 輸出連接成功信息
# ThingSpeak MQTT 帳號和頻道訊息
THINGAPEAK_MQTT_CLIENT_ID = b"JSEOKS8fBAknNBM4PA0xKzY" # ThingSpeak MQTT 客戶端 ID
THINGAPEAK_MQTT_USERNAME = b"JSEOKS8fBAknNBM4PA0xKzY" # ThingSpeak MQTT 用戶名
THINGAPEAK_MQTT_PASSWORD = b"6lYlTrEioZr6lSqCg6tgyMyS" # ThingSpeak MQTT 密碼
THINGAPEAK_CHANNEL_ID = b"2574640" # ThingSpeak 頻道 ID
# 建立 MQTT 客戶端並連接到服務器
client = MQTTClient(
client_id=THINGAPEAK_MQTT_CLIENT_ID, # 客戶端 ID
server=b"mqtt3.thingspeak.com", # MQTT 服務器地址
user=THINGAPEAK_MQTT_USERNAME, # 用戶名
password=THINGAPEAK_MQTT_PASSWORD, # 密碼
ssl=False # 是否使用 SSL
)
client.connect() # 連接到 MQTT 服務器
# 定義 I2C 地址和 LCD 顯示參數
I2C_ADDR = 0x27 # I2C 地址
totalRows = 2 # LCD 總行數
totalColumns = 16 # LCD 總列數
# 初始化 I2C
i2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=10000) # 初始化 ESP32 的 I2C 方法
# i2c = I2C(scl=Pin(5), sda=Pin(4), freq=10000) # 初始化 ESP8266 的 I2C 方法
# 初始化 LCD
lcd = I2cLcd(i2c, I2C_ADDR, totalRows, totalColumns) # 創建 LCD 物件
# 初始化超聲波傳感器
sr04_L = HCSR04(trigPin=25, echoPin=26) # 左側超聲波傳感器
sr04_R = HCSR04(trigPin=18, echoPin=19) # 右側超聲波傳感器
# 定義 LINE Notify 的 API 網址
url_line_sro4 = "https://hook.eu2.make.com/emw7d9k68wg1emjcwy0ocut7afsff0wr" # LINE Notify 超音波 alarm API 網址
# 顯示 "Under Detection" 只顯示一次
lcd.move_to(1, 1) # 移動到 LCD 指定位置
lcd.putstr("Under Detection") # 在 LCD 顯示 "Under Detection"
time.sleep(1) # 延遲 1 秒
lcd.clear() # 清除 LCD 屏幕
# 無限循環
while True:
try:
# 獲取左、右兩側超聲波傳感器距離
L = int(sr04_L.distance()) # 左側距離
R = int(sr04_R.distance()) # 右側距離
lcd.move_to(0, 0) # 移動到 LCD 第一行第一列
lcd.putstr(f"Left:{L}cm") # 顯示左側距離
lcd.move_to(0, 1) # 移動到 LCD 第二行第一列
lcd.putstr(f"Right:{R}cm") # 顯示右側距離
print('Left Distance:', L, 'cm') # 輸出左側距離到控制台
print('Right Distance:', R, 'cm') # 輸出右側距離到控制台
if L < 100 or R < 100: # 如果任意一側距離小於 100 cm
lcd.clear() # 清除 LCD 屏幕
lcd.move_to(0, 0) # 移動到 LCD 第一行第一列
lcd.putstr("Alert!") # 顯示警報信息
credentials = bytes("channels/{:s}/publish".format(THINGAPEAK_CHANNEL_ID), 'utf-8') # 構造 MQTT 憑證字符串,指定發佈頻道
payload = bytes("field3=1\n", 'utf-8') # 構造 MQTT 發佈數據
client.publish(credentials, payload) # 發佈數據到 ThingSpeak 頻道
response = urequests.get(url_line_sro4 + "?sr04_L=" + str(L) + "&sr04_R=" + str(R)) # 發送 HTTP 請求到 LINE Notify
response.close() # 確保請求正確關閉
else:
credentials = bytes("channels/{:s}/publish".format(THINGAPEAK_CHANNEL_ID), 'utf-8') # 構造 MQTT 憑證字符串,指定發佈頻道
payload = bytes("field3=0\n", 'utf-8') # 構造 MQTT 發佈數據
client.publish(credentials, payload) # 發佈數據到 ThingSpeak 頻道
credentials = bytes("channels/{:s}/publish".format(THINGAPEAK_CHANNEL_ID), 'utf-8') # 構造 MQTT 憑證字符串,指定發佈頻道
payload = bytes("field1={:.1f}&field2={:.1f}\n".format(L, R), 'utf-8') # 構造 MQTT 發佈數據
client.publish(credentials, payload) # 發佈數據到 ThingSpeak 頻道
time.sleep(5) # 延遲 5 秒
except Exception as e:
print(e.args[0]) # 捕獲並輸出異常信息