#include "DHT.h"
#include "PID_v1_bc.h"
#include "LiquidCrystal_I2C.h"
#include "Arduino.h"
#include "Crescer.h"
#include <EEPROM.h>
#include "RTClib.h"
//============================================================================================================
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Domingo", "Segunda", "Terca", "Quarta", "Quinta", "Sexta", "Sabado"};
int Hor = 0 ;
int Min = 0;
int Sec = 0;
int Data;
float date;
//============================================================================================================
//Módulo Encoder Rotativo KY-040
#define ENCODER_CLK 2
#define ENCODER_DT 3
#define ENCODER_SW 4
//============================================================================================================
// Variáveis de controle
int counter = 0 ;
bool choice = false ;
bool choice2 = false ;
bool choice3 = false ;
bool choice4 = false ;
double Setpoint = 37.7; // Temperatura de referência
double Setpointu = 60; // Umidade de referência
int falta = 21;// Contagem de dias do nascimento
double motor = 1;// Contagem do tempo do motor
double motor2 = 2;// Contagem do tempo do motor
double faltam = 0;// Contagem do tempo do motor
//============================================================================================================
//Temporizador motor
Tempora temp1;// o número entre parenteses é um indice necessário e até tem outra maneira mas não precisa
Tempora temp2;
Tempora tempImpr;
//============================================================================================================
// Sensor de Temperatura DHT
#define DHTPIN A2 // Pino ao qual o DHT22 está conectado
#define DHTTYPE DHT22 // Tipo de sensor DHT
DHT dht(DHTPIN, DHTTYPE);
//============================================================================================================
// Parâmetros PID
double Input, Output, Input1, Output1;
double Kp = 2.0; // Ganho proporcional
double Ki = 5.0; // Ganho integral
double Kd = 1.0; // Ganho derivativo
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
//============================================================================================================
// Pino para controle
#define mot 8 // Pino para controlar o Motor
const int mosfetPin = 6; // Pino para controlar o aquecedor
const int RelePin = 7 ; // Pino do rele para controlar a umidade
//============================================================================================================
// Display LCD
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
//============================================================================================================
//Objeto para salvar na EEPROM
struct MyObject {
double t;
double u;
int c;
};
//============================================================================================================
//============================================================================================================
void setup() {
Serial.begin(9600); // Inicializa o monitor serial
dht.begin(); // Inicializa dht
lcd.init();
lcd.backlight();
//============================================================================================================
while (!Serial)
{
// wait for serial port to connect. Needed for native USB port only
}
//============================================================================================================
// EEPROM
double f = 123.456f; //Variável para armazenar dados lidos da EEPROM.
int eeAddress = 0; //Endereço EEPROM para iniciar a leitura
Serial.print("Ler EEPROM: ");
EEPROM.get(eeAddress, f); //Ler os dados da EEPROM na posição 'eeAddress'
Serial.println(f, 3); //This may print 'ovf, nan' if the data inside the EEPROM is not a valid float.
//Dados para armazenar no Objeto.
MyObject customVar = {
37.7,
60,
21
};
//============================================================================================================
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Para ajustar a data e a hora na primeira inicialização
//rtc.adjust(DateTime(2024, 1, 1, 16, 30, 00));
// rtc.adjust(DateTime(__DATE__, __TIME__));
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//=============================================================================================================
if (! rtc.begin()) {
Serial.println("Não foi possível encontrar o RTC");
Serial.flush();
abort();
}
//============================================================================================================
// Initialize encoder pins
pinMode(ENCODER_CLK, INPUT_PULLUP);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_SW, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), readEncoder, FALLING);
menu ();
//============================================================================================================
// Variáveis de controle de tempo do motor
temp1.defiSP( 60000*motor );
//temp1.defiSP( 3.600.000);
temp2.defiSP(1000);
tempImpr.defiSP(60000*motor);
// tempImpr.defiSP(3600000);
//=============================================================================================================
pinMode(mot, OUTPUT);
digitalWrite(mot, 0);// Desliga o motor no início
pinMode(mosfetPin, OUTPUT);
pinMode(RelePin, OUTPUT);
analogWrite(mosfetPin, 0); // Desliga o aquecedor no início
// Configura o PID
myPID.SetOutputLimits(0, 255); // Limite de saída PWM entre 0 e 255
myPID.SetMode(AUTOMATIC);
myPID.SetSampleTime(1000); // Tempo de amostragem em milissegundos (1 segundo)
//lcdlimp() ;
secondTest2();
}
//============================================================================================================
void lcdlimp()
{
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(" ");
}
// Função de tempo do motor
void temp() {
if (tempImpr.Saida(1))
{
Serial.print("Tempo 1: ");
digitalWrite( mot, HIGH );
if ( temp1.Saida(1))
{
Serial.print(" Tempo 2: ");
digitalWrite( mot, LOW );
tempImpr.Saida(0);
temp1.Saida(0);
}
}}
//============================================================================================================
// Função do enconder
void readEncoder() {
int dtValue = digitalRead(ENCODER_DT);
if (dtValue == HIGH) {
counter++; // Clockwise
if (choice3 == true) {
Setpoint += 0.1;
}
if (choice2 == true) {
Setpointu += 5;
}
if (choice4 == true) {
falta += 1;
if ( falta == 30) {
falta = 0;
}
}
}
if (dtValue == LOW) {
counter--; // Counterclockwise
if (choice3 == true) {
Setpoint -= 0.1;
}
if (choice2 == true) {
Setpointu -= 5;
}
if (choice4 == true) {
falta -= 1;
if ( falta == -1) {
falta = 30;
}
}
}
}
//============================================================================================================
// Get the counter value, disabling interrupts.
// This make sure readEncoder() doesn't change the value
// while we're reading it.
int getCounter() {
int result;
noInterrupts();
result = counter;
interrupts();
return result;
}
//============================================================================================================
void resetCounter() {
noInterrupts();
choice = !choice ;
choice2 = false ;
choice3 = false ;
tempImpr.Saida(0);
temp1.Saida(0);
interrupts();
}
//============================================================================================================
void Counterdata()
{
// Se faltar mais de 4 dias para a choca move os motores as 6:00, 12:00, 17:56 e 23:59
if (falta >= 1)
{
if ( Hor == 24 && (Min == 00 || Min == 00) && Sec == 01)
{
falta -= 1 ;
delay(100);
}
}
if (falta == 3) {
if ( Hor == 6 && (Min == 00 || Min == 00) && Sec == 01)
{
Setpoint = 37.6; // Temperatura de referência
Setpointu = 63;
delay(100);
secondTest();
}
if ( Hor == 10 && (Min == 00 || Min == 00) && Sec == 01)
{
Setpoint = 37.5; // Temperatura de referência
Setpointu = 64;
delay(100);
secondTest();
}
if ( Hor == 14 && (Min == 00 || Min == 00) && Sec == 01)
{
Setpoint = 37.4; // Temperatura de referência
Setpointu = 65;
secondTest();
delay(100);
}
}
// Se faltar 4 dias ou menos para chocar a chocadeira para na posição 80
if (falta == 2)
{
if ( Hor == 6 && (Min == 00 || Min == 00) && Sec == 01)
{
Setpoint = 37.3; // Temperatura de referência
Setpointu = 66;
delay(100);
secondTest();
}
if ( Hor == 10 && (Min == 00 || Min == 00) && Sec == 01)
{
Setpoint = 37.2; // Temperatura de referência
Setpointu = 68;
secondTest();
delay(100);
}
if ( Hor == 14 && (Min == 00 || Min == 00) && Sec == 01)
{
Setpoint = 37.1; // Temperatura de referência
Setpointu = 70;
secondTest();
delay(100);
}
}
if (falta == 1)
{
if ( Hor == 6 && (Min == 00 || Min == 00) && Sec == 01)
{
Setpoint = 37.0; // Temperatura de referência
Setpointu = 72;
delay(100);
secondTest();
}
if ( Hor == 9 && (Min == 00 || Min == 00) && Sec == 01)
{
Setpoint = 36.8; // Temperatura de referência
Setpointu = 73;
secondTest();
delay(100);
}
if ( Hor == 11 && (Min == 00 || Min == 00) && Sec == 01)
{
Setpoint = 36.7; // Temperatura de referência
Setpointu = 75;
secondTest();
delay(100);
}
}
}
//============================================================================================================
void menu ()
{
//----------------------------------------------------------------------------------------------------------
if (choice == false)
{
//temp();
choice2 = false ;
choice3 = false ;
choice4 = false ;
lcd.setCursor(0, 0);
lcd.print(" Temperatura:");
lcd.setCursor(15, 0);
lcd.print(Input);
lcd.setCursor(10, 0);
//lcd.print(" ");
// delay(100);
lcd.setCursor(0, 1);
lcd.print(" Umidade:");
lcd.setCursor(16, 1);
//lcd.print(faltam );
lcd.print(int (Input1));
lcd.setCursor(10, 1);
//lcd.print(" ");
delay(100);
lcd.setCursor(0, 2);
lcd.print(" Cont. de dias:");
lcd.setCursor(16, 2);
lcd.print(falta);
// lcd.print(int (tempImpr.CV/6000));
delay(10);
}
//----------------------------------------------------------------------------------------------------------
else if (counter == 1 && choice == true)
{
lcdlimp();
while (choice == true)
{
// lcd.clear();
choice3 = true;
//readEncoder();
lcd.setCursor(0, 0);
lcd.print(" Temperatura: ");
lcd.setCursor(15, 0);
lcd.print(Setpoint);
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(" ");
delay(400);
if (digitalRead(ENCODER_SW) == LOW)
{
choice = false;
counter = 0;
secondTest();
lcdlimp();
}
}// código a ser executado repetidamente
}
//----------------------------------------------------------------------------------------------------------
else if (counter == 2 && choice == true)
{
while (choice == true)
{
// lcd.clear();
choice2 = true;
lcd.setCursor(0, 0);
lcd.print(" Umidade: ");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(14, 0);
lcd.print(Setpointu);
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(" ");
delay(400);
if (digitalRead(ENCODER_SW) == LOW)
{
choice = false;
counter = 0;
secondTest();
lcdlimp();
}
}// código a ser executado repetidamente
}
//----------------------------------------------------------------------------------------------------------
else if (counter == 3 && choice == true)
{
while (choice == true) {
//lcd.clear();
choice4 = true;
lcd.setCursor(0, 0);
lcd.print(" Nascimento em: ");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(17, 0);
lcd.print(falta);
DateTime now = rtc.now();
DateTime future (now + TimeSpan(falta,0,0,0));
// Serial.print(" now + d + h + m + s: ");
lcd.setCursor(0, 2);
lcd.print("Data de Nascimento:");
lcd.setCursor(0, 3);
lcd.print(future.day(), DEC);
lcd.print('/');
lcd.print(future.month(), DEC);
lcd.print('/');
lcd.print(future.year(), DEC);
lcd.print(" (");
lcd.print(daysOfTheWeek[future.dayOfTheWeek()]);
lcd.print(") ");
delay(400);
if (digitalRead(ENCODER_SW) == LOW)
{
choice = false;
counter = 0;
secondTest();
lcdlimp();
}
}
}
//----------------------------------------------------------------------------------------------------------
else if (counter == 4 && choice == true)
{
resetCounter();
menu () ;
temp();
}
}
//============================================================================================================
//============================================================================================================
void loop()
{
//faltam = tempImpr.defiSP();
DateTime now = rtc.now();
Hor = now.hour();
Min = now.minute();
Sec = now.second();
Data = now.day();
// calcula uma data
DateTime future (now + TimeSpan(falta,0,0,0));// Serial.print(" now + d + h + m + s: ");
Serial.println();
Serial.print("Data de Nascimento: ");
Serial.print(future.day(), DEC);
Serial.print('/');
Serial.print(future.month(), DEC);
Serial.print('/');
Serial.print(future.year(), DEC);
Serial.print('-');
Serial.println();
lcd.setCursor(0, 3);
lcd.print("Nasc. em:");
lcd.setCursor(9, 3);
lcd.print(future.day(), DEC);
lcd.print('/');
lcd.print(future.month(), DEC);
lcd.print('/');
lcd.print(future.year(), DEC);
Serial.println();
//============================================================================================================
// Leitura da temperatura
Input = dht.readTemperature();
Input1 = dht.readHumidity();
temp();
// Controle PID
myPID.Compute();
//============================================================================================================
int dtValue2 = digitalRead(ENCODER_DT);
// Ajuste da potência do aquecedor usando PWM
int heaterPower = Output;
analogWrite(mosfetPin, heaterPower);
// Exibir dados no monitor serial
Serial.print("Temperatura: ");
Serial.print(Input);
Serial.print(" °C | Potência do Aquecedor: ");
Serial.print(heaterPower);
Serial.println(" (0-255)");
Serial.println();
Serial.print("Hora atual: ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
Serial.print(now.day(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.year(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.println();
delay(500);
//============================================================================================================
if ( Input1 < Setpointu )
{
digitalWrite( RelePin, HIGH );
menu () ;
}
else if (Input1 >= Setpointu )
{
digitalWrite( RelePin,LOW );
menu () ;
}
//============================================================================================================
//dtValue2 == HIGH
if (dtValue2 == HIGH )
{
if (digitalRead(ENCODER_SW) == LOW)
{
resetCounter();
menu () ;
}
if (counter == 1 && choice == false)
{
menu () ;
lcd.setCursor(0, 0);
lcd.print(">>");
delay(100);
}
else if (counter == 2 && choice == false)
{
menu () ;
lcd.setCursor(0, 1);
lcd.print(">>");
delay(100);
}
else if (counter == 3 && choice == false)
{
menu () ;
lcd.setCursor(0, 2);
lcd.print(">>");
delay(100);
}
else if (counter == 4)
{
lcd.setCursor(0, 1);
lcd.print(">>");
counter = 1 ;
menu () ;
delay(50);
}
else if (counter < 0 )
{
counter = 3 ;
menu () ;
}
else if (counter == 0 )
{
menu () ;
}
// delay(200);
}
}
//============================================================================================================
void secondTest() {
int eeAddress = sizeof( float); //Move address to the next byte after float 'f'.
MyObject customVar; //Variable to store custom object read from EEPROM.
//EEPROM.put (eeAddress, customVar) ;
customVar.t = float (Setpoint);
customVar.u = float (Setpointu);
customVar.c = falta;
EEPROM.put(eeAddress, customVar);
EEPROM.get(eeAddress, customVar) ;
Serial.println("Read custom object from EEPROM: ");
Serial.println(customVar.t);
Serial.println(customVar.u);
Serial.println(customVar.c);
}
//============================================================================================================
void secondTest2() {
int eeAddress = sizeof( float); //Move address to the next byte after float 'f'.
MyObject customVar; //Variable to store custom object read from EEPROM.
//customVar.t = float(Setpoint)
EEPROM.get(eeAddress, customVar);
if (customVar.t > 0 && customVar.u > 0)
{
Setpoint = customVar.t ;
Setpointu = customVar.u;
falta = customVar.c ;
Serial.println("Read custom object from EEPROM: ");
Serial.println(customVar.t);
Serial.println(customVar.u);
Serial.println(customVar.c);
}
}
//============================================================================================================