// include the library code:
#include <CPU.h>  // Include the library to use the CPU temperature sensor
#include <LiquidCrystal.h>
#include <SimpleDHT.h>
#include <Servo.h>
#include <ezButton.h>
#include <Wire.h>
#include "pitches.h"

/*
 * Test sketch for the RP2040 CPU temperature sensor library
 * Author: Francisco Torres (deimoshall.dev)
 * Date: July 2023
 * License: MIT
 * Repository: https://github.com/DeimosHall/RP2040_CPU_Temperature.git
*/
CPU cpu;  // Create an instance of the CPU temperature sensor

ezButton button2(14);  // create ezButton object that attach to pin 4;
#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
#define DHTTYPE DHT21   // DHT 21 (AM2301)
#define SPEAKER_PIN 2
const int gameTones[] = { NOTE_G3, NOTE_C4, NOTE_E4, NOTE_G5};
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 10, d5 = 9, d6 = 8, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
//Parametros do time
unsigned int falta = 1;
unsigned long centesimos;
unsigned long minutos;
unsigned long horas;
unsigned long segundos;
unsigned long dia;
unsigned long piscatempo;
int valor;
float pos = 0.0; // Variable where the arm's position will be stored (in degrees)
float step = 1.0; // Variable used for the arm's position step
int motorpin = 3;
unsigned long umid = 180;
unsigned long cont;
unsigned long tempo;
unsigned int bpm;
unsigned int vira;
unsigned int eclodibilidade = minutos;
unsigned long incubacao;
void serial();
void seleciona();
void piscaLed();
void relogio();
unsigned long alterVeloc = 1;
unsigned int programa = 1;

//Folga da eclodibilidade
unsigned long currentTime = 0;
unsigned long previousTime = 0;
unsigned long inter;
unsigned long inter1 = 60 * 3;//com o parametro 60 ha uma contagem de um minuto vezes tres dias = 4320
// Tempo de teste no cronometro da WORWI 60 * 3 = 3 MINUTOS LIGADO.
unsigned long inter2 = 60 * 2;//Tempo de folga da galinha 30000 / 2000
// Tempo de teste no cronometro da WORWI 60 = 1 MINUTO DELIGADO.
//Tabela de aves
int programGalinha = 21;// ou 504 horas.
int bpmGalinha = 180; // minutos; // interval at which to blink (milliseconds) 333 para configurar 180 bpm (frequência cardiaca da galina).
int umdGalinha = 29;
int programCodorna = 17;// ou 408 horas.
int programGanso = 34;// ou 816 horas.
int programPavao = 28;// ou 672 horas.
int programPeru = 28;// ou 672 horas.
int programAngola = 28;// ou 672 horas.
int programPato = 28;// ou 672 horas.
int programMarreco = 30;// ou 720 horas.
int programFaisao = 28;// ou 672 horas.
int programPerdizBr = 21;// ou 504 horas.
int programPerdizCk = 24;// ou 576 horas.
int programEMA = 42;// ou 1008 horas.
int programMUTUM = 30;// ou 720 horas.
int programPombo = 17;// ou 408 horas.
int programMacucu = 18;// ou 432 horas.
int programAvestruz = 42;// ou 1008 horas.

int pinDHT22 = 4;
SimpleDHT22 dht22(pinDHT22);
Servo motor;

// constants won't change. Used here to set a pin number:
const int ledPin1 = 5;  // the number of the LED pin resistência
const int ledPin2 = 6;  // the number of the LED pin ventilação
const int ledPin3 = 13;  // the number of the LED pin inclodibilidade
const int resPin1 = 15; // the number of the LED pin continuidade da resistência

// Variables will change:
bool ledState1 = HIGH;  // ledState used to set the LED
int ledState2 = HIGH;  // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;  // will store last time LED was updated

//constants won't change: // interval at which to blink (milliseconds) para configurar bpm (frequência cardiaca da ave).
const long interval2 = umid;  // interval at which to blink (milliseconds) para configurar umidade da ave).

