from machine import Pin, SoftI2C, ADC
from umqtt.simple import MQTTClient
import dht, ssd1306, time, ujson, urequests, network
# ---- configs ----
SSID = "Wokwi-GUEST"
SENHA = ""
BROKER = "053423cb66294544a5f86f4414132286.s1.eu.hivemq.cloud"
USER = "Projetos"
PASS = "Saude@2026"
TOPICO = "estacao/dados"
API_KEY = "83d048934257d9cd34a41af2d84d2972"
CIDADE = "Sao Paulo,BR"
URL = "http://api.openweathermap.org/data/2.5/weather?q=" + CIDADE + "&appid=" + API_KEY + "&units=metric"
# wifi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, SENHA)
while not wlan.isconnected():
time.sleep(0.5)
print("wifi ok")
# pinos / sensores
i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
dht_sensor = dht.DHT22(Pin(15))
ldr = ADC(Pin(34)); ldr.atten(ADC.ATTN_11DB)
mq2 = ADC(Pin(35)); mq2.atten(ADC.ATTN_11DB)
botao = Pin(14, Pin.IN, Pin.PULL_UP)
# mqtt
client = MQTTClient("esp32meteo", BROKER, port=8883, user=USER, password=PASS,
ssl=True, ssl_params={"server_hostname": BROKER})
try:
client.connect()
print("mqtt ok")
except:
print("mqtt falhou")
tela = 0
ult_btn = 0
ult_pub = 0
ult_owm = 0
pressao = None
p_ant = None
prev = "---"
def heat_index(t, h):
if t < 27:
return t
return -8.78 + 1.61*t + 2.34*h - 0.146*t*h - 0.0123*t*t - 0.0164*h*h + 0.00221*t*t*h + 0.000725*t*h*h
def conforto(ic):
if ic < 18: return "Frio"
if ic < 26: return "Confortavel"
if ic < 32: return "Calor leve"
if ic < 41: return "Calor forte"
return "Perigo"
def qualidade(v):
if v < 1000: return "Boa"
if v < 2000: return "Moderada"
if v < 2500: return "Ruim"
return "Muito Ruim"
def previsao(t, h, p, pa):
if p is None: return "Sem dados"
d = (p - pa) if pa else 0
if d <= -2: return "Chuva a caminho"
if d < 0 and h > 75: return "Nublado"
if p >= 1015 and h < 70 and t >= 28: return "Ensolarado"
if p >= 1015: return "Tempo bom"
if p < 1005: return "Instavel"
return "Estavel"
while True:
# botao (debounce simples)
if botao.value() == 0 and time.ticks_diff(time.ticks_ms(), ult_btn) > 250:
tela = (tela + 1) % 4
ult_btn = time.ticks_ms()
# le sensores
try:
dht_sensor.measure()
t = dht_sensor.temperature()
h = dht_sensor.humidity()
except:
t, h = 0, 0
luz = round(ldr.read() / 4095 * 100, 1)
ar = mq2.read()
ic = heat_index(t, h)
agora = time.time()
# busca pressao a cada 60s
if agora - ult_owm > 60:
try:
r = urequests.get(URL)
if r.status_code == 200:
p_ant = pressao
pressao = r.json()["main"]["pressure"]
prev = previsao(t, h, pressao, p_ant)
print("pressao", pressao, "prev", prev)
r.close()
except Exception as e:
print("erro owm", e)
ult_owm = agora
# desenha tela
oled.fill(0)
if tela == 0:
oled.text("Estacao Meteo", 0, 0)
oled.text("T:{:.1f}C".format(t), 0, 16)
oled.text("U:{:.0f}%".format(h), 70, 16)
oled.text("Luz:{:.0f}%".format(luz), 0, 30)
oled.text("Ar:" + qualidade(ar), 0, 44)
elif tela == 1:
oled.text("Conforto", 0, 0)
oled.text("IC: {:.1f}C".format(ic), 0, 20)
oled.text(conforto(ic), 0, 36)
elif tela == 2:
oled.text("Previsao", 0, 0)
oled.text(prev[:16], 0, 20)
oled.text("P:{}".format(pressao if pressao else "--"), 0, 40)
else:
oled.text("Alertas", 0, 0)
y = 16
if t >= 32: oled.text("! Temp alta", 0, y); y += 12
if h <= 30: oled.text("! Umid baixa", 0, y); y += 12
if ar >= 2500: oled.text("! Ar ruim", 0, y); y += 12
if y == 16: oled.text("Tudo ok", 0, 20)
oled.show()
# publica mqtt a cada 10s
if agora - ult_pub > 10:
msg = {
"temperatura": t, "umidade": h, "luminosidade": luz,
"ar_adc": ar, "ar": qualidade(ar),
"indice_calor": round(ic, 1), "conforto": conforto(ic),
"pressao": pressao, "previsao": prev,
}
try:
client.publish(TOPICO, ujson.dumps(msg))
print("publicado")
except:
try: client.connect()
except: pass
ult_pub = agora
time.sleep_ms(100)Loading
ssd1306
ssd1306