#include <EEPROM.h>
#include <DHT.h>
#include <Servo.h>
#include "AlarmTone.h"
#include <LiquidCrystal.h>
#define DHTPIN 2
#define DHTTYPE DHT22
#define RELAY_HEAT 3
#define FAN_PIN 4
#define SERVO_PIN 5
#define SPEAKER_PIN A3
// Se estiver usando LCD com módulo I2C, use esta linha:
// #include <LiquidCrystal_I2C.h>
// LiquidCrystal_I2C lcd(0x27, 16, 2); // Exemplo de endereço I2C
// Se o LCD estiver conectado diretamente aos pinos (modo 4-bit):
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
DHT dht(DHTPIN, DHTTYPE);
Servo virador;
AlarmTone alarmTone;
// Variáveis para as leituras e controle
int pos = 0;
float tempMin = 37.0;
float tempMax = 38.0;
float umidadeMin = 45.0;
float umidadeMax = 55.0;
// Variáveis para temporização
unsigned long ultimaVirada = 0;
unsigned long ultimoAlarmeTemp = 0;
unsigned long ultimoUpdateLCD = 0;
unsigned long eclode = 0;
// Constantes de tempo (em milissegundos)
const unsigned long intervaloVirada = 4UL * 60UL * 60UL * 1000UL; // 4 horas
const unsigned long alarmeTempDelay = 5UL * 60UL * 1000UL; // 5 minutos para alarme
const unsigned long eclodido = 21UL * 24UL * 60UL * 60UL * 1000UL; // 21 dias para eclosão
const unsigned long updateLCDInterval = 2000UL; // Atualiza LCD a cada 2 segundos
void setup() {
Serial.begin(9600);
// Inicialização do LCD
lcd.begin(16, 2);
lcd.print("Iniciando...");
delay(2000);
// Inicialização dos componentes
dht.begin();
pinMode(RELAY_HEAT, OUTPUT);
pinMode(FAN_PIN, OUTPUT);
pinMode(SPEAKER_PIN, OUTPUT); // Definindo o pino do speaker como saída
virador.attach(SERVO_PIN);
virador.write(0); // Posição inicial
// Inicialização de estados
digitalWrite(RELAY_HEAT, LOW);
digitalWrite(FAN_PIN, LOW);
lcd.clear();
}
void loop() {
unsigned long tempoAtual = millis();
// --- Leitura do sensor e atualização do LCD (não bloqueante) ---
if (tempoAtual - ultimoUpdateLCD >= updateLCDInterval) {
float temperatura = dht.readTemperature();
float umidade = dht.readHumidity();
if (isnan(temperatura) || isnan(umidade)) {
lcd.setCursor(0, 0);
lcd.print("Erro no sensor");
return;
}
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(temperatura, 1); // Exibe com uma casa decimal
lcd.print((char)223); // Símbolo de grau
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("U:");
lcd.print(umidade, 1); // Exibe com uma casa decimal
lcd.print("%");
// Controle de aquecimento
if (temperatura < tempMin) {
digitalWrite(RELAY_HEAT, HIGH);
lcd.setCursor(12, 0);
lcd.print("Aq");
} else if (temperatura > tempMax) {
digitalWrite(RELAY_HEAT, LOW);
lcd.setCursor(12, 0);
lcd.print(" ");
}
// Controle de ventilação
if (temperatura > tempMax || umidade > umidadeMax) {
digitalWrite(FAN_PIN, HIGH);
lcd.setCursor(12, 1);
lcd.print("Vent");
} else {
digitalWrite(FAN_PIN, LOW);
lcd.setCursor(12, 1);
lcd.print(" ");
}
ultimoUpdateLCD = tempoAtual;
}
// --- Alarme de temperatura fora da faixa (com temporização) ---
if (millis() - ultimoAlarmeTemp > alarmeTempDelay) {
if (dht.readTemperature() < tempMin || dht.readTemperature() > tempMax) {
alarmTone.play();
// Não atualiza ultimoAlarmeTemp para que o alarme continue tocando
}
} else {
alarmTone.stop();
ultimoAlarmeTemp = millis();
}
// --- Alerta de eclosão (opcional, pode ser removido) ---
if (millis() - eclode > eclodido) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Eclodindo: pinto");
lcd.setCursor(0, 1);
lcd.print("Aguarde: Verifiq");
// Mensagem de eclosão será mantida até o reset do Arduino
}
// --- Viragem dos ovos (não bloqueante) ---
if (tempoAtual - ultimaVirada >= intervaloVirada) {
// Lógica de viragem do servo aqui (não bloqueante)
// Exemplo:
virador.write(90); // Gira para 90 graus
delay(500); // Aguarda a virada
virador.write(0); // Volta à posição inicial
ultimaVirada = tempoAtual;
Serial.println("Ovos virados!");
}
}