import network #import network import thư viện network để kết nối với mạng WiFi.
import time #import time import thư viện time để sử dụng hàm sleep().
from machine import Pin, I2C #from machine import Pin, I2C import thư viện Pin và I2C để sử dụng các chân GPIO và giao tiếp I2C.
import dht #import dht import thư viện dht để sử dụng cảm biến DHT
import ujson #import ujson import thư viện ujson để chuyển đổi dữ liệu JSON.
from umqtt.simple import MQTTClient #from umqtt.simple import MQTTClient import thư viện MQTTClient để kết nối với máy chủ MQTT.
from i2c_lcd import I2cLcd #from umqtt.simple import MQTTClient import thư viện MQTTClient để kết nối với máy chủ MQTT.
import urequests as requests #import urequests as requests import thư viện requests để thực hiện yêu cầu HTTP tới API của
#MQTT là một giao thức nhắn tin nhẹ nhàng hoạt động tốt với các thiết bị có tài nguyên hạn chế
# MQTT Server
MQTT_CLIENT_ID = "micropython-weather-demo" #MQTT_CLIENT_ID là ID duy nhất của khách hàng MQTT.
MQTT_BROKER = "broker.mqttdashboard.com" #MQTT_BROKER là địa chỉ IP hoặc tên miền của máy chủ MQTT.
MQTT_USER = "" #MQTT_USER và MQTT_PASSWORD là tên người dùng và mật khẩu của máy chủ MQTT, nếu có.
MQTT_PASSWORD = ""
MQTT_TOPIC = "wokwi-weather"#MQTT_TOPIC là tên của chủ đề MQTT mà khách hàng sẽ xuất bản dữ liệu thời tiết.
sensor = dht.DHT22(Pin(14)) # Tạo một đối tượng cảm biến DHT22 và kết nối nó với chân 14.
led = Pin(15, Pin.OUT) #Tạo một đối tượng LED và kết nối nó với chân GPIO 13, thiết lập nó làm chân đầu ra.
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000) # Khởi tạo giao tiếp I2C bằng cách sử dụng chân GPIO 22 cho SCL và GPIO 21 cho SDA, với tần số 400000 Hz.
lcd = I2cLcd(i2c, 0x27, 2, 16) # Tạo một đối tượng màn hình LCD, kết nối nó với I2C bằng địa chỉ 0x27 và có kích thước 2 hàng, 16 cột.
# Tên mạng Wi-Fi và mật khẩu
ssid = "Wokwi-GUEST" #Lưu trữ tên của mạng Wi-Fi mà thiết bị sẽ kết nối.
password = "" #Lưu trữ mật khẩu của mạng Wi-Fi (nếu có).
# Khởi tạo kết nối Wi-Fi
wifi = network.WLAN(network.STA_IF) #Tạo một đối tượng WLAN để quản lý kết nối Wi-Fi ở chế độ trạm (station mode), tức là thiết bị sẽ kết nối với mạng Wi-Fi hiện có.Tạo một đối tượng WLAN để quản lý kết nối Wi-Fi ở chế độ trạm (station mode), tức là thiết bị sẽ kết nối với mạng Wi-Fi hiện có.
wifi.active(True) #Kích hoạt giao diện Wi-Fi của thiết bị.
wifi.connect(ssid, password) #Bắt đầu quá trình kết nối với mạng Wi-Fi được chỉ định bởi tên và mật khẩu đã lưu trong các biến ssid và password.
while not wifi.isconnected(): #ạo vòng lặp while để kiểm tra trạng thái kết nối Wi-Fi. Vòng lặp sẽ tiếp tục chạy cho đến khi thiết bị kết nối thành công với mạng Wi-Fi.
pass #Là một câu lệnh rỗng, không thực hiện gì cả. Nó được sử dụng ở đây để giữ cho vòng lặp chạy mà không cần thực hiện thêm hành động nào trong khi chờ kết nối Wi-Fi.
# In ra địa chỉ IP sau khi kết nối thành công
print("Kết nối Wi-Fi thành công") #In ra thông báo xác nhận rằng kết nối Wi-Fi đã thành công.
print("Địa chỉ IP:", wifi.ifconfig()[0]) #In ra địa chỉ IP của thiết bị sau khi kết nối Wi-Fi.
# URL của máy chủ OpenWeatherMap:
# URL của máy chủ OpenWeatherMap
#Lưu trữ URL của máy chủ OpenWeatherMap, nơi cung cấp dữ liệu thời tiết.
url = "https://api.openweathermap.org/data/2.5/weather?lat=9.915573&lon=105.2780097&units=metric&appid=32b1ef56d6463fdbf6a4c6b3368c33ae"
# Khởi tạo MQTT Client
# Tạo một đối tượng MQTT Client với ID duy nhất MQTT_CLIENT_ID và kết nối nó với máy chủ MQTT MQTT_BROKER.
client = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER, user=MQTT_USER, password=MQTT_PASSWORD)
client.connect() #Kết nối MQTT Client với máy chủ MQTT.
# LCD
i2c_lcd = I2C(scl=Pin(22), sda=Pin(21), freq=100000) #Khởi tạo giao tiếp I2C với các chân GPIO 22 (SCL) và 21 (SDA), tần số 100000 Hz.
lcd = I2cLcd(i2c_lcd, 0x27, 2, 16) #Tạo đối tượng màn hình LCD, kết nối qua I2C với địa chỉ 0x27, có 2 hàng và 16 cột.
time.sleep(1) #Tạm dừng 1 giây để cho màn hình LCD khởi động hoàn toàn.
lcd.clear() #Xóa toàn bộ nội dung đang hiển thị trên màn hình LCD.
# START
text = 'Starting...' #Tạo biến text chứa chuỗi "Starting..." để hiển thị trên màn hình LCD.
lcd.putstr(text)#Hiển thị chuỗi text lên màn hình LCD.
prev_weather = None # Tạo biến prev_weather và gán giá trị None cho nó. Biến này sẽ được sử dụng để lưu trữ dữ liệu thời tiết trước đó, nhằm so sánh và tránh cập nhật trùng lặp lên màn hình LCD và máy chủ MQTT.
while True:
try:
# Gửi HTTP GET request đến OpenWeatherMap API
response = requests.get(url) #gửi một yêu cầu HTTP GET đến API OpenWeatherMap để lấy dữ liệu thời tiết.
if response.status_code == 200: # nghĩa là yêu cầu thành công và API trả về dữ liệu.
#khác 200, nghĩa là có lỗi trong quá trình gửi yêu cầu HTTP, chương trình sẽ in ra thông báo lỗi.
data = response.json()#chuyển đổi dữ liệu JSON nhận được thành một đối tượng Python.
temp_api = data['main']['temp']
humidity_api = data['main']['humidity']
print("Dữ liệu nhận được từ WEB:")
print("Nhiệt độ:", temp_api, "C")
print("Độ ẩm:", humidity_api, "%")
# Gửi thông tin đến MQTT Broker khi có sự thay đổi
#chứa nhiệt độ và độ ẩm hiện tại
#Chuyển đổi current_weather thành chuỗi JSON.
current_weather = {
"temp": temp_api,
"humidity": humidity_api,
}#Gửi chuỗi JSON lên máy chủ MQTT qua client.publish().
if current_weather != prev_weather: #Cập nhật prev_weather với giá trị current_weather cho lần kiểm tra tiếp theo.
message = ujson.dumps(current_weather)
client.publish(MQTT_TOPIC, message)
prev_weather = current_weather
print("Published to MQTT:", message) # Thêm dòng này để xác nhận xuất MQTT
# Hiển thị thông tin lên LCD
lcd.clear() #Chương trình xóa nội dung cũ trên màn hình LCD.
lcd.putstr("NhietDo: {} C\n".format(temp_api)) #Hiển thị nhiệt độ và độ ẩm lên màn hình LCD.
lcd.putstr("DoAm: {}%\n".format(humidity_api))
led.value(1) # mở đèn
else:
print("Lỗi trong quá trình gửi yêu cầu HTTP")
time.sleep(1) #tạm dừng chương trình 1 giây trước khi lặp lại vòng while, giúp giảm tải cho hệ thống và API OpenWeatherMap.
except Exception as e: #ẽ bắt các lỗi chung khác có thể xảy ra, in ra thông báo lỗi và tạm dừng 1 giây trước khi tiếp tục vòng lặp.
print("Lỗi:", e)
time.sleep(1)