# Импорт необходимых библиотек
import network # Для работы с WiFi подключением
import time # Для работы с временем и задержками
from machine import Pin, PWM, SoftI2C # Для управления пинами, ШИМ и I2C
import dht # Для работы с датчиком температуры/влажности DHT22
import ujson # Для работы с данными в формате JSON
from umqtt.simple import MQTTClient # MQTT клиент для связи с брокером
import ssd1306 # Для работы с OLED дисплеем
import machine # Для функций сброса (reset)
# ========== НАСТРОЙКИ MQTT ==========
MQTT_CLIENT_ID = "wokwi-esp32-weather" # Уникальный ID устройства
MQTT_BROKER = "broker.emqx.io" # Адрес публичного MQTT брокера
MQTT_TOPIC_SUB = "wokwi/weather/control" # Топик для получения команд
# ========== ИНИЦИАЛИЗАЦИЯ УСТРОЙСТВ ==========
# Датчик DHT22 подключен к пину 15
sensor = dht.DHT22(Pin(15))
# Настройка I2C интерфейса для дисплея (SCL=5, SDA=4)
i2c = SoftI2C(scl=Pin(5), sda=Pin(4))
# Инициализация OLED дисплея 128x64
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# Сервопривод на пине 12 с частотой ШИМ 50 Гц
servo = PWM(Pin(12), freq=50)
# Светодиоды:
temp_led = Pin(2, Pin.OUT) # Светодиод температуры (пин 2)
humidity_led = Pin(16, Pin.OUT) # Светодиод влажности (пин 16)
# ========== ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ ==========
current_temp = 20.0 # Текущая температура (начальное значение 20°C)
def set_servo(temp):
"""
Управление сервоприводом в зависимости от температуры
15°C → 0°, 30°C → 180°, промежуточные значения линейно
"""
angle = max(0, min(180, (temp - 15) * 12)) # Ограничиваем угол 0-180°
duty = int(40 + (angle / 180) * 115) # Преобразуем угол в сигнал ШИМ
servo.duty(duty) # Устанавливаем скважность ШИМ
def update_leds(temp, hum):
"""
Управление светодиодами:
- Температурный светодиод включается при <18°C или >26°C
- Светодиод влажности включается при <30% или >70%
"""
temp_led.value(temp < 18 or temp > 26) # Включение по температуре
humidity_led.value(hum < 30 or hum > 70) # Включение по влажности
def update_display(temp, hum):
"""Обновление информации на OLED дисплее"""
oled.fill(0) # Очищаем дисплей
# Выводим температуру с одним знаком после запятой
oled.text(f"Temp: {temp:.1f}C", 0, 20)
# Выводим влажность с одним знаком после запятой
oled.text(f"Hum: {hum:.1f}%", 0, 40)
oled.show() # Обновляем дисплей
def connect_wifi():
"""Подключение к WiFi сети Wokwi-GUEST"""
sta_if = network.WLAN(network.STA_IF) # Создаем интерфейс станции
sta_if.active(True) # Активируем интерфейс
# Подключаемся к сети (Wokwi-GUEST не требует пароля)
sta_if.connect('Wokwi-GUEST', '')
# Ожидаем подключения в течение 10 секунд
for _ in range(20):
if sta_if.isconnected():
return True # Возвращаем True при успешном подключении
time.sleep(0.5)
return False # Возвращаем False если подключение не удалось
def on_message(topic, msg):
"""
Обработчик входящих MQTT сообщений
Принимает числа от 15 до 30 и устанавливает температуру
"""
global current_temp
try:
# Преобразуем сообщение из bytes в число
temp = float(msg.decode())
# Проверяем что температура в допустимом диапазоне
if 15 <= temp <= 30:
current_temp = temp # Обновляем текущую температуру
set_servo(current_temp) # Устанавливаем сервопривод
print(f"Set temp: {current_temp}C") # Вывод в консоль для отладки
except:
pass # Игнорируем сообщения которые не являются числами
# ========== ОСНОВНАЯ ПРОГРАММА ==========
# Подключаемся к WiFi (если не удалось - перезагружаемся)
if not connect_wifi():
machine.reset()
try:
# Создаем MQTT клиента
mqtt = MQTTClient(MQTT_CLIENT_ID, MQTT_BROKER)
# Устанавливаем обработчик входящих сообщений
mqtt.set_callback(on_message)
# Подключаемся к брокеру
mqtt.connect()
# Подписываемся на топик для получения команд
mqtt.subscribe(MQTT_TOPIC_SUB)
except Exception as e:
print("MQTT error:", e)
machine.reset() # Перезагрузка при ошибке
# ========== ГЛАВНЫЙ ЦИКЛ ==========
while True:
try:
# Считываем показания датчика (в Wokwi будет current_temp)
sensor.measure()
# Получаем влажность с датчика
hum = sensor.humidity()
# Обновляем дисплей текущими значениями
update_display(current_temp, hum)
# Обновляем состояние светодиодов
update_leds(current_temp, hum)
# Проверяем новые MQTT сообщения
mqtt.check_msg()
# Небольшая задержка для стабильности
time.sleep(0.5)
except Exception as e:
print("Error:", e)
time.sleep(5) # Пауза при ошибке перед следующей попыткой