void setup() {
  Wire.begin();
  cpu.begin();  // Initialize the CPU temperature sensor
  Serial1.begin(115200);
  Serial1.println("Pi Pico Eclodidor de ovos!");
  Serial1.println("-------------------------------");
  Serial1.println("CPU temperature: " + String(cpu.getTemperature()) + " °C");
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  button2.loop(); // MUST call the loop() function first
  // Print a message to the LCD.
  lcd.setCursor(0, 0);
  lcd.print("Choca_Aviao(!)");
  delay(1000);
  lcd.clear();
  valor = analogRead(resPin1);
  // set the digital pin as output:
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(resPin1, INPUT_PULLUP);
  pinMode(SPEAKER_PIN, OUTPUT);

  motor.attach(motorpin);
  motor.write(pos);
  button2.setDebounceTime(50); // set debounce time to 50 milliseconds

}
void playLevelUpSound() {
  tone(SPEAKER_PIN, NOTE_E4);
  delay(150);
  tone(SPEAKER_PIN, NOTE_G4);
  delay(150);
  tone(SPEAKER_PIN, NOTE_E5);
  delay(150);
  tone(SPEAKER_PIN, NOTE_C5);
  delay(150);
  tone(SPEAKER_PIN, NOTE_D5);
  delay(150);
  tone(SPEAKER_PIN, NOTE_G5);
  delay(150);
  noTone(SPEAKER_PIN);
}
void loop() {
  relogio();
  piscaLed();  
  seleciona();
  serial();
}
void relogio() {
  //relógio é a divisão do quantador millis().
  cont = millis();
  segundos = cont / falta;
  centesimos = cont / 100;
  minutos = segundos / 60;
  horas = minutos / 60;
  dia = horas / 24;
  return;
}
void servocomando() {
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    motor.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);
    //Servos de rotação contínua responderão à função writeMicrosecond de maneira análoga à função write.
    //motor.writeMicroseconds(1500);  // set servo to mid-point 1500
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    motor.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);
  }
}
void piscaLed() {
  piscatempo = millis();
  currentTime = piscatempo / 1000;
  if (ledState1) {
    inter = inter1;
  } else {
    inter = inter2;
  }
  //Folga eclodibilidade (tempo que a ave levaria para umidecer, resfriar, alimentar e defecar.
  if ((currentTime - previousTime) >= inter) {
    previousTime = currentTime;
    servocomando();
    ledState1 = !ledState1;
    digitalWrite(ledPin3, !ledState1);
    delay(15);
  }
  //Eclosão dos pintaguinhos
  if (dia >= programa) {
    lcd.clear();
    lcd.noBlink();
    lcd.setCursor(0, 1);
    lcd.print("Ovos ECLODINDO");
    delay(1000);
    // Turn on the blinking cursor:
    lcd.blink();
    lcd.setCursor(0, 0);
    lcd.print("Ovos ECLODINDO");
    delay(1000);
    return;
  }
  //set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  // here is where you'd put code that needs to be running all the time.
  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();
  if ((currentMillis - previousMillis) >= interval2) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;


    if ((umid = 2) || (umid < 180) && (umid = umid + 10)) {
      umid = (random (umid));

    }
    // if the LED is off turn it on and vice-versa:
    if (ledState2 == LOW) {
      ledState2 = umid;
    } else {
      ledState2 = umid;
    }
  }
}
void seleciona() {
  int incubar = programa - dia;
  lcd.setCursor(0, 1);
  lcd.print("F:");
  lcd.print(incubar);
  lcd.print("d H:");
  lcd.print(horas);
  //lcd.noBlink();
  lcd.setCursor(11, 1);
  lcd.print(" P:");
  lcd.print(long (alterVeloc));

  button2.loop(); // MUST call the loop() function first
  int btn2State = button2.getState();
  // read without samples.
  // @remark We use read2 to get a float data, such as 10.1*C
  //    if user doesn't care about the accurate data, use read to get a byte data, such as 10*C.
  float temperature = 0;
  float humidity = 0;
  int err = SimpleDHTErrSuccess;
  if ((err = dht22.read2(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
    delay(millis() / 2000);
    return;
  }

  // start working...
  lcd.setCursor(0, 0);
  lcd.print(temperature);
  lcd.print("*C, ");
  lcd.setCursor(8, 0);
  lcd.print(humidity);
  lcd.print("RU%");
  //verifica a resistência de aquecimento
  if (temperature <= 24) {
    if (valor == 0) {
      playLevelUpSound();
      delay(3);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Verificar");
      lcd.setCursor(0, 1);
      lcd.print("ResistorQueimada");
      delay(1000);
      lcd.clear();
    }
  }
  if (button2.isPressed())
    (alterVeloc = alterVeloc + 1);
  if (alterVeloc == 1) {
    programa = programGalinha;
    if (incubar >= 2) {
      if (temperature >= 37.8) {
        digitalWrite(ledPin1, !HIGH);
      }
      else if (temperature <= 37.4)  {
        bpm = bpmGalinha += eclodibilidade;
        digitalWrite(ledPin1, ledState1 * bpm);
      }
      else
      {
        //lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Chocagem");
        delay(1000);
      }
      //Alarme de umidade
      if ((float)humidity <= 50) {
        playLevelUpSound();
        delay(300);
        digitalWrite(ledPin2, !HIGH);
        lcd.setCursor(0, 0);
        lcd.print("**FaltaUmidade**");
        delay(1000);
        lcd.clear();
      }
      else if (humidity >= 51.5) {
        digitalWrite(ledPin2, ledState2);
        int (umid) = humidity ;
      }
      else {
        //lcd.clear();
        lcd.setCursor(8, 0);
        lcd.print("Perfeita");
        delay(1000);

      }
    }
    if (incubar <= 2) {
      if (temperature >= 36.9) {
        digitalWrite(ledPin1, !HIGH);
      }
      if (temperature <= 36.7)  {
        bpm = bpmGalinha += eclodibilidade;
        digitalWrite(ledPin1, ledState1 * bpm);
      }
      //Alarme de umidade
      if ((float)humidity <= 59.5) {
        playLevelUpSound();
        delay(300);
        digitalWrite(ledPin2, !HIGH);
      }
      if (humidity <= 65) {
        digitalWrite(ledPin2, ledState2);
        int (umid) = humidity ;
      }
    }
  }
  if (alterVeloc == 2) {
    programa = programCodorna;
    if ((float)temperature <= 37.8) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }

    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc == 3) {
    programa = programGanso;
    if ((float)temperature <= 37.6) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }
    /*if ((float)humidity <= 26.5) {
      tone(beep, 700);
      delayMicroseconds(1000);
      noTone(beep);
      delayMicroseconds(1000);
      }*/
    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc == 4) {
    programa = programPavao;
    if ((float)temperature <= 37.6) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }
    /*if ((float)humidity <= 26.5) {
      tone(beep, 700);
      delayMicroseconds(1000);
      noTone(beep);
      delayMicroseconds(1000);
      }*/
    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc == 5) {
    programa = programPeru;
    if ((float)temperature <= 37.6) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }
    /*if ((float)humidity <= 26.5) {
      tone(beep, 700);
      delayMicroseconds(1000);
      noTone(beep);
      delayMicroseconds(1000);
      }*/
    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc == 6 ) {
    programa = programAngola;
    if ((float)temperature <= 37.7) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }
    /*if ((float)humidity <= 26.5) {
      tone(beep, 700);
      delayMicroseconds(1000);
      noTone(beep);
      delayMicroseconds(1000);
      }*/
    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc == 7 ) {
    programa = programPato;
    if ((float)temperature <= 37.6) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }
    /*if ((float)humidity <= 26.5) {
      tone(beep, 700);
      delayMicroseconds(1000);
      noTone(beep);
      delayMicroseconds(1000);
      }*/
    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc == 8 ) {
    programa = programMarreco;
    if ((float)temperature <= 37.6) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }
    /*if ((float)humidity <= 26.5) {
      tone(beep, 700);
      delayMicroseconds(1000);
      noTone(beep);
      delayMicroseconds(1000);
      }*/
    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc == 9 ) {
    programa = programFaisao;
    if ((float)temperature <= 37.8) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }
    /*if ((float)humidity <= 26.5) {
      tone(beep, 700);
      delayMicroseconds(1000);
      noTone(beep);
      delayMicroseconds(1000);
      }*/
    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc == 10 ) {
    programa = programPerdizBr;
    if ((float)temperature <= 37.5) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }
    /*if ((float)humidity <= 26.5) {
      tone(beep, 700);
      delayMicroseconds(1000);
      noTone(beep);
      delayMicroseconds(1000);
      }*/
    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc == 11 ) {
    programa = programPerdizCk;
    if ((float)temperature <= 37.8) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }
    /*if ((float)humidity <= 26.5) {
      tone(beep, 700);
      delayMicroseconds(1000);
      noTone(beep);
      delayMicroseconds(1000);
      }*/
    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc == 12 ) {
    programa = programEMA;
    if ((float)temperature <= 36) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }
    /*if ((float)humidity <= 26.5) {
      tone(beep, 700);
      delayMicroseconds(1000);
      noTone(beep);
      delayMicroseconds(1000);
      }*/
    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc == 13 ) {
    programa = programMUTUM;
    if ((float)temperature <= 37.7) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }
    /*if ((float)humidity <= 26.5) {
      tone(beep, 700);
      delayMicroseconds(1000);
      noTone(beep);
      delayMicroseconds(1000);
      }*/
    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc == 14 ) {
    programa = programPombo;
    if ((float)temperature <= 37.8) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }
    /*if ((float)humidity <= 26.5) {
      tone(beep, 700);
      delayMicroseconds(1000);
      noTone(beep);
      delayMicroseconds(1000);
      }*/
    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc == 15 ) {
    programa = programMacucu;
    if ((float)temperature <= 37.7) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }
    /*if ((float)humidity <= 26.5) {
      tone(beep, 700);
      delayMicroseconds(1000);
      noTone(beep);
      delayMicroseconds(1000);
      }*/
    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc == 16 ) {
    programa = programAvestruz;
    if ((temperature <= 36) && (temperature <= 36.5)) {
      //btm = ;
      digitalWrite(ledPin1, ledState1);
    }
    else {
      digitalWrite(ledPin1, !HIGH);
    }
    /*if ((float)humidity <= 26.5) {
      tone(beep, 700);
      delayMicroseconds(1000);
      noTone(beep);
      delayMicroseconds(1000);
      }*/
    if ((humidity >= 27) && (humidity <= 30)) {
      digitalWrite(ledPin2, ledState2);
    }
    else {
      digitalWrite(ledPin2, !HIGH);
    }
    return;
  }
  if (alterVeloc >= 17)
  {
    alterVeloc = 1;
    return;
  }
}
void serial() {
  /*Serial1.print(F("SERVO State : ")); Serial.println(pos);
  Serial1.print(F("BPM : ")); Serial.println(umid);*/
}
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module