Incubator control using Arduino

Hi,
Need guidance on working of Arduino. I am developing an incubator using the following circuit

Here I am using a buck converter of 3 amp rating to reduce voltage to required level for Arduino Uno board and also the ultrasonic humidifier. Everything is just fine until the humidifier starts which is when pin 7 goes high. This pin is not connected any hardware and I have written code to connect pushbuttons which I have ordered online but not yet received. But somehow this pin goes high when pin 8 i.e. ultrasonic humidifier pin goes high. So I wanted to know if there is any internal working I might be overlooking. In the diagram I have't drawn the 12k resistor for each mosfet between gate and source pins however they are present in real circuit. Kindly help me understand the problem here. The following is the code I used -

/*
  Incubator for 20 Eggs code by K.N.Ganesh
*/
#include <Arduino.h>
#include <LiquidCrystal_I2C.h>
// Include the libraries:
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <Servo.h>
//#include <TimeLib.h>

#define DHTPIN 2
#define FAN 4
#define SERVO 9
#define HUMIDIFIER 8
#define HEATER 12

/*Keys*/
#define MENUSET 7
#define INCRSET 11
#define DECRSET 13
#define EXIT 5
#define DHTTYPE DHT11
float hum = 0;
float temp = 0;

float prevhum = 0;
float prevtemp = 0;

LiquidCrystal_I2C lcd(0x27, 16, 2);  // I2C address 0x3F, 16 column and 2 rows
DHT dht(DHTPIN, DHTTYPE);
int day = 0;
unsigned long dayprevMillis = 0;
unsigned long daycurrentMillis = 0;
int hour = 0;
unsigned long hourprevMillis = 0;
unsigned long hourcurrentMillis = 0;
// int angle = 24;

// unsigned long turnerprevmillis = 0;
// unsigned long turnercurrentmillis = 0;

bool ShowMenu = 0;

bool menupressed = 0;
bool menuactive = 0;
bool exitpressed = 0;
int submenuselection = 0;
bool submenuentered = 0;

bool incrpressed = 0;
bool tempmenu = 0;
bool humidmenu = 0;
bool daymenu = 0;
bool decrpressed = 0;

Servo servo;

// Define global variables
unsigned long turnerpreviousMillis = 0;
const unsigned long interval = 200;  // Interval for angle changes (in milliseconds)
int angle = -1;
int state = 0;

char value[16];  // for lcd display

void turner() {
  unsigned long currentMillis = millis();

  if (day <= 18) {  // turn egg upto eighteen days
    if (hour == 6) {
      if (state == 0) {
        if (angle == -1) {
          angle = 12;
        }
        if (angle < 48) {
          servo.write(angle);
          angle++;
          turnerpreviousMillis = currentMillis;
        }
        if (currentMillis - turnerpreviousMillis >= interval) {
          state = 1;
        }
      }
    }

    if (hour == 12) {
      if (state == 1) {
        if (angle > 12) {
          servo.write(angle);
          angle--;
          turnerpreviousMillis = currentMillis;
        }
        if (currentMillis - turnerpreviousMillis >= interval) {
          state = 2;
        }
      }
    }

    if (hour == 18) {
      if (state == 2) {
        if (angle > 0) {
          servo.write(angle);
          angle--;
          turnerpreviousMillis = currentMillis;
        }
        if (currentMillis - turnerpreviousMillis >= interval) {
          state = 3;
        }
      }
    }

    if (hour == 24) {
      if (state == 3) {
        if (angle <= 12) {
          servo.write(angle);
          angle++;
          turnerpreviousMillis = currentMillis;
        }
        if (currentMillis - turnerpreviousMillis >= interval) {
          state = 0;
        }
      }
    }
  }
}


