import machine
from umqtt.simple import MQTTClient
import time
from machine import Timer
import dht
from machine import SoftI2C
import ssd1306
import network
# 配置参数(需根据实际情况修改)
WIFI_SSID = "Wokwi-GUEST" # WiFi名称,不支持5G WiFi
WIFI_PASSWORD = "" # WiFi密码
CLIENT_ID = "e39e849e30724a72a98a07dad99a7f8e" # 设备ID
MQTT_TOPIC = "temphum" # MQTT主题
# 服务器配置
MQTT_SERVER = "bemfa.com"
MQTT_PORT = 9501
# 硬件配置
DHT_PIN = machine.Pin(2)
OLED_SCL = machine.Pin(4)
OLED_SDA = machine.Pin(5)
UPDATE_INTERVAL = 5000
PING_INTERVAL = 30000
# 初始化传感器和显示屏
dht_sensor = dht.DHT22(DHT_PIN)
i2c = SoftI2C(scl=OLED_SCL, sda=OLED_SDA)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# 全局变量
mqtt_client = None
ping_timer = None
# WiFi连接函数(带详细状态码)
def connect_wifi():
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
print("正在连接WiFi...")
sta_if.active(True)
sta_if.connect(WIFI_SSID, WIFI_PASSWORD)
max_wait = 15
while max_wait > 0:
status = sta_if.status()
print(f"WiFi连接状态码: {status}")
if status == 3:
print("WiFi连接成功!")
break
if status in [0, 2, 4]:
print(f"连接错误,状态码: {status}")
machine.reset()
max_wait -= 1
time.sleep(1)
if sta_if.isconnected():
print(f"网络配置: {sta_if.ifconfig()}")
else:
print("WiFi连接失败,重启设备...")
machine.reset()
# 消息回调函数
def message_callback(topic, msg):
print(f"收到消息: {topic.decode()} - {msg.decode()}")
# 初始化MQTT连接
def init_mqtt():
global mqtt_client
try:
mqtt_client = MQTTClient(
CLIENT_ID,
MQTT_SERVER,
MQTT_PORT,
keepalive=60
)
mqtt_client.set_callback(message_callback)
mqtt_client.connect()
mqtt_client.subscribe(MQTT_TOPIC)
print(f"已连接到MQTT服务器: {MQTT_SERVER}")
return True
except Exception as e:
print(f"MQTT连接失败: {e}")
return False
# 读取传感器数据(补充缺失的函数)
def read_sensor_data():
try:
dht_sensor.measure()
temp = dht_sensor.temperature()
hum = dht_sensor.humidity()
return temp, hum
except OSError as e:
print(f"传感器读取失败: {e}")
return None, None
# 更新OLED显示
def update_oled_display(temp, hum):
oled.fill(0)
oled.text(f"T: {temp:.1f}°C", 0, 10)
oled.text(f"H: {hum:.1f}%", 0, 30)
oled.text("Bemfa Cloud", 0, 50)
oled.show()
# 发布数据到MQTT
def publish_to_mqtt(temp, hum):
global mqtt_client
if mqtt_client:
try:
message = f"T:{temp:.1f},H:{hum:.1f}"
mqtt_client.publish(MQTT_TOPIC, message.encode())
print(f"已发布数据: {message}")
except Exception as e:
print(f"MQTT发布失败: {e}")
reconnect_mqtt()
# 发送MQTT心跳
def send_mqtt_ping(timer):
global mqtt_client
if mqtt_client:
try:
mqtt_client.ping()
print("MQTT心跳发送成功")
except Exception as e:
print(f"MQTT心跳失败: {e}")
reconnect_mqtt()
# 重新连接MQTT(补充缺失的函数)
def reconnect_mqtt():
global mqtt_client, ping_timer
print("尝试重新连接MQTT...")
try:
if mqtt_client:
mqtt_client.disconnect()
if ping_timer:
ping_timer.deinit()
except:
pass
if init_mqtt():
# 重新初始化心跳定时器
ping_timer = Timer(-1)
ping_timer.init(
period=PING_INTERVAL,
mode=Timer.PERIODIC,
callback=send_mqtt_ping
)
print("MQTT重新连接成功")
else:
print("MQTT重新连接失败,5秒后重试...")
time.sleep(5)
# 主函数
def main():
# 连接WiFi
connect_wifi()
# 初始化MQTT
if not init_mqtt():
print("MQTT初始化失败,程序退出")
return
# 初始化心跳定时器
global ping_timer
ping_timer = Timer(-1)
ping_timer.init(
period=PING_INTERVAL,
mode=Timer.PERIODIC,
callback=send_mqtt_ping
)
print("系统启动完成,开始数据采集...")
last_update = time.ticks_ms()
try:
while True:
if mqtt_client:
mqtt_client.check_msg()
current_time = time.ticks_ms()
if time.ticks_diff(current_time, last_update) >= UPDATE_INTERVAL:
last_update = current_time
temp, hum = read_sensor_data()
if temp is not None and hum is not None:
print(f"温度: {temp:.1f}°C, 湿度: {hum:.1f}%")
update_oled_display(temp, hum)
publish_to_mqtt(temp, hum)
time.sleep_ms(100)
except Exception as e:
print(f"主程序异常: {e}")
reconnect_mqtt()
main()
if __name__ == "__main__":
main()