from machine import Pin # 從machine模組引入Pin類別,用於控制引腳
import dht # 引入dht模組,用於操作DHT11溫濕度傳感器
import time # 引入time模組,用於時間延遲
import network # 引入network模組,用於連接Wi-Fi
from umqtt.robust import MQTTClient # 引入MQTTClient模組,用於MQTT通訊
import urequests # 引入urequests模組,用於發送HTTP請求
# 連接到Wi-Fi網路
sta = network.WLAN(network.STA_IF) # 建立Wi-Fi站點(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"2493946" # 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服務器
button = Pin(23, Pin.IN, Pin.PULL_UP) # 設定引腳23為按鈕,並啟用內部上拉電阻
LED2 = Pin(25, Pin.OUT) # 設定引腳25為LED輸出引腳
interruptCounter = 0 # 初始化中斷計數器
# 初始化 DHT11 溫濕度傳感器和連接的引腳
p0 = Pin(15, Pin.IN) # 創建Pin物件,將GPIO15設為資料腳,用於連接DHT11溫濕度傳感器
d = dht.DHT22(p0) # 創建DHT11物件,並指定使用p0物件來連接DHT11溫濕度傳感器
# 定義 LINE Notify 的 API 網址
url_line_Temp = "https://hook.eu2.make.com/x5of7pptbup4x8koijmkd14ug6diprod" # LINE Notify溫度API網址
url_line_Hum = "https://hook.eu2.make.com/fkbk3osn8alkh73r8j6j3vonbwnfbbai" # LINE Notify濕度API網址
j = 0 # 初始化計數器
# 定義中斷處理函數
def button_pressed(button):
global interruptCounter # 使用全域變數 interruptCounter
time.sleep_ms(150) # 延遲150毫秒以防止按鍵彈跳
if button.value() == 1: # 如果按鈕處於按下狀態
interruptCounter += 1 # 增加中斷計數
print('pin change:', button) # 打印引腳變化信息
print('interruptCounter:', interruptCounter) # 打印中斷計數
LED2.value(not LED2.value()) # 切換LED燈狀態
if LED2.value(): # 如果LED燈是亮的
client.publish(b"channels/{:s}/publish/fields/field6".format(THINGAPEAK_CHANNEL_ID), b"1") # 發布LED狀態為1
else: # 如果LED燈是滅的
client.publish(b"channels/{:s}/publish/fields/field6".format(THINGAPEAK_CHANNEL_ID), b"0") # 發布LED狀態為0
# 設置按鍵中斷
button.irq(trigger=Pin.IRQ_FALLING, handler=button_pressed) # 設置按鍵中斷觸發為下降沿,處理函數為button_pressed
while True:
Temperature = 0 # 初始化溫度變數
Humidity = 0 # 初始化濕度變數
for i in range(10): # 迭代10次以取得平均數值
d.measure() # 讀取 DHT11 溫濕度傳感器數據
t = d.temperature() # 讀取溫度值
h = d.humidity() # 讀取濕度值
print('溫度', t) # 打印溫度
print('濕度', h) # 打印濕度
Temperature += t # 累加溫度值
Humidity += h # 累加濕度值
time.sleep(2) # 延遲2秒
Avg_Temp = int(Temperature / 10) # 計算平均溫度
Avg_Hum = int(Humidity / 10) # 計算平均濕度
print('我是溫度', Avg_Temp) # 打印平均溫度
print('我是濕度', Avg_Hum) # 打印平均濕度
if Avg_Temp > 33: # 如果溫度超過33度
response = urequests.get(url_line_Temp + "?DHT_Temp=" + str(Avg_Temp)) # 發送HTTP請求到LINE Notify
response.close() # 確保請求正確關閉
print("溫度過高,目前為 " + str(Avg_Temp) + "°C") # shell顯示警告訊息
if Avg_Hum > 80: # 如果濕度超過80%
response = urequests.get(url_line_Hum + "?DHT_Hum=" + str(Avg_Hum)) # 發送HTTP請求到LINE Notify
response.close() # 確保請求正確關閉
print("濕度過高,目前為 " + str(Avg_Hum) + "%") # shell顯示警告訊息
j += 1 # 計數器加1
print('第 ' + str(j) + ' 筆資料已上傳') # shell顯示資料上傳狀況
credentials = bytes("channels/{:s}/publish".format(THINGAPEAK_CHANNEL_ID), 'utf-8') # 構造 MQTT 憑證字符串,指定發佈頻道
payload = bytes("field2={:.1f}&field3={:.1f}\n".format(Avg_Temp, Avg_Hum), 'utf-8') # 構造 MQTT 發佈負載字符串,包含平均溫度和濕度數據
client.publish(credentials, payload) # 發佈數據到 ThingSpeak 頻道
time.sleep(5) # 延遲5秒