void pollpins() {
  //continuously read menu button
  menupressed = digitalRead(MENUSET);  // this read depends on speed of microcontrols and speed at which user presses and releases button.
  if (menupressed != 0 && menuactive == 1) {
    // This condition passed means we are in submenu
    submenuentered = 1;
  } else if (menupressed != 0) {
    menuactive = 1;
    MainMenu();
  }

  incrpressed = digitalRead(INCRSET);
  if (incrpressed != 0 && menuactive == 1 && submenuentered == 0) {
    // Set curcor position here to show menu item selection
    submenuselection = submenuselection + 1;
    if (submenuselection == 2) { submenuselection = 0; }
    ShowSelectedItem();
  } else if (incrpressed != 0 && menuactive == 1 && submenuentered == 1) {

    ShowSubMenu(0);
  }

  decrpressed = digitalRead(DECRSET);
  if (decrpressed != 0 && menuactive == 1 && submenuentered == 0) {
    // Set curcor position here to show menu item selection
    submenuselection = submenuselection - 1;
    if (submenuselection == 2) { submenuselection = 0; }
    ShowSelectedItem();
  } else if (decrpressed != 0 && menuactive == 1 && submenuentered == 1) {

    ShowSubMenu(1);
  }

  exitpressed = digitalRead(EXIT);  // this read depends on speed of microcontrols and speed at which user presses and releases button.
  if (exitpressed != 0) {
    exitpressed = 0;
    submenuentered = 0;
    menuactive = 0;
    submenuselection = 0;
    ShowValues();
  }
}
void ShowValues() {

  hum = dht.readHumidity();      // read humidity
  temp = dht.readTemperature();  // read temperature
   /*testing code*/
      Serial.print("Temp: ");
      Serial.println(temp);     // print the temperature
     // Serial.print((char)223);  // print ° character
      Serial.println(" C");
      /*testing code Ends*/
      /*testing code*/
      Serial.print("Hum: ");
      Serial.println(hum);  // print the humidity
      Serial.print("%");
      /*testing code Ends*/
        /*testing code*/
      Serial.print("Day: ");
      Serial.println(daycounter());  // print the days
      /*testing code Ends*/

  if (prevhum != hum || prevtemp != temp) {

    // check if any reads failed
    if (isnan(hum) || isnan(temp)) {
      lcd.setCursor(0, 0);
      lcd.print("Failed");
    } else {
      lcd.setCursor(0, 0);  // start to print at the first row
      lcd.print("Temp: ");
      lcd.print(temp);       // print the temperature
      lcd.print((char)223);  // print ° character
      lcd.print("C");

      // /*testing code*/
      // Serial.print("Temp: ");
      // Serial.println(temp);     // print the temperature
      // Serial.print((char)223);  // print ° character
      // Serial.println("C");
      /*testing code Ends*/

      lcd.setCursor(0, 1);  // start to print at the second row
      lcd.print("Hum: ");
      lcd.print(hum);  // print the humidity
      lcd.print("%");

      // /*testing code*/
      // Serial.print("Hum: ");
      // Serial.println(hum);  // print the humidity
      // Serial.print("%");
      /*testing code Ends*/


      lcd.setCursor(10, 1);  // start to print at the second row
      lcd.print("Day: ");
      lcd.print(daycounter());  // print the days
      /*testing code*/
      // Serial.print("Day: ");
      // Serial.println(daycounter());  // print the days
      /*testing code Ends*/
    }
    prevhum=hum;
    prevtemp=temp;
  }
  else
  {
    //Serial.println("No Change");
  }
  Serial.println("Reached Temperature block");
  if (temp > 38.5) {
    digitalWrite(HEATER, LOW);
    digitalWrite(FAN, LOW);
    Serial.println("Heater switched off");
  } else if (temp < 37) {
    digitalWrite(HEATER, HIGH);
    digitalWrite(FAN, HIGH);
    Serial.println("Heater switched on");
  }
  Serial.println("Reached Humidity block");
  if (hum < 60 && day <=18) {
    digitalWrite(HUMIDIFIER, HIGH);
    //digitalWrite(FAN, HIGH);
    Serial.println("Fan Switched on");
  } else if (hum > 65 && day <= 18) {
    digitalWrite(HUMIDIFIER, LOW);
    //digitalWrite(FAN, HIGH);
    Serial.println("Fan Switched off");
  } else if (day > 18 && hum < 70) {
    digitalWrite(HUMIDIFIER, HIGH);
    //digitalWrite(FAN, HIGH);
    Serial.println("Fan Switched on for 19th day");
  }

  /*TURNER CODE*/
}
void MainMenu() {
  // Lcd shows Menu
  Serial.begin(9600);
  lcd.clear();
  lcd.print("Select Setting :");
  lcd.setCursor(1,0);
  lcd.print(" Temp| Hum| Day");
}
int daycounter() {
  daycurrentMillis = millis();
  //day = millis();
  if (daycurrentMillis - dayprevMillis >= 86400000) {
    day++;
    dayprevMillis = daycurrentMillis;
    // Serial.println(day);
  }
  return day;
}
int hourcounter() {
  hourcurrentMillis = millis();
  //day = millis();
  if (hourcurrentMillis - hourprevMillis >= 3600000) {
    hour++;
    hourprevMillis = hourcurrentMillis;
    if (hour == 24) { hour = 1; }
    // Serial.println(day);
  }
  return hour;
}
void lcdprint(char *menuname, char *mnushort, char *value) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Set ");
  lcd.print(menuname);
  lcd.print(":");
  lcd.setCursor(1, 0);
  lcd.print(mnushort);
  lcd.print(" - ");
  lcd.print(value);
}
void ShowSubMenu(int op) {
  if (op == 0) {
    if (submenuselection == 0) {
      temp = temp + 0.5;
      lcdprint("Temperature", "Temp", dtostrf(temp, 2, 1, value));
    } else if (submenuselection = 1) {
      hum = hum + 0.5;
      lcdprint("Humidity", "Hum", dtostrf(hum, 2, 1, value));
    } else if (submenuselection = 2) {
      day = day + 1;
      lcdprint("Days", "Day", dtostrf(day, 2, 0, value));
    }
  } else if (op == 1) {
    if (submenuselection == 0) {
      temp = temp - 0.5;
      lcdprint("Temperature", "Temp", dtostrf(temp, 2, 1, value));
    } else if (submenuselection = 1) {
      hum = hum - 0.5;
      lcdprint("Humidity", "Hum", dtostrf(hum, 2, 1, value));
    } else if (submenuselection = 2) {
      day = day - 1;
      lcdprint("Days", "Day", dtostrf(day, 2, 0, value));
    }
  }
}
void ShowSelectedItem() {
  if (submenuselection == 0) {
    lcd.setCursor(1, 0);
    lcd.print('>');
    lcd.setCursor(1, 6);
    lcd.print(' ');
    lcd.setCursor(1, 11);
    lcd.print(11, ' ');
  } else if (submenuselection == 1) {
    lcd.setCursor(1, 0);
    lcd.print(' ');
    lcd.setCursor(1, 6);
    lcd.print('>');
    lcd.setCursor(1, 11);
    lcd.print(' ');
  } else if (submenuselection == 2) {
    lcd.setCursor(1, 0);
    lcd.print(' ');
    lcd.setCursor(1, 6);
    lcd.print(' ');
    lcd.setCursor(1, 11);
    lcd.print('>');
  }
}

