#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <uri/UriBraces.h>
#include <SPI.h>
#include <Ethernet.h>
#include <DHT.h>
#include <Servo.h>
// --- Definições de Pinos e Constantes ---
#define DHTPIN 2 // Pino do sensor DHT
#define DHTTYPE DHT22 // Tipo do sensor DHT (DHT22)
#define SERVO_PIN 3 // Pino do servo motor para viragem
const int RESISTENCIA_PIN = 5; // Pino da resistência de aquecimento
const int FAN_PIN = 6; // Pino do ventilador
const int MOTOR_STATUS_PIN = 13; // Pino para indicar o status do motor (LED)
// --- Parâmetros de Controle ---
const float TEMPERATURA_IDEAL = 37.5; // Temperatura ideal para a incubadora
const float UMIDADE_IDEAL = 65.0; // Umidade ideal para a incubadora
// Tempo de viragem dos ovos: 4 horas em milissegundos
// 1UL * 60UL * 60UL * 1000UL = 1 hora
// 4UL * 60UL * 60UL * 1000UL = 4 horas
const unsigned long INTERVALO_VIRADA = 4UL * 60UL * 60UL * 1000UL;
// Posições do servo motor
const int SERVO_POS_MIN = 0; // Posição mínima do servo (graus)
const int SERVO_POS_MAX = 180; // Posição máxima do servo (graus)
const int SERVO_DELAY = 150; // Tempo para o servo se mover (ms)
// --- Configurações de Rede ---
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Endereço MAC do seu módulo Ethernet
IPAddress ip(192, 168, 1, 177); // Endereço IP fixo para o Arduino
EthernetServer server(80); // Porta do servidor web (HTTP padrão)
// --- Variáveis Globais ---
DHT dht(DHTPIN, DHTTYPE); // Objeto para o sensor DHT
Servo virador; // Objeto para o servo motor
unsigned long ultimaVirada = 0; // Armazena o tempo da última virada dos ovos
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
// Defining the WiFi channel speeds up the connection:
//#define WIFI_CHANNEL 6
WiFiClient client;
WiFiServer server(80);
// --- Função de Configuração (SETUP) ---
void setup()
{
Serial.begin(9600); // Inicializa a comunicação serial para debug
// Configura os pinos como OUTPUT
pinMode(RESISTENCIA_PIN, OUTPUT);
pinMode(FAN_PIN, OUTPUT);
pinMode(MOTOR_STATUS_PIN, OUTPUT);
// Garante que resistência e ventilador comecem desligados
digitalWrite(RESISTENCIA_PIN, LOW);
digitalWrite(FAN_PIN, LOW);
digitalWrite(MOTOR_STATUS_PIN, LOW); // Garante que o LED de status do motor comece desligado
// Anexa o servo ao pino e define uma posição inicial (0 graus)
virador.attach(SERVO_PIN);
virador.write(SERVO_POS_MIN);
// Inicializa a comunicação Ethernet e o servidor web
Ethernet.begin(mac, ip);
server.begin();
Serial.print("Servidor Ethernet iniciado em: ");
Serial.println(Ethernet.localIP());
// Inicializa o sensor DHT
dht.begin();
Serial.println("Sensor DHT inicializado.");
// Exibe o status inicial do motor no serial
Serial.print("Status inicial do motor: ");
Serial.println(digitalRead(MOTOR_STATUS_PIN) ? "Ligado " : "Desligado ");
Serial1.println();
Serial1.println("Conectando a:");
Serial1.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial1.print(".");
}
Serial1.println("");
Serial1.println("Conectado!");
Serial1.println("Endereço de IP: ");
Serial1.println(WiFi.localIP());
server.begin();
}
// --- Função Principal (LOOP) ---
void loop()
{
// --- Leitura do Sensor DHT ---
float temp = dht.readTemperature();
float hum = dht.readHumidity();
// Verifica se a leitura do sensor foi bem-sucedida
if (isnan(temp) || isnan(hum)) {
Serial.println("Erro ao ler do sensor DHT!");
temp = 0; // Define valores padrão em caso de erro
hum = 0;
}
// --- Controle da Resistência (Temperatura) ---
if (temp < TEMPERATURA_IDEAL) {
digitalWrite(RESISTENCIA_PIN, HIGH); // Liga a resistência
Serial.println("Resistência: LIGADA (Temp: " + String(temp) + ")");
} else {
digitalWrite(RESISTENCIA_PIN, LOW); // Desliga a resistência
Serial.println("Resistência: DESLIGADA (Temp: " + String(temp) + ")");
}
// --- Controle do Ventilador (Umidade) ---
if (hum > UMIDADE_IDEAL) {
digitalWrite(FAN_PIN, HIGH); // Liga o ventilador
Serial.println("Ventilador: LIGADO (Umid: " + String(hum) + ")");
} else {
digitalWrite(FAN_PIN, LOW); // Desliga o ventilador
Serial.println("Ventilador: DESLIGADO (Umid: " + String(hum) + ")");
}
// --- Viragem dos Ovos ---
// Verifica se o tempo para a próxima virada foi atingido
if (millis() - ultimaVirada >= INTERVALO_VIRADA) {
Serial.println("Iniciando viragem dos ovos...");
digitalWrite(MOTOR_STATUS_PIN, HIGH); // Liga o LED de status do motor
// Move o servo para a posição máxima (180 graus)
virador.write(SERVO_POS_MAX);
delay(SERVO_DELAY); // Espera o servo se mover
// Move o servo de volta para a posição mínima (0 graus)
virador.write(SERVO_POS_MIN);
delay(SERVO_DELAY); // Espera o servo se mover
digitalWrite(MOTOR_STATUS_PIN, LOW); // Desliga o LED de status do motor
ultimaVirada = millis(); // Atualiza o tempo da última virada
Serial.println("Viragem concluída.");
}
// --- Servidor Web (Requisições HTTP) ---
EthernetClient client = server.available(); // Tenta obter um cliente conectado
WiFiClient client = server.available(); // escuta os clientes que chegam
if (client) { // Se um cliente estiver conectado
Serial.println("Novo cliente conectado.");
String currentLine = ""; // Armazena a linha atual da requisição HTTP
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c); // Imprime o caractere no serial para debug
if (c == '\n') { // Se o caractere for uma nova linha
if (currentLine.length() == 0) { // Se a linha em branco, significa o fim do cabeçalho da requisição HTTP
// Envia o cabeçalho da resposta HTTP
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // A conexão será fechada após a resposta
client.println(); // Linha em branco para indicar o fim do cabeçalho
// Envia o corpo da página HTML
client.println("<!DOCTYPE html><html><head><meta charset='UTF-8'><title>Incubadora</title>");
client.println("<meta http-equiv='refresh' content='10'>"); // Atualiza a página a cada 10 segundos
client.println("<style>");
client.println("body { font-family: Arial, sans-serif; background-color: #f0f0f0; margin: 20px;}");
client.println("h1 { color: #333; }");
client.println("p { margin: 5px 0; }");
client.println(".status-ligado { color: green; font-weight: bold; }");
client.println(".status-desligado { color: red; }");
client.println("</style>");
client.println("</head><body>");
client.println("<h1>Monitoramento da Incubadora</h1>");
client.print("<p>Temperatura: <span class='");
client.print((temp < TEMPERATURA_IDEAL - 0.5 || temp > TEMPERATURA_IDEAL + 0.5) ? "status-desligado" : "status-ligado");
client.print("'>");
client.print(temp);
client.println(" °C</span></p>");
client.print("<p>Umidade: <span class='");
client.print((hum < UMIDADE_IDEAL - 5 || hum > UMIDADE_IDEAL + 5) ? "status-desligado" : "status-ligado");
client.print("'>");
client.print(hum);
client.println(" %</span></p>");
client.print("<p>Resistência: <span class='");
client.print(digitalRead(RESISTENCIA_PIN) ? "status-ligado" : "status-desligado");
client.print("'>");
client.print(digitalRead(RESISTENCIA_PIN) ? "Ligada" : "Desligada");
client.println("</span></p>");
client.print("<p>Ventilador: <span class='");
client.print(digitalRead(FAN_PIN) ? "status-ligado" : "status-desligado");
client.print("'>");
client.print(digitalRead(FAN_PIN) ? "Ligado" : "Desligado");
client.println("</span></p>");
client.print("<p>Status do motor: <span class='");
client.print(digitalRead(MOTOR_STATUS_PIN) ? "status-ligado" : "status-desligado");
client.print("'>");
client.print(digitalRead(MOTOR_STATUS_PIN) ? "Virando" : "Parado");
client.println("</span></p>");
client.println("</body></html>");
break; // Sai do loop while para fechar a conexão
} else { // Se a linha não estiver em branco, é parte do cabeçalho
currentLine = ""; // Limpa a linha para a próxima
}
} else if (c != '\r') { // Se o caractere não for um retorno de carro
currentLine += c; // Adiciona o caractere à linha atual
}
}
}
delay(1); // Pequeno atraso para garantir que a resposta seja enviada completamente
client.stop(); // Fecha a conexão com o cliente
Serial.println("Cliente desconectado.");
}
}