So my friend and I are trying to set up a temperature and humidity controller using Arduino Nano. I wrote the sketch for it using a youtuber's code and the insights gained from various Arduino forum posts, and I designed the circuitry to collect DHT11 sensor information, and turn on logic level MOSFETs to turn on an ultrasonic fogger control board, and a fan to distribute the humidity better. The Arduino Nano also outputs to a solid-state relay to turn on a couple heater cores normally used for 3d printers, mounted inside a large-ish heat sink with a fan to distribute heat. The heater cores and fan are all controlled by the SSR. The majority of the setup is powered by a 12v, 4A dc power supply, and the ultrasonic control board is powered by a 5v, 2A dc power supply. The grounds are all connected.
I have 220 ohm current limiting resistors on all output pins, and 10k ohm pull-down resistors on the 2 MOSFETs and the SSR, so I'm pretty sure I'm not drawing too much current from the output pins, though I haven't measured it yet.
Now that I've described my set up, my problem is that when I power it on, it will run as intended for a few seconds and then the Nano will restart. I have previously been able to run the project long enough to write the temperature and humidity set points into EEPROM, and it turns the controllers on when it starts so it knows what values it's shooting for before turning off, but it doesn't turn off the heater or humidity control once it reaches those either. I'm assuming that has to do with it resetting constantly though.
I'm enclosing a photo of my circuit schematic, and if I'm not mistaken on how to post my sketch code, that as well.
#include <ezButton.h>
#include <dht.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>
// DHT sensor initialize
#define dht_apin A0 // analog pin the sensor is connected to
dht DHT; // initialize DHT object
// initialize buttons with debounce functionality (mode button can't be EZ for interrupt purposes)
ezButton buttonUp(10); // initialize up button and set to input_pullup
ezButton buttonDn(9); // initialize down button and set to input_pullup
// initialize the lcd library with the numbers of the interface pins
LiquidCrystal lcd(A1,A2,4,5,6,7); // rs = A1, en = A2
// set up variables
float sensorTemp; // Temp value read from the sensor
float sensorHum; // Humidity value read from the sensor
float adjsensorTemp; // Temp value used for comparing made by turning the tsp int into a float
float adjsensorHum; // Humidity value used for comparing made by turning the hsp int into a float
int tsp,hsp,hst; // create global variables for temp & humidity setpoint and on/off state of fogger
volatile int m; // create volatile mode variable for use with interrupt
volatile bool modeChange; // create volatile variable to keep track of whether interrupt button has been pressed within each case
unsigned long lastDebounceTime; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
unsigned long startTime; // beginning of time tracking
unsigned long displayTime; // keep track of how long the display has shown a certain screen
unsigned long dhtDelay = 2000; // length of time DHT11 requires between sensor reads
// begin setup phase
void setup() {
Serial.begin(9600); // initialize serial communications at 9600 bps
lcd.begin(16, 2); // initialize lcd operations
delay(500); // delay to let system boot
// input pin set up
pinMode(2,INPUT_PULLUP); // mode button input pin setup
attachInterrupt(digitalPinToInterrupt(2), toggle, FALLING); // allow mode button to be pressed at any time during loop to change modes
buttonUp.setDebounceTime(50); // set up button debounce time
buttonDn.setDebounceTime(50); // set down button debounce time
// output pin set up
pinMode(11,OUTPUT); // heater control relay output pin
pinMode(12,OUTPUT); // humidifier fan control pin
pinMode(13,OUTPUT); // humidifier control output pin
digitalWrite(11,LOW); // default heater value to start with heater pin 'off'
digitalWrite(12,LOW); // default fogger fan value to start with fan pin 'off'
digitalWrite(13,LOW); // default fogger value to set up pin to be used as an 'activate upon going low, then high again' mode
// set default variable values
m = 0; // start up in normal operational mode
modeChange = false; // set default modeChange value to avoid excessive eeprom writes
tsp= 28; // set default values in case program acts wrong to prevent overheating chamber
hsp= 80; // set default values in case program acts wrong to prevent overhumidifying chamber
lastDebounceTime = 0; // set lastDebounceTime default value
startTime = 0; // set startTime default value
// print out splash screen and give the user a chance to read it
lcd.print("Temp & Humidity");
lcd.setCursor(0, 1);
lcd.print("Controller");
delay(2000); // delay to let user read splash screen and to wait long enough for if statement for initial reading of DHT sensor
} // end "Setup()"
// begin main loop
void loop() {
buttonUp.loop(); // must call this at beginning of loop for up button functionality
buttonDn.loop(); // must call this at beginning of loop for down button functionality
displayTime=millis();
//serial.print("current time: ");
//serial.print(displayTime);
//serial.print(" milliseconds since startTime updated.");
switch (m){
case 0: // regular operational mode -- display and control temp&humidity
//display current values every second
if(displayTime - startTime < 1000 && displayTime % 500 == 0){
//serial.print("current sensor measurement display expected");
lcd.clear();
lcd.print("Temp:");
lcd.print(sensorTemp);
lcd.print("C");
lcd.setCursor(0,1); // sets cursor at bottom left
lcd.print("Hum:");
lcd.print(sensorHum);
lcd.print("%");
}
// wait until screen has shown for a second, clear it and show setpoints for a second
if(displayTime - startTime >= 1000 && displayTime % 500 == 0){
//serial.print("setpoint display expected");
tsp=EEPROM.read(0); // read temperature setpoint stored in EEPROM
hsp=EEPROM.read(1); // read humidity setpoint stored in EEPROM
adjsensorTemp=float(tsp); // make tsp a float for comparing number in EEPROM with value from sensor
adjsensorHum=float(hsp); // make hsp a float for comparing number in EEPROM with value from sensor
lcd.clear(); // erases screen and resets position to top left
lcd.print("TSP:");
lcd.print(tsp);
lcd.print("C");
lcd.setCursor(0,1); // sets cursor at bottom left
lcd.print("HSP:");
lcd.print(hsp);
lcd.print("%");
}
// read DHT sensor and prepare values for comparison
if(displayTime - startTime >= dhtDelay){ // only allow DHT11 sensor to read once every 2 seconds
//serial.print("DHT11 read and startTime update expected");
DHT.read11(dht_apin); // read the analog in value - can only be read every 2 seconds or so
sensorTemp=DHT.temperature; // get sensor temp
sensorHum=DHT.humidity; // get sensor humidity
startTime=displayTime; // reset displayTime to current time
}
// low temp only
if(sensorTemp<(adjsensorTemp-1)&&sensorHum>(adjsensorHum+1)){
//serial.print("low temp only");
digitalWrite(11,HIGH); // turn on heater
}
// low humidity only
if(sensorTemp>(adjsensorTemp+1)&&sensorHum<(adjsensorHum-1)){
//serial.print("low humidity only");
if(hst==0){
//serial.print("humidifier on");
digitalWrite(12,HIGH); // turn on fan
digitalWrite(13,HIGH); // turn on humidifier
delay(50); // delay for ultrasonic control pin to act like button push
digitalWrite(13,LOW);
hst = 1;
}
}
// both variables low
if(sensorTemp<(adjsensorTemp-1)&&sensorHum<(adjsensorHum-1)){
//serial.print("both variables low");
digitalWrite(11,HIGH); // turn on heater
if(hst==0){
//serial.print("humidifier on");
digitalWrite(12,HIGH); // turn on fan
digitalWrite(13,HIGH); // turn on humidifier
delay(50);
digitalWrite(13,LOW);
hst = 1;
}
}
// neither variable low
if(sensorTemp>(adjsensorTemp+1)&&sensorHum>(adjsensorHum+1)) {
digitalWrite(11,LOW); // turn off heater
if(hst==1){ // verify humidifier is on before changing
digitalWrite(12,LOW); // turn off fan
digitalWrite(13,HIGH); // turn off humidifier
delay(50);
digitalWrite(13,LOW);
hst = 0;
}
}
if(modeChange==true){
modeChange=false; // reset modeChange so the program doesn't write to eeprom excessively
}
break; // used to return to beginning of loop without moving through rest of cases
// Temp setpoint change menu
case 1:
// temp setpoint up
if(buttonUp.getState()==0){
tsp++; // increase temp setpoint
if(displayTime - startTime >= 100){ // prevent the screen from clearing so fast it's not readable
lcd.clear();
lcd.print("Set Temp Limit:");
lcd.setCursor(0, 1);
lcd.print(tsp);
lcd.print(" C");
startTime = displayTime;
}
}
// temp setpoint down
if(buttonDn.getState()==0){
tsp--; // decrease temp setpoint
if(displayTime - startTime >= 100){ // prevent the screen from clearing so fast it's not readable
lcd.clear();
lcd.print("Set Temp Limit:");
lcd.setCursor(0, 1);
lcd.print(tsp);
lcd.print(" C");
startTime = displayTime;
}
}
// temp limiters
if(tsp<0){tsp=0;}
if(tsp>50){tsp=50;}
// save values in eeprom
if(modeChange==true){
EEPROM.write(0, tsp); // write new temp setpoint to eeprom register
modeChange = false; // reset modeChange state to avoid excessive eeprom writes
}
break; // used to return to beginning of loop without moving through rest of cases
// Humidity setpoint change menu
case 2:
// humidity setpoint up
if(buttonUp.getState()==0){
hsp++; // increase humidity setpoint
if(displayTime - startTime >= 100){
lcd.clear();
lcd.print("Set Hum Limit:");
lcd.setCursor(0, 1);
lcd.print(hsp);
lcd.print("%");
startTime = displayTime;
}
}
// humidity setpoint down
if(buttonDn.getState()==0){
hsp--; // decrease humidity setpoint
if(displayTime - startTime >= 100){
lcd.clear();
lcd.print("Set Hum Limit:");
lcd.setCursor(0, 1);
lcd.print(hsp);
lcd.print("%");
delay(1000);
startTime = displayTime;
}
}
// humidity limiters
if(hsp<20){hsp=20;}
if(hsp>90){hsp=90;}
// save values in eeprom
if(modeChange==true){
EEPROM.write(1, hsp); // write new humidity setpoint to eeprom register
modeChange=false; // reset modeChange state to avoid excessive eeprom writes
}
break;
}
}
// interrupt service routine 'toggle'
void toggle(){
unsigned long interruptTime = millis(); // create local variable to compare current time with last debounce time
if(interruptTime - lastDebounceTime > debounceDelay){
m++; // change mode case
modeChange = true; // change modeChange to true so EEPROM can write new setpoint values after changing from one mode to another
if(m>2){ // reset mode to normal operation after moving through temp & humidity setpoint change menus
m=0;
}
lastDebounceTime = interruptTime; // update last debounce time variable with new value
}
}
If anyone can help me figure out why this Arduino keeps resetting, I would be so grateful!