void setup() {

  Serial.begin(9600);
  pinMode(MENUSET, INPUT);
  pinMode(INCRSET, INPUT);
  pinMode(DECRSET, INPUT);
  pinMode(EXIT, INPUT);
  pinMode(DHTPIN, INPUT);
  pinMode(SERVO, OUTPUT);
  pinMode(FAN, OUTPUT);
  pinMode(HUMIDIFIER, OUTPUT);
  pinMode(HEATER, OUTPUT);


  dht.begin();      // initialize the sensor
  lcd.init();       // initialize the lcd
  lcd.backlight();  // open the backlight
  lcd.clear();

  servo.attach(SERVO);
  //Serial.begin(9600);
  servo.write(angle);
}

void loop() {
  pollpins();
  ShowValues();
  turner();
}

I even tried asking Chatgpt and it said my code was ok, and I should be checking the electrical connections made.

These are the component I used -

  1. Servo MG996r
  2. CPU fan 12v dc
  3. DHT11 sensor
  4. 12v Relay module.
  5. 3 IRLZ44N Mosfets to switch relay, fan and humidifier
  6. 5v ultrasonic Humidifier 113khz.
  7. 5200 mah li-ion battery
  8. MP1584 3amp buck converter.
  9. 100 watt bulb.
  10. 1602 LCD with I2C interface.

mosfet source must be grounded

There are quite a few circuit mistakes.

Use a yellow highlighter and trace out each circuit section.

It is grounded through Arduino ,look at the first MOSFET , I have tied up all sources and added ground to the first MOSFET.

