#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <EEPROM.h>
#include <DHT.h>
// Configurações gerais
#define DHTPIN 2
#define DHTTYPE DHT22
#define RELAY_TEMP 3
#define RELAY_HUMID 4
#define RELAY_MOTOR 8
#define BTN_NEXT 5
#define BTN_SELECT 6
#define BTN_BACK 7
// Inicialização dos dispositivos
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 20, 4);
RTC_DS1307 rtc;
// Variáveis de controle
typedef struct {
float tempDesejada;
float umidDesejada;
float tolTemp;
float tolUmid;
int diasEclodir;
int tempoMotor; // Tempo de acionamento do motor em segundos
char aveSelecionada[10];
} Configuracao;
Configuracao configAtual;
int telaAtual = 0; // Controle de telas
int telaAnterior = -1; // Rastrear a última tela exibida
int horarioSelecionado = 0; // Horário selecionado para ajuste
int ajusteMinuto = 0; // Controle para ajustar horas ou minutos
int aveSelecionada = 0; // Índice da ave selecionada
int toleranciaSelecionada = 0; // Controle para ajustar tolerâncias
// Horários de rolagem
int horario1[2] = {8, 0};
int horario2[2] = {14, 0};
int horario3[2] = {20, 0};
void setup() {
// Configuração inicial
Serial.begin(9600);
lcd.begin(20, 4); // Especificando o tamanho do display
lcd.backlight();
pinMode(RELAY_TEMP, OUTPUT);
pinMode(RELAY_HUMID, OUTPUT);
pinMode(RELAY_MOTOR, OUTPUT);
pinMode(BTN_NEXT, INPUT_PULLUP);
pinMode(BTN_SELECT, INPUT_PULLUP);
pinMode(BTN_BACK, INPUT_PULLUP);
digitalWrite(RELAY_TEMP, LOW);
digitalWrite(RELAY_HUMID, LOW);
digitalWrite(RELAY_MOTOR, LOW);
dht.begin();
if (!rtc.begin()) {
lcd.setCursor(0, 0);
lcd.print("Erro no RTC!");
while (1);
}
if (!rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
carregarConfiguracoes();
inicializarTela();
}
void loop() {
navegarTelas();
controleAmbiente();
}
void carregarConfiguracoes() {
EEPROM.get(0, configAtual);
if (configAtual.tempDesejada == 0 || configAtual.umidDesejada == 0) {
// Configurações padrão
configAtual.tempDesejada = 37.5;
configAtual.umidDesejada = 55.0;
configAtual.tolTemp = 0.5;
configAtual.tolUmid = 5.0;
configAtual.diasEclodir = 21;
configAtual.tempoMotor = 10; // Tempo padrão do motor: 10 segundos
strcpy(configAtual.aveSelecionada, "Galinha");
}
}
void inicializarTela() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("---- Chocadeira ----");
lcd.setCursor(0, 1);
lcd.print(" Inicializando...");
delay(2000);
lcd.setCursor(0, 2);
lcd.print(" Versao 1.0");
delay(2000);
}
void exibirTelaPrincipal() {
DateTime agora = rtc.now();
float tempAtual = dht.readTemperature();
float umidAtual = dht.readHumidity();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(agora.day()); lcd.print("/"); lcd.print(agora.month()); lcd.print("/"); lcd.print(agora.year());
lcd.setCursor(10, 0);
lcd.print(agora.hour()); lcd.print(":"); lcd.print(agora.minute()); lcd.print(":"); lcd.print(agora.second());
lcd.setCursor(0, 1);
lcd.print("T: "); lcd.print(tempAtual, 1); lcd.print("C");
lcd.print(" U: "); lcd.print(umidAtual, 1); lcd.print("%");
lcd.setCursor(0, 2);
lcd.print("Ave: "); lcd.print(configAtual.aveSelecionada);
lcd.setCursor(0, 3);
lcd.print("Dias: "); lcd.print(configAtual.diasEclodir);
}
void exibirTelaRolagemOvos() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Rolagem dos Ovos");
int *horarioAtual;
switch (horarioSelecionado) {
case 0:
lcd.setCursor(0, 1);
lcd.print("> Horario 1: ");
horarioAtual = horario1;
break;
case 1:
lcd.setCursor(0, 1);
lcd.print("> Horario 2: ");
horarioAtual = horario2;
break;
case 2:
lcd.setCursor(0, 1);
lcd.print("> Horario 3: ");
horarioAtual = horario3;
break;
}
lcd.print(horarioAtual[0]); lcd.print(":"); lcd.print(horarioAtual[1]);
lcd.setCursor(0, 3);
lcd.print("Ajuste: ");
lcd.print(ajusteMinuto == 0 ? "Hora" : "Min");
}
void exibirTelaTolerancia() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Ajuste Tolerancias");
if (toleranciaSelecionada == 0) {
lcd.setCursor(0, 1);
lcd.print("> Temp Tol: "); lcd.print(configAtual.tolTemp, 1); lcd.print("C");
} else {
lcd.setCursor(0, 1);
lcd.print(" Temp Tol: "); lcd.print(configAtual.tolTemp, 1); lcd.print("C");
}
if (toleranciaSelecionada == 1) {
lcd.setCursor(0, 2);
lcd.print("> Umid Tol: "); lcd.print(configAtual.tolUmid, 1); lcd.print("%");
} else {
lcd.setCursor(0, 2);
lcd.print(" Umid Tol: "); lcd.print(configAtual.tolUmid, 1); lcd.print("%");
}
}
void exibirTelaSelecaoAve() {
const char* aves[] = {"Galinha", "Codorna", "Pato", "Ganso"};
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Selecionar Ave");
for (int i = 0; i < 4; i++) {
lcd.setCursor(0, i + 1);
if (i == aveSelecionada) {
lcd.print("> ");
} else {
lcd.print(" ");
}
lcd.print(aves[i]);
}
}
void navegarTelas() {
if (digitalRead(BTN_NEXT) == LOW) {
telaAtual++;
if (telaAtual > 4) telaAtual = 0; // Cicla entre as telas
delay(200);
}
if (digitalRead(BTN_BACK) == LOW) {
telaAtual--;
if (telaAtual < 0) telaAtual = 4; // Cicla entre as telas
delay(200);
}
if (digitalRead(BTN_SELECT) == LOW) {
if (telaAtual == 1) {
aveSelecionada++;
if (aveSelecionada > 3) aveSelecionada = 0; // Cicla entre as aves
} else if (telaAtual == 2) {
toleranciaSelecionada = !toleranciaSelecionada; // Alterna tolerâncias
} else if (telaAtual == 3) {
ajusteMinuto = !ajusteMinuto; // Alterna entre ajustar horas e minutos
}
delay(200);
}
if (telaAtual != telaAnterior) {
telaAnterior = telaAtual;
switch (telaAtual) {
case 0:
exibirTelaPrincipal();
break;
case 1:
exibirTelaSelecaoAve();
break;
case 2:
exibirTelaTolerancia();
break;
case 3:
exibirTelaRolagemOvos();
break;
}
}
}
void controleAmbiente() {
float tempAtual = dht.readTemperature();
float umidAtual = dht.readHumidity();
if (tempAtual < configAtual.tempDesejada - configAtual.tolTemp) {
digitalWrite(RELAY_TEMP, HIGH);
} else if (tempAtual > configAtual.tempDesejada + configAtual.tolTemp) {
digitalWrite(RELAY_TEMP, LOW);
}
if (umidAtual < configAtual.umidDesejada - configAtual.tolUmid) {
digitalWrite(RELAY_HUMID, HIGH);
} else if (umidAtual > configAtual.umidDesejada + configAtual.tolUmid) {
digitalWrite(RELAY_HUMID, LOW);
}
}