// Gian Ferrari
// Turma 1 - Embarcados
// Controle Climático de estufa
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <math.h>
#include <ESP32Servo.h>
// ---- WiFi Wokwi -------------------------------------
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASSWORD = "";
// ---- Ubidots ----------------------------------------
const char* MQTT_BROKER = "industrial.api.ubidots.com";
const int MQTT_PORT = 1883;
const char* MQTT_CLIENTID = ""; // (funcionou no Wokwi)
const char* UBIDOTS_TOKEN = "BBUS-G5vQxCZ6TSLJhA285ShtDiA0uJhz1y";
const char* MQTT_SUB_TOPIC = "/v1.6/devices/esp32-proj/rele/lv";
const char* MQTT_PUB_TOPIC = "/v1.6/devices/esp32-proj";
// ---- DHT22 -----------------------------------
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// ---- LDR ------------------------------------
#define LDR_PIN 34
const float GAMMA = 0.7;
const float RL10 = 50;
const float ADC_MAX = 4095.0;
const float VREF = 3.3;
const float R_DIV_OHMS = 10000.0;
// ---- SERVO ----------------------------------
#define SERVO_PIN 18
Servo servo;
int servoPos = 90; // posição inicial
// ---- RELÉ -----------------------------------
#define RELAY_PIN 16
bool releOn = false; // estado do relé
// ---- Variáveis ------------------------------
char msg[255];
float temperatura = 18.0;
float umidade = 40.0;
float lux = 0.0;
WiFiClient espClient;
PubSubClient mqtt(espClient);
void mqttCallback(char* topic, byte* payload, unsigned int length) {
char buf[32];
unsigned int n = (length < sizeof(buf) - 1) ? length : (sizeof(buf) - 1);
memcpy(buf, payload, n);
buf[n] = '\0';
// Espera 0/1 (ou qualquer valor numérico)
releOn = (atof(buf) >= 1.0);
// Aciona o relé (se o seu módulo for ativo em LOW, inverta aqui)
digitalWrite(RELAY_PIN, releOn ? HIGH : LOW);
Serial.print("[MQTT] Comando relé recebido: ");
Serial.println(buf);
}
// ---- Conexão WiFi ---------------------------------
void connectWiFi() {
Serial.print("[WiFi] Conectando...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\n[WiFi] Conectado!!!");
}
// ---- Conexão MQTT -----------------------------------
void connectMQTT() {
mqtt.setServer(MQTT_BROKER, MQTT_PORT);
mqtt.setCallback(mqttCallback);
while (!mqtt.connected()) {
Serial.println("[MQTT] Conectando...");
if (mqtt.connect(MQTT_CLIENTID, UBIDOTS_TOKEN, "")) {
Serial.println("[MQTT] Conectado!!!");
mqtt.subscribe(MQTT_SUB_TOPIC);
} else {
Serial.print(" falhou (rc=");
Serial.print(mqtt.state());
Serial.println("). Tentando novamente em 2s...");
delay(2000);
}
}
}
unsigned long lastMsg = 0;
// ---- Setup -----------------------------------------------------
void setup() {
Serial.begin(115200);
dht.begin();
pinMode(LDR_PIN, INPUT);
analogReadResolution(12);
servo.attach(SERVO_PIN, 500, 2400);
servo.write(servoPos);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW); // inicia desligado
connectWiFi();
connectMQTT();
}
// ---- Código Principal ------------------------------------------
void loop() {
if (!mqtt.connected())
connectMQTT();
mqtt.loop();
unsigned long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
// ---- DHT22 --------------------------
float t = dht.readTemperature();
float h = dht.readHumidity();
if (isnan(t) || isnan(h)) return;
temperatura = t;
umidade = h;
// ---- LDR ----------------------------
int analogValue = analogRead(LDR_PIN);
float voltage = (analogValue / ADC_MAX) * VREF;
if (voltage < 0.001) voltage = 0.001;
if (voltage > VREF - 0.001) voltage = VREF - 0.001;
float resistance = R_DIV_OHMS * voltage / (VREF - voltage);
lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1.0 / GAMMA));
// ---- SERVO (Lux → Ângulo) ------------
float luxClamped = constrain(lux, 0.0, 100000.0);
servoPos = (int)(180.0 - (luxClamped / 100000.0) * 180.0);
servo.write(servoPos);
// ---- MQTT ---------------------------
snprintf(msg, sizeof(msg),
"{\"temperatura\": %.2f, \"umidade\": %.1f, \"lux\": %.1f, \"rele\": %d}",
temperatura, umidade, lux, (int)releOn);
mqtt.publish(MQTT_PUB_TOPIC, msg);
// ---- Monitor Serial -----------------
Serial.print("[MQTT] Publicado: ");
Serial.println(msg);
}
}