This is my first project which I can call useful. According to my understanding of electronics and common sense I created this circuit. So kindly help me understand the mistakes in the circuit and I will post the updated image after I learn from you. Please.

Yes sorry I didn't exactly create the replica but I have verified and that connection exists directly to battery negative terminal. The ground is.tied properly.

The relay coil needs a kickback diode.


Be careful,

= is not the same as ==

Please give me some time to check, I might have uploaded the old code here, I am sure I have rectified these errors as I got code reviewed by chatgpt and it pointed out same issues. But kick back diode is not in Circuit as I am using a relay module not the direct component, it has the required kickback diode.

Who drew up your schematic ?

I guess it was my mistake, the code is not updated with equality operators, it got rolled back while undoing some other code. I will update and let you know. Thanks for the help, but let me try and get back to you with the results.
I drew the schematic using free online tool, sorry I am not from an electronics background but I am learning.

Ok fan doesn't have a diode I will fix that. Thanks.

Here is the schematic drawn in a more standard fashion.

The DHT11 might need a pullup resistor.

3 Likes

You have set pin 7 as INPUT. With no connection to the pin it will be floating, which makes it very sensitive to any nearby voltage. If you want the input to be HIGH when the pushbutton is pressed, then you will need a pull-down resistor to ground. Alternatively, use the internal pullup to +5v, and wire the switch to ground, so that the input goes LOW when the pushbutton is pressed.

Thank you very much for the effort. Yes the DHT11 has the pullup between its data pin and the voltage pin. I have now included the diode for reverse current for fan as well. Can you please tell me why you have attached resistors with each mosfet? i.e. the 220R ? I don't have 10k resistors but I found 12k works fine so I put one across gain and source for each mosfet. Also I am using this - Relay Module (https://www.mantech.co.za/Images/products/555-12VDC-666-200502A.jpg) which I am assuming has the reverse protection diode. I see that you have changed the pin allocation a bit. Please advise if it is a required change or if my pin allocation is fine. I have referred code individually for each component from other sources and tried to put it together. I would happy to simulate the whole thing online but I don't know of any resources that could help. I have tried creating this using wokwi.com but there aren't required components. One thing I want you to know here is that when I start the system (using spst 6 amp switch) sometimes it starts and stops and sometimes it works for a longer duration.

Thanks for the information. Will do this and get back to you.

Can you point me resources where I can convert this to a clean pcb design, where I can simply mount the components and solder them. Right now I am using general purpose board which is messy and am afraid that I would short circuit, and that is why I am doing a continuity check for each connection wherever required.

Thanks very much I think that was the issue , I pulled the switch pins low it seems fine. However sometimes the whole systems shuts down and restarts which is undesirable due to day count and turner(). Also found some loose contacts couldn't actually pinpoint but when I wiggle the wires I find their presence. I wonder could it be the inductor present in the humidifier causing power issues. I am using this humidifier - https://robu.in/product/dc-5v-ultrasonic-humidifiers-power-circuit-board-with-atomizing-chip/. Or may be there something else that is causing the system restart.

I have now included the diode for reverse current for fan as well.
The diode may not be needed but having it won’t hurt.

Can you please tell me why you have attached resistors with each mosfet? i.e. the 220R ?
The 220R is used to limit the Arduino output current.

I don't have 10k resistors but I found 12k works fine so I put one across gain and source for each mosfet.
12k to 100k is fine.

Also I am using this - Relay Module (https://www.mantech.co.za/Images/products/555-12VDC-666-200502A.jpg) which I am assuming has the reverse protection diode.
Probalbly, we need to see a schematic of this board.

I see that you have changed the pin allocation a bit.
If I did, it was in error.

I have referred code individually for each component from other sources and tried to put it together. I would happy to simulate the whole thing online but I don't know of any resources that could help. I have tried creating this using wokwi.com but there aren't required components. One thing I want you to know here is that when I start the system (using spst 6 amp switch) sometimes it starts and stops and sometimes it works for a longer duration.
The SPST switch needs to be added to the schematic.

sometimes it starts and stops and sometimes it works for a longer duration.
Have not looked closely at your sketch; this might be as a result in floating inputs.

1 Like

After a point to point wired prototype board is made, a PCB program like EasyEDA can be used to design a board and then ordered from JLCPCB.COM

However, a one of a kind hand wired board should work fine for years.

2 Likes