Greetings !
I am using Arduino Uno to control a terrarium for my pet.
Parts:
-RTC module
-LCD
-DHT sensor
-Relay board 4-channel
Objectives:
-Day-night cicle where the lights are turned on/off
-Diferent temperature for day and night
-Hot side and cool side with different temperatures
-Fans turning on/off according to the humidity
Display:
Everything that is fixed display is printed on the setup.
Things that are variable are done in the loop. (Day/Night symbol, time and blinking “:”, temperature, humidity and status of the fans and relays)
Problem:
The program can run for days without a problem but then it freezes or gets random restarts. it also can happen after a few minutes only. Either the LCD turns all blank or the time stops and the LCD freezes displaying the last info.
I checked the ram and it was not increasing.
Tried 3 different power supplies powering the arduino via USB.
So i assume I have a blackhole in my code somewhere, it is a bit extense but easy to understand, i believe.
Thank you for your time !
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <dht.h>
#if defined(ARDUINO) && ARDUINO >= 100
#define printByte(args) write(args);
#else
#define printByte(args) print(args,BYTE);
#endif
#define RELAY1 9 //hot side relay
#define RELAY2 10 //cool side relay
#define RELAY3 11 //fan relay
#define RELAY4 12 //light relay
#define DHT11_HOT 5 //hot side sensor
#define DHT11_COOL 4 //cool side sensor
RTC_DS1307 RTC;
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
dht DHT;
bool hoton = false;
bool coolon = false;
bool fanon = false;
int chk = 0;
int tempHot = 0;
int humHot = 0;
int tempCool = 0;
int humCool = 0;
int checkTemp = 0;
int checkHum = 0;
int segAnt = -1;
byte termometru[8] = //icon for termometer
{
B00100,
B01010,
B01010,
B01110,
B01110,
B11111,
B11111,
B01110
};
byte picatura[8] = //icon for water droplet
{
B00100,
B00100,
B01010,
B01010,
B10001,
B10001,
B10001,
B01110,
};
byte night[8] = { //icon for moon
0b11100,
0b00110,
0b00011,
0b00011,
0b00011,
0b00011,
0b00110,
0b11100
};
byte dia[8] = { //icon for sun
0b00000,
0b00100,
0b10101,
0b01110,
0b11111,
0b01110,
0b10101,
0b00100
};
void setup()
{
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
digitalWrite(RELAY1, LOW);
digitalWrite(RELAY2, LOW);
digitalWrite(RELAY3, LOW);
digitalWrite(RELAY4, LOW);
lcd.begin (20, 4) ; // initialize the lcd
lcd.print("Initialising...");
lcd.createChar(1, termometru);
lcd.createChar(2, picatura);
lcd.createChar(3, night);
lcd.createChar(4, dia);
lcd.setBacklight(LOW);
lcd.clear();
Wire.begin();
RTC.begin();
//RTC.adjust(DateTime(__DATE__, __TIME__)); //sets the rtc time to the compilation time
//basic layout of the LCD
lcd.setCursor(1, 0); lcd.print(" Yoshi's Land ");
lcd.setCursor(0, 1); lcd.print(" "); lcd.write(1);
lcd.setCursor(2, 1); lcd.print(" ");
lcd.setCursor(13, 1); lcd.print(" ");
lcd.setCursor(18, 1); lcd.write(2); lcd.print(" ");
lcd.setCursor(0, 2); lcd.print("Hot :"); lcd.setCursor(7, 2); lcd.print((char)223); lcd.print("C ");
lcd.setCursor(0, 3); lcd.print("Cool:"); lcd.setCursor(7, 3); lcd.print((char)223); lcd.print("C ");
}
void loop()
{
DateTime now = RTC.now(); //get the time from the rtc
//DISPLAYING THE TIME
if (now.hour() < 10) { //using 24h format if hour<10 adds the 0 and prints the hour
lcd.setCursor(7, 1); lcd.print("0"); lcd.print(now.hour(), DEC);
};
if (now.hour() >= 10) {
lcd.setCursor(7, 1); lcd.print(now.hour(), DEC);
};
if (now.second() % 2 == 0)lcd.print(":");//blinking ":" 1 sec on/off
if (now.second() % 2 != 0)lcd.print(" ");
if (now.minute() < 10) { //if min<10 adds the 0 and prints the minutes
lcd.print("0");
};
lcd.print(now.minute(), DEC);
//READING SENSORS AND COMMAND RELAYS
if (now.hour() >= 14) { //at 14h the day cycle starts
lcd.setCursor(0, 0);
lcd.write(4);
lcd.setBacklight(HIGH);
if (now.second() % 2 == 0 && now.second() != segAnt) { //every 2 seconds, read the sensor
chk = DHT.read11(DHT11_HOT);
checkTemp = DHT.temperature;
if (checkTemp > 0 && checkTemp < 60) { //only temperature and humidity readings that make sense are processed
tempHot = checkTemp + 3;
}
checkHum = DHT.humidity;
if (checkHum > 0 && checkHum < 100) {
humHot = checkHum;
}
chk = DHT.read11(DHT11_COOL);
checkTemp = DHT.temperature;
if (checkTemp > 0 && checkTemp < 60) {
tempCool = checkTemp;
}
checkHum = DHT.humidity;
if (checkHum > 0 && checkHum < 100) {
humCool = checkHum - 23;
}
segAnt = now.second(); //saves the seconds so that it only reads one time in each second
}
//acting on the relays
if (tempHot < 30)
{
digitalWrite(RELAY1, LOW);
hoton = true;
}
if (tempHot > 30)
{
digitalWrite(RELAY1, HIGH);
hoton = false;
}
if (tempCool < 22)
{
digitalWrite(RELAY2, LOW);
coolon = true;
}
if (tempCool > 22)
{
digitalWrite(RELAY2, HIGH);
coolon = false;
}
if (humHot > 50 || humCool > 50)
{
digitalWrite(RELAY3, LOW);
fanon = true;
}
if (humHot < 50 && humCool < 50)
{
digitalWrite(RELAY3, HIGH);
fanon = false;
}
digitalWrite(RELAY4, LOW);
}
if (now.hour() < 14) { //at 00 the night cycle starts
lcd.setCursor(0, 0);
lcd.write(3);
lcd.setBacklight(LOW);
if (now.second() % 2 == 0 && now.second() != segAnt) {
chk = DHT.read11(DHT11_HOT);
checkTemp = DHT.temperature;
if (checkTemp > 0 && checkTemp < 60) {
tempHot = checkTemp + 3;
}
checkHum = DHT.humidity;
if (checkHum > 0 && checkHum < 100) {
humHot = checkHum;
}
chk = DHT.read11(DHT11_COOL);
checkTemp = DHT.temperature;
if (checkTemp > 0 && checkTemp < 60) {
tempCool = checkTemp;
}
checkHum = DHT.humidity;
if (checkHum > 0 && checkHum < 100) {
humCool = checkHum - 23;
}
segAnt = now.second();
}
if (tempHot < 16)
{
digitalWrite(RELAY1, LOW);
hoton = true;
}
if (tempHot > 16)
{
digitalWrite(RELAY1, HIGH);
hoton = false;
}
if (tempCool < 16)
{
digitalWrite(RELAY2, LOW);
coolon = true;
}
if (tempCool > 16)
{
digitalWrite(RELAY2, HIGH);
coolon = false;
}
digitalWrite(RELAY3, HIGH);
fanon = false;
digitalWrite(RELAY4, HIGH);
}
//TEMP, HUM AND OTHER INFO ON THE LCD
lcd.setCursor(5, 2); lcd.print(tempHot);
lcd.setCursor(10, 2);
if (hoton == true) {
lcd.print("[ON] ");
} else {
lcd.print("[OFF] ");
}
if (fanon == true) {
lcd.print("*");
} else {
lcd.print(" ");
}
lcd.print(humHot); lcd.print("%");
lcd.setCursor(5, 3); lcd.print(tempCool);
lcd.setCursor(10, 3);
if (coolon == true) {
lcd.print("[ON] ");
} else {
lcd.print("[OFF] ");
}
if (fanon == true) {
lcd.print("*");
} else {
lcd.print(" ");
}
lcd.print(humCool); lcd.print("%");
}