Egg incubator project

I wrote a simple code in steps, but when you reach a certain stage, many problems begin to appear. The link to the project simulation and the code is here. Is there any help?
How it works: When you press settings, it enters settings mode, starting with setting the temperature to raise and lower the temperature you want to reach, then humidity, then incubation days, then the engine runs every 1 to 9 hours, once for a minute, but entering the settings is complicated and does not work.

I have not yet added the saving inside the EEPROM for the settings. Also, each indicator LED must light up when the set temperature or humidity is reached, and the engine indicator LED must turn on when the engine starts. Also, when the days end, such as 21 days, another indicator LED light up.

Is there a question hidden somewhere?

I think you need to have a variable to indicate what the screen state is, so that when Setting mode is pressed for example, it stays in that state.

I also suggest putting code into functions, it will be easier to read and maintain.

ETA: It turns out you already have a variable to indicate the current screen. I think the problem with the buttons is not setting the "previous_xxx_state" variables.

Anyway, here is an updated sketch, you can compare the differences

#include <DHT.h>
#include<Wire.h>
#include <LiquidCrystal_I2C.h>
#define DHTPIN 2
#define DHTTYPE DHT22
#include "RTClib.h"
#include "customchar.h"

RTC_DS1307 RTC;
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Define the variables for temperature and humidity
float hum;
float temp;

// Define the strings for temperature and humidity
char tempStr[6];
char humStr[5];

// Define the pins for the buttons
#define UP_PIN 3
#define DOWN_PIN 4
#define SAVE_PIN 5
#define SETTING_PIN 6

// Define the pins for the relay, the fan, and the LEDs
#define RELAY_PIN 7
#define FAN_PIN 8
#define LED1_PIN 9
#define LED2_PIN 10
#define LED3_PIN 11

// Define the values for the buttons
#define UP_VALUE 0
#define DOWN_VALUE 1
#define SAVE_VALUE 2
#define SETTING_VALUE 3
#define NONE_VALUE 4

// Define the variables for the settings
float temp_setting = 25.0; // default temperature setting
float hum_setting = 50.0; // default humidity setting
int day_setting = 21; // default day setting
int engine_setting = 5; // default engine setting

enum {Normal, Temperature, Humidity, Day, Engine} ;

int setting_mode = Normal; // 0 for normal mode, 1 for temperature mode, 2 for humidity mode, 3 for day mode, 4 for engine mode

// Define the variables for the button states
int up_state = 0;
int down_state = 0;
int save_state = 0;
int setting_state = 0;

int prev_up_state = 0;
int prev_down_state = 0;
int prev_save_state = 0;
int prev_setting_state = 0;

// Define the variables for the engine time and the days
unsigned long engine_time = 0; // the time when the engine last ran
unsigned long start_time = 0; // the time when the program started
int engine_interval = 3600000; // the interval between engine runs in milliseconds
int engine_duration = 60000; // the duration of engine runs in milliseconds
int day_count = 0; // the number of days passed

void setup() {
  Wire.begin();

  dht.begin();
  lcd.init();
  lcd.clear();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("  H - Electro");
  delay(2000);
  lcd.clear();
  RTC.begin(); // load the time from your computer.


  lcd.createChar(0, TempChar);
  lcd.createChar(1, HumChar);
  lcd.createChar(2, Ochar);

  // set up the button pins as inputs with pull-up resistors
  pinMode(UP_PIN, INPUT_PULLUP);
  pinMode(DOWN_PIN, INPUT_PULLUP);
  pinMode(SAVE_PIN, INPUT_PULLUP);
  pinMode(SETTING_PIN, INPUT_PULLUP);

  // set up the relay, the fan, and the LED pins as outputs
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(FAN_PIN, OUTPUT);
  pinMode(LED1_PIN, OUTPUT);
  pinMode(LED2_PIN, OUTPUT);
  pinMode(LED3_PIN, OUTPUT);

  // get the initial time
  start_time = millis();

  if (! RTC.isrunning()) {
    lcd.setCursor(1, 1);
    lcd.print("RTC is NOT work");// This will reflect the time that your sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
}

void check_buttons (void)
{
  // read the button states
  up_state = digitalRead(UP_PIN);
  down_state = digitalRead(DOWN_PIN);
  save_state = digitalRead(SAVE_PIN);
  setting_state = digitalRead(SETTING_PIN);

  // check if any button is pressed
  if (up_state == LOW || down_state == LOW || save_state == LOW || setting_state == LOW) 
  {
    // clear the screen
    lcd.clear();

    // check which button is pressed and change the settings accordingly
    if (setting_state == LOW && prev_setting_state == HIGH ) {
      // switch to the next setting mode
      setting_mode = (setting_mode + 1) % 5;
    }
    else if (up_state == LOW && prev_up_state == HIGH) {
      // increase the current setting value
      if (setting_mode == 1) {
        temp_setting += 0.5;
      }
      else if (setting_mode == 2) {
        hum_setting += 1.0;
      }
      else if (setting_mode == 3) {
        day_setting += 1;
      }
      else if (setting_mode == 4) {
        engine_setting = (engine_setting % 9) + 1;
      }
    }
    else if (down_state == LOW && prev_down_state == HIGH) {
      // decrease the current setting value
      if (setting_mode == 1) {
        temp_setting -= 0.5;
      }
      else if (setting_mode == 2) {
        hum_setting -= 1.0;
      }
      else if (setting_mode == 3) {
        day_setting -= 1;
      }
      else if (setting_mode == 4) {
        engine_setting = (engine_setting + 7) % 9 + 1;
      }
    }
    else if (save_state == LOW && prev_save_state == HIGH) {
      // save the current setting value and switch to the next setting mode
      setting_mode = (setting_mode + 1) % 5;
    }
  }

  prev_up_state = up_state;
  prev_down_state = down_state;
  prev_save_state = save_state;
  prev_setting_state = setting_state;
}

void loop() {
  hum = dht.readHumidity();
  temp = dht.readTemperature();
  DateTime now = RTC.now();

  if (isnan(temp) || isnan(hum)) {
    // Print an error message
    lcd.setCursor(0, 0);
    lcd.print("No Sensor Detect");
  }
  else {
    dtostrf(temp, 4, 1, tempStr);
    dtostrf(hum, 2, 0, humStr);
  }

  check_buttons();

  // display the current setting mode and value
  if (setting_mode == Temperature) {
    lcd.setCursor(0, 0);
    lcd.print("Temp Mode");
    lcd.setCursor(0, 1);
    lcd.print("T: ");
    lcd.print(temp_setting);
    lcd.print(" C");
  }
  else if (setting_mode == Humidity) {
    lcd.setCursor(0, 0);
    lcd.print("Hum Mode");
    lcd.setCursor(0, 1);
    lcd.print("H: ");
    lcd.print(hum_setting);
    lcd.print(" %");
  }
  else if (setting_mode == Day) {
    lcd.setCursor(0, 0);
    lcd.print("Day Mode");
    lcd.setCursor(0, 1);
    lcd.print("D: ");
    lcd.print(day_setting);
  }
  else if (setting_mode == Engine) {
    lcd.setCursor(0, 0);
    lcd.print("Engine Mode");
    lcd.setCursor(0, 1);
    lcd.print("M: ");
    lcd.print(engine_setting);
  }
  else if (setting_mode == Normal)
  {
    // display the normal mode screen
    lcd.clear();

    // set temp
    lcd.setCursor(0, 0);
    lcd.write(byte(0));
    lcd.print(tempStr);
    lcd.setCursor(5, 0);
    lcd.write(byte(2));
    lcd.print("C");

    // set Humidity
    lcd.setCursor(8, 0);
    lcd.write(byte(1));
    lcd.print(humStr);
    lcd.print("%");

    //Motor Time
    lcd.setCursor(13, 0);
    lcd.print("M");
    lcd.print(":");
    lcd.print(engine_setting);

    // day and counter
    lcd.setCursor(0, 1);
    // get the current date and time
    DateTime current = RTC.now();
    // get the start date and time
    DateTime start = DateTime(start_time / 1000);
    // get the difference between current and start
    TimeSpan diff = current - start;
    // calculate the number of days passed
    day_count = diff.days();
    // display the number of days passed
    lcd.print(day_count);
    lcd.print(" = ");
    // display the remaining days
    lcd.print("D ");
    lcd.print(day_setting - day_count);
  }


  // control the relay and the fan based on the temperature and humidity settings
  if (temp > temp_setting) {
    // turn on the relay and the fan
    digitalWrite(RELAY_PIN, HIGH);
    digitalWrite(FAN_PIN, HIGH);
  }
  else if (temp < temp_setting - 1) {
    // turn off the relay and the fan
    digitalWrite(RELAY_PIN, LOW);
    digitalWrite(FAN_PIN, LOW);
  }

  // control the LEDs based on the engine time and the days
  if (millis() - engine_time >= engine_interval * engine_setting) {
    // turn on the first LED and run the engine for one minute
    digitalWrite(LED1_PIN, HIGH);
    // add your code to run the engine here
    delay(engine_duration);
    // turn off the first LED and stop the engine
    digitalWrite(LED1_PIN, LOW);
    // add your code to stop the engine here
    // update the engine time
    engine_time = millis();
  }

  if (day_count >= day_setting) {
    // turn on the second LED and indicate the end of the program
    digitalWrite(LED2_PIN, HIGH);
    // add your code to end the program here
  }
  else if (day_count >= day_setting - 1) {
    // turn on the third LED and indicate the last day
    digitalWrite(LED3_PIN, HIGH);
    // add your code to do something on the last day here
  }
  delay(300);
}

Thank you, I have fixed the interface. Can you please help in fixing the number of days and the save button to save the value in an EEPROM? A picture showing how it should look.

The second line from the left is an ascending timer of seconds, hours, days. The number between parentheses is the number of days that have passed - the number after = is the number of days stored in the settings.

لقطة شاشة 2024-01-25 195640

1 Like

Hello, I want to make the same circuit. Can you please share the circuit connection diagram and circuit codes with me? please help me

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.