Hi guys. Having a problem with my circuitry and or power supply.
Im controlling a commercial cooler. The thermostat went out, so I thought I would make one with Arduino. Im fairly new to this stuff, this is my largest and most complex project so far.
Specifically controlling the compressor/condenser fan and inside evaporator fan based on temperature. Plus, interior lights, and have an alarm relay output in case of a freeze condition, compressor failure, or arduino goes down.
Components-
Uno R3
5V 3A power supply (x2) https://www.amazon.com/dp/B005T6UJBU?psc=1&ref=ppx_yo2ov_dt_b_product_details
4 position 5V relay board rated for 30A https://www.amazon.com/dp/B07BLKV64Y?ref=ppx_yo2ov_dt_b_product_details&th=1
temp sensor
5V motion
2004 LCD +I2C
When I started this, I had the project put together on my desk while writing the code to work out bugs. Ive gotten the bugs worked out of the code. It ran on my desk for days without issue. But, instead of the relay board I had LEDs to indicate what is in what state. It was also running only from USB power.
Fast forward to installing it in the cooler. Found the relay board takes quite a bit of power to power all 4 relays(about 200mA per relay). Was originally powering with a 12v 1A transformer into the DC socket. It was recomended that I not do that, so I installed a 5V power supply for the entire project, powering the arduino through the 5V pin, It works like this, until at some point it crashes when any relay turns off or on.
I then added a second 5V power supply, one for the relay board, and the other for the Arduino, temp sensor, motion, and LCD, powering the Arduino through the 5V pin still. It works for a little longer like this, but eventually, things will crash at some point when a relay is turned off or on, either right away, 10 minutes, 1 hour, at some point. By crash, I mean the LCD will display jibberish, the code will stop looping, or both.
I also want to note that there is about 4 feet of cable 4/22awg cable between the arduino and LCD. The arduino and relays are in the cooler in the cold, the LCD on the outside.
I attached the code and a circuit schematic of how things are wired right now.
Again, I'm a beginner. The code works just fine. Not sure what is wrong to crash it.
Questions-
-In the schematic you will notice I have an output attached to an input, in two different places(4&5. 6&7) This is the only way I could think to do since you can't digitalRead an output pin. This is okay, correct?
-I do not have any resistors on the I2C, I read this is a thing just before this. Will this help?

//INPUT PINS
int tempsensor = 11; // Interior temp Sensor
int fanState = 7; // State of Evaporator fan, used for on/off timing.
int compState = 5; // State of Compressor, used for evap fan delay.
int SPdn = 2; // Setpoint down
int SPup = 3; // Setpoint up
int motion = 10; // Motion detector for light
//OUTPUT PINS
int evapFan = 6; // Evaporator fan relay
int compressor = 4; // Compressor relay
int light = 8; // Light relay
int alarm = 9; // Alarm relay
int heartbeat = 13; // Status blink
//INTEGERS
int temp;
int tempLOW = 35; // Low setpoint
int tempHIGH = 38; // High setpoint
int OFFcountdownMIN = 4; // "Fan OFF for" countdown
int OFFcountdownSEC = 59; // "Fan OFF for" countdown
int ONcountdownMIN = 1; // "Fan ON for" countdown
int ONcountdownSEC = 59; // "Fan ON for" countdown
int compRunMIN = 0; // Compressor Runtime
int compRunSEC = 0; // Compressor Runtime
int fanDelay = 0; // fan delay on compressor start
int lighttimer; // light on for 10 minutes(600)
int freeze = 32; // freeze alarm
// Shortcuts
#define ON HIGH
#define OFF LOW
//LIBRARYS
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <DallasTemperature.h>
OneWire oneWire (tempsensor);
DallasTemperature sensors(&oneWire);
//LCD Setup
char array1[] = "SETPOINT - F";
char array2[] = "TEMPERATURE F";
char array3[] = "FAN : ";
char array4[] = "COMP : ";
LiquidCrystal_I2C lcd(0x27, 20, 4);
// A
//
//------------------------------------------------------------------------------------
void setup() {
pinMode(evapFan, OUTPUT);
pinMode(compressor, OUTPUT);
pinMode(light, OUTPUT);
pinMode(alarm, OUTPUT);
pinMode(tempsensor, INPUT);
pinMode(compState, INPUT);
pinMode(fanState, INPUT);
pinMode(SPdn, INPUT);
pinMode(SPup, INPUT);
pinMode(motion, INPUT);
pinMode(13, OUTPUT); //Yellow LED on board.
digitalWrite(evapFan, OFF);
digitalWrite(compressor, OFF);
digitalWrite(light, OFF);
digitalWrite(alarm, HIGH); // Normal= Relay on, wired NC to 5816
digitalWrite(compState, INPUT_PULLUP);
digitalWrite(fanState, INPUT_PULLUP);
digitalWrite(SPdn, INPUT_PULLUP);
digitalWrite(SPup, INPUT_PULLUP);
digitalWrite(motion, INPUT_PULLUP);
digitalWrite(13, LOW);
lcd.init();
lcd.backlight();
lcd.clear();
lcd.print(array1);
lcd.setCursor(0, 1);
lcd.print(array2);
lcd.setCursor(0, 2);
lcd.print(array3);
lcd.setCursor(0, 3);
lcd.print(array4);
sensors.begin();
Serial.begin(9600);
}
//------------------------------------------------------------------------------------
void loop(void) {
digitalWrite(heartbeat, ON);
delay(200);
digitalWrite(heartbeat, OFF);
delay(200);
// SETPOINT BUTTONS------------------------------------------------------------------
if (digitalRead(SPdn) == LOW) { // setpoint down button
tempLOW = tempLOW - 1;
tempHIGH = tempHIGH - 1;
}
if (digitalRead(SPup) == LOW) { // setpoint up button
tempLOW = tempLOW + 1;
tempHIGH = tempHIGH + 1;
}
// INTERIOR LIGHT--------------------------------------------------------------------
if (digitalRead(motion) == LOW) { // light timer start at 10 minutes (600)
lighttimer = 0;
}
lighttimer++;
if (lighttimer <= 600) { // light on, off after 10 minutes no motion
digitalWrite(light, ON);
} else {
digitalWrite(light, OFF);
}
//TEMP DISPLAY------------------------------------------------------------------------
lcd.setCursor(13, 0);
lcd.print(tempLOW); //low setpoint
lcd.setCursor(16, 0);
lcd.print(tempHIGH); //high setpoint
sensors.requestTemperatures();
lcd.setCursor(13, 1);
lcd.print((sensors.getTempCByIndex(0) * 9.0) / 5.0 + 32.0);//temperature in F
// Temp Control-----------------------------------------------------------------------
temp = ((sensors.getTempCByIndex(0) * 9.0) / 5.0 + 32.0); // read temp
if (temp > tempHIGH) { // Temperature HIGH Setpoint, turn compressor on
digitalWrite(compressor, ON);
}
if (temp < tempLOW) { // Temperature LOW Setpoint, turn compressor off
digitalWrite(compressor, OFF);
}
if (temp < freeze) { // Freeze alert
digitalWrite(compressor, OFF);
digitalWrite(evapFan, ON);
digitalWrite(alarm, LOW);
lcd.setCursor(13,1);
lcd.print(" FREEZE");
lcd.setCursor(4,2);
lcd.print(" ON ");
lcd.setCursor(5,3);
lcd.print("DISABLED ");
delay(60000);
}
// Compressor ON----------------------------------------------------------------------
// Compressor ON
if (digitalRead(compState) == ON) {
lcd.setCursor(5, 3);
lcd.print("ON for : "); //comp on
lcd.setCursor(13, 3); //compressor minutes
lcd.print(compRunMIN);
lcd.setCursor(16, 3); //compressor seconds
lcd.print(compRunSEC);
fanDelay++;
compRunSEC = compRunSEC + 1;
if (compRunSEC == 60) { // compressor seconds counter
compRunSEC = 00;
compRunMIN = compRunMIN + 1;
}
// Evap fan ON after compressor is on for 20 seconds
if (fanDelay > 20) { //compressor less than 20 sec
digitalWrite(evapFan, ON);
lcd.setCursor(5, 2); //fan
lcd.print("ON ");
}
else{ //compressor more than 20 sec
digitalWrite(evapFan, OFF);
lcd.setCursor(5, 2);
lcd.print("DELAY ");
}
}
// Compressor OFF--------------------------------------------------------------------
else {
//evap fan run for 2 minutes after compressor off
lcd.setCursor(5, 3);
lcd.print("OFF ("); //compressor OFF
lcd.setCursor(18, 3);
lcd.print(")"); //History time
compRunMIN = 0; //runtime reset
compRunSEC = 0; //runtime reset
fanDelay = 0; //fan delay reset
//evaporator fan ON interval-------------------------------------------------------
if (digitalRead(fanState) == ON){
OFFcountdownMIN = 4; //OFFcountdown reset
OFFcountdownSEC = 59; //OFFcountdown reset
lcd.setCursor(5, 2);
lcd.print("ON for : "); //fan low for
lcd.setCursor(13, 2); //fan minutes
lcd.print(ONcountdownMIN);
lcd.setCursor(16, 2); //fan seconds
lcd.print(ONcountdownSEC);
ONcountdownSEC = ONcountdownSEC - 1;
if (ONcountdownSEC == -1) { // on seconds counter
ONcountdownSEC = 59;
ONcountdownMIN = ONcountdownMIN - 1;
}
if (ONcountdownMIN == -1){ //fan off at 0:0
digitalWrite(evapFan, OFF);
}
}
//evaporator fan OFF interval-------------------------------------------------------
else {
ONcountdownMIN = 1; //ONcountdown reset
ONcountdownSEC = 59; //ONcountdown reset
lcd.setCursor(5, 2);
lcd.print("OFF for : ");
lcd.setCursor(13, 2); //fan minutes
lcd.print(OFFcountdownMIN);
lcd.setCursor(16, 2); //fan seconds
lcd.print(OFFcountdownSEC);
OFFcountdownSEC = OFFcountdownSEC - 1;
if (OFFcountdownSEC == -1) { // on seconds counter
OFFcountdownSEC = 59;
OFFcountdownMIN = OFFcountdownMIN - 1;
}
if (OFFcountdownMIN == -1){ //fan on at 0:0
digitalWrite(evapFan, ON);
}
}
}
}