Hello,
I'm working on an Arduino code to control basic gardening functions ( just lighting, watering, and heating for now) and I've run into a bit of a problem. For some background on the setup I have a DS1307 realtime clock module that I'm using to keep time as well as an AM2302 digital humidity and temperature sensor module that I'm using to measure ambient conditions. Because of this, the beginning of the program consists of sections of example code for each sensor which were provided with the libraries. All of that seems to be working nicely as I'm getting accurate time and temp/humidity data back over serial. The problem that I'm experiencing is during or after my logic loop.
The idea is to set boolean variables for light, water, and heat based on the time of day and current ambient conditions in the garden. I accomplish this using nested "if" statements. The booleans seem to be updating correctly within the logic loop, as I have added some serial prints within the logic loop itself to aid in debugging. However, when I attempt to print boolean values after my logic loop and then switch relays based on them all of my booleans unfailingly return "false" values. This happens even when the print statements within the logic loop itself indicate the booleans should be "true". I don't think I'm overwriting the values anywhere else in my code so I'm a bit mystified as to why they all return false after the logic loop. Here's hoping that the Arduino community will be able to point out my inevitably stupid mistake. The code is attached below. It's fairly well commented which should help in figuring out what I'm doing in each section. The logic loop where I adjust my booleans starts at line 149.
Thanks so much,
doc
#include <DS1307RTC.h>
#include <Time.h>
#include <Wire.h>
#include "DHT.h"
//~~~~~TEMP & HUMIDITY~~~~~~~~~
#define DHTPIN 2 // what pin we're connected to
#define LIGHTPIN 11
#define WATERPIN 10
#define HEATPIN 9
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);
const int thdelay = 240; // AM2303 takes 250 ms to read temp or humidity
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
const int delaytime = 500; // delay of 5 sec between readings
boolean lightson;// = false;
boolean wateron;// = false;
boolean heaton;// = false;
boolean dan;
int daytemp = 78;
int nighttemp = 74;
//~~~~~~~CLOCK~~~~~~~~~
const char *monthName[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
tmElements_t tm;
void setup() {
// // getting initial clock readings from computer at time of compilation
// bool parse=false;
// bool config=false;
//
// // get the date and time the compiler was run
// if (getDate(__DATE__) && getTime(__TIME__)) {
// parse = true;
// // and configure the RTC with this info
// if (RTC.write(tm)) {
// config = true;
// }
// }
//
Serial.begin(9600);
while (!Serial) ; // wait for Arduino Serial Monitor
delay(200);
// if (parse && config) {
// Serial.print("DS1307 configured Time=");
// Serial.print(__TIME__);
// Serial.print(", Date=");
// Serial.println(__DATE__);
// } else if (parse) {
// Serial.println("DS1307 Communication Error :-{");
// Serial.println("Please check your circuitry");
// } else {
// Serial.print("Could not parse info from the compiler, Time=\"");
// Serial.print(__TIME__);
// Serial.print("\", Date=\"");
// Serial.print(__DATE__);
// Serial.println("\"");
// }
Serial.print("\n");
Serial.println("Begin Control System");
Serial.println("-------------------");
pinMode(WATERPIN,OUTPUT);
pinMode(LIGHTPIN,OUTPUT);
pinMode(HEATPIN,OUTPUT);
pinMode(8,OUTPUT);
digitalWrite(WATERPIN, HIGH); // set to high initially
digitalWrite(LIGHTPIN, HIGH); // because high value
digitalWrite(HEATPIN, HIGH); // opens relay
dht.begin();
}
void loop() {
tmElements_t tm;
float h = dht.readHumidity(); // read humidity
float t = dht.readTemperature(); // read temperature
float t_f = t*(1.8)+32; // convert degrees c to degrees f
if (RTC.read(tm)) {
// Serial.print("Time = ");
print2digits(tm.Hour);
Serial.write(':');
print2digits(tm.Minute);
Serial.write(':');
print2digits(tm.Second);
// Serial.print(", Date (D/M/Y) = ");
Serial.print("\t\t");
Serial.print(tm.Day);
Serial.write('/');
Serial.print(tm.Month);
Serial.write('/');
Serial.print(tmYearToCalendar(tm.Year));
Serial.println();
} else { // loop activates if clock can't be read
if (RTC.chipPresent()) {
Serial.println("The DS1307 is stopped. Please run the SetTime");
Serial.println("example to initialize the time and begin running.");
Serial.println();
} else {
Serial.println("DS1307 read error! Please check the circuitry.");
Serial.println();
}
delay(9000);
}
if (isnan(t) || isnan(h)) {
Serial.println("Failed to read from DHT");
} else {
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t_f);
Serial.println(" *F");
}
// counting seconds on pin 11, alternating some sort of output to verify functioning clock
int remainder = tm.Second % 2;
if (remainder == 0){
digitalWrite(8,LOW);
}
else{
digitalWrite(8,LOW);
}
/* Logic Loop starts here. First we check time to decide what should be on.
During the day (6AM to midnight) the lights should be on.
In the morning (6:00A - 6:02A) the water is turned on.
If the temp drops below 'daytemp' the heater is turned on.
At night (midnight to 6AM) the lights are turned off.
No water loop is present in this lights loop, so if lights are off water is off.
If the temp drops below 'nighttemp' the heater is turned on.
All bools are FALSE until changed.
*/
if(tm.Hour >=6 && tm.Hour <=24){ // lights on between 6 AM and midnight
boolean lightson = true;
Serial.print("\nLights in loop: "); // just some debugging to see if values are adjusted
Serial.print(lightson); // correctly within the loop itself
if(tm.Hour == 6 && tm.Minute <= 2){ // water from 6 AM to 6:01 AM
boolean wateron = true;
}
else{
boolean wateron = false;
}
if(t_f <= daytemp){
boolean heaton = true;
Serial.print("\nHeat in loop: "); // just some debugging to see if values are adjusted
Serial.print(heaton); // correctly within the loop itself
}
else{
boolean heaton = false;
Serial.print("\nHeat in loop: "); // just some debugging to see if values are adjusted
Serial.print(heaton); // correctly within the loop itself
}
}
// else{
// boolean lightson = false;
// if(t_f <= nighttemp){
// boolean heaton = true;
// }
// else {
// boolean heaton = false;
// }
// }
/*
print the values of the variables for lights, heat and water. this section is reporting
false values for booleans where the logic loop above returns true values. i'm not sure why...
*/
Serial.print("\nLights:\t");
Serial.print(lightson);
Serial.print("\nWater:\t");
Serial.print(wateron);
Serial.print("\nHeat:\t");
Serial.print(heaton);
Serial.print("\n");
Serial.print("--------------------------------------------------");
Serial.print("\n");
/*
this section of "if"s handles changing the output to the
relays based on the boolean variables for lights, water, and heat
*/
if (lightson){
digitalWrite(LIGHTPIN, LOW);
}
else{
digitalWrite(LIGHTPIN, HIGH);
}
if(wateron){
digitalWrite(WATERPIN, LOW);
}
else{
digitalWrite(WATERPIN, HIGH);
}
if(heaton){
digitalWrite(HEATPIN, LOW);
}
else{
digitalWrite(HEATPIN, HIGH);
}
delay(2*thdelay);
delay(delaytime);
}
void print2digits(int number) {
if (number >= 0 && number < 10) {
Serial.write('0');
}
Serial.print(number);
}