Plant Tending Project

Hello All! Thanks for reviewing this project. First time posting though I have been digging through the posts for answers. My head is sore from scratching. I am new to programming. It is tedious and I have made a lot of mistakes. I really would appreciate some help getting these relays operate correctly. Please let me know if I have left out any pertinent information.

Board: ELEGOO Uno R3

The project uses (2) DS18B20 sensors to measure soil temperature and the temperature of water in a sump. When the soil temperature falls below a certain temperature a relay is supposed to activate a circulation motor/pump to warm the plant roots. The second DS18B20 sensor monitors the temperature of water in the sump to keep it warm enough to warm the plant roots. When the water temp falls below a certain temperature a relay should activate a 12V dc heater.

The project also utilizes a soil resistivity probe to measure the water content of the soil. When the soil dries out the probe should activate a relay to irrigate the plant.

This project also utilizes a DS3231 real time clock to activate 12V leds in the optimum spectrum for plant growth. The program should cycle a relay to turn on and off the plant light at a time that can be set using Arduino software. I have not been able to get the RTC to cycle the relay correctly.

No LCD, no push buttons. A computer interface will be used to set all parameters.

This is the wiring schematic used. If the relay output pins do not correctly correspond please disregard that part of the diagram.

In order to better manage my errors I have divided the code into two parts as shown below. The temp sensors are reading and displaying temperature. The RTC shows the correct time. I think most of my errors may be in the if loop sequences.

Regarding the DS18B20 and Relays code I think maybe I left something important out required to use the alarms. I also suspect that referencing sensor1, sensor2 in the loops may be problematic.
Code:

// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2 // Data wire is connected to GPIO2
const int relayPin1 = 8; //Coordinates relay inputs to Arduino outputs
const int relayPin2 = 9; //Coordinates relay inputs to Arduino outputs
const int relayPin3 = 10; //Coordinates relay inputs to Arduino outputs
const int relayPin4 = 11; //Coordinates relay inputs to Arduino outputs
// Setup a oneWire instance to communicate with a OneWire device
OneWire oneWire(ONE_WIRE_BUS);
// Pass oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);
//DeviceAddress Temp1, Temp2;
uint8_t sensor1[8] = { 0x28, 0x3E, 0x80, 0xC1, 0x17, 0x20, 0x06, 0xB1 };
uint8_t sensor2[8] = { 0x28, 0x77, 0x92, 0xB5, 0x17, 0x20, 0x06, 0x0B };

void setup(void){
  pinMode(relayPin1, OUTPUT);
  //pinMode(relayPin2, OUTPUT);
  pinMode(relayPin3, OUTPUT);
  //pinMode(relayPin4, OUTPUT);
  Serial.println("Setting alarm temps...");
  // alarm when temp is lower than 22C
  sensors.setLowAlarmTemp(sensor1, 22);
  // alarn when temp is lower than 26C
  sensors.setLowAlarmTemp(sensor2, 26);
    // attach alarm handler

  Serial.begin(9600);
  sensors.begin();
}

void loop(void){ 
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println("DONE");
   
  Serial.print(" Sensor 1(*F): ");
  Serial.println(sensors.getTempF(sensor1)); 
  
  Serial.print(" Sensor 2(*F): ");
  Serial.println(sensors.getTempF(sensor2)); 
  
  delay(2000);
  //Temp1A = sensors.getLowAlarmTemp(sensor1);
 // Temp2A = sensors.getLowAlarmTemp(sensor2);
  //checkAlarm(Temp1);
  if (sensors.hasAlarm(sensor1))
  {
    digitalWrite(relayPin1, HIGH);
    Serial.print("Soil radiator is On");
  }
 // checkAlarm(Temp2);
 // checkAlarm(Temp2);
  if (sensors.hasAlarm(sensor2))
  {
    digitalWrite(relayPin3, HIGH);
    Serial.print("Sump Heater is On");
  }
}

Regarding the DS3231 RTC and Soil Hygrometer & Relay code, I suspect that the time period specified in the if loop may be the problem. I’m not really sure what is wrong with the soil resistivity code.
Code:

/********************************
  name: 5V relay module, DHT 11 humidity and temperature sensor module, DS18B20 temperature module
  function: This program shows how the DHT 11 temperature and humidity sensor and the DS18B20 temperature sensor turns on
  devices or power sockets connected to a 5V relay module
********************************/
// First we include the libraries
#include <OneWire.h> 
#include <DallasTemperature.h>
#include <Wire.h>
#include "RTClib.h" //RTClib by Adafruit Version 1.12.5

#define ONE_WIRE_BUS 2 // Data wire is plugged into pin 2 on the Arduino DS18B20

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
const int relayPin1 = 8; //Coordinates relay inputs to Arduino outputs
const int relayPin2 = 9; //Coordinates relay inputs to Arduino outputs
const int relayPin3 = 10; //Coordinates relay inputs to Arduino outputs
const int relayPin4 = 11; //Coordinates relay inputs to Arduino outputs
int Hygrometer = A1;
int thresholdValue = 600;// you can adjust the wetness of the soil by changing the threshold value
uint8_t sensor1[8] = { 0x28, 0x3E, 0x80, 0xC1, 0x17, 0x20, 0x06, 0xB1 };
uint8_t sensor2[8] = { 0x28, 0x77, 0x92, 0xB5, 0x17, 0x20, 0x06, 0x0B };


OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices -DS18B20
DallasTemperature sensors(&oneWire);// Pass our oneWire reference to Dallas Temperature.
RTC_DS3231 rtc; //Initialize RTC module

void setup(){
  Serial.begin(9600);
  pinMode(relayPin1, OUTPUT);
  pinMode(relayPin2, OUTPUT);
  pinMode(relayPin3, OUTPUT);
  pinMode(relayPin4, OUTPUT);
  pinMode(Hygrometer, INPUT);
  digitalWrite(relayPin2, LOW);
 //Serial.println("Dallas Temperature IC Control Library Demo"); 
 // Start up the library
delay(3000);//Wait 3 seconds before accessing Sensor 
sensors.begin();
delay(1000);
Wire.begin();
delay(1000);
if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
	
	// Comment out below lines once you set the date & time.
    // Following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
	
    // Following line sets the RTC with an explicit date & time
    // for example to set January 27 2017 at 12:56 you would call:
    // rtc.adjust(DateTime(2017, 1, 27, 12, 56, 0));
  }
  }
  
void loop()
{
   DateTime now = rtc.now();
    
    Serial.println("Current Date & Time: ");
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    Serial.println();
    delay(1000);
    
 if (now.hour() > 19 && now.hour() < 7) { //Turns the grow light off between 7PM and 7AM
    digitalWrite (relayPin4, LOW);
    Serial.println("Grow Light Off");
} 
else {
  digitalWrite (relayPin4, HIGH);
Serial.print("Grow Light On");
}


int sensorValue = analogRead(Hygrometer);// read the soil conductivity on analog pin A1:
  Serial.print(sensorValue);
  if(sensorValue < thresholdValue){
    Serial.println(" - Doesn't need watering");
    digitalWrite(relayPin2, LOW);
  }
  else {
    Serial.println(" - Time to water your plant");
    digitalWrite(relayPin2, HIGH);
  }
  delay(500);
 }

Thanks again for taking a look. Any help is appreciated.

At what point in your program development did you discover the relays were not operating correctly? How should they be operating? Have you been Serial.print() the condition values?
Paul

Thanks Paul,

I had one relay working with a single ds18b20 sensor but had to modify the code when I added another ds18b20 sensor. Nixed a DHT11 sensor for the soil resistivity at the same time. The relays have leds and click when activated so I was using that for verification and testing with hot and cold water. I may not know enough to answer your question. I tried a lot of code and struggled with it.

At 1st glance, motors need kickback diodes.

The Arduino looks like it might be powering too much load from the 5v pin.

The relay board relays should be powered from an external supply.


In the Arduino IDE, use Ctrl T or CMD T to format your code then copy the complete sketch.

Larry,

Thanks for the response. The RTC, two DS18B20 sensors, Relay input VCC, and moisture conductivity sensor are the only things powered by the Arduino. The right side of the bread board is 12v and completely isolated from the Arduino. It is The DC motors may need diodes, but they are all on a separate circuit from the controller and function fine.

I do have the code separated for now so the overall system voltage should not be the issue. I believe the programing is the problem. I’m not sure that my code speaks the library language.

Have not looked at the code yet.


You have the GND on the relay board connected to the Arduino GND, this is not needed.

You do not show how the relay board relays get powered.


The motor coils need a kickback diode to stop inductive noise from getting to the Arduino.


But, sounds like you know better, I’ll leave this to others.

I really don’t know much about it, but I try. I didn’t mean to sound rude. Tone is often hard to deduce from text. I do appreciate your time and effort. The figure helps me to understand what you meant. External supply of 5v and ground to the pins as recommended was completed with some difficulty. No change in status resulted. The relays are all still powered HIGH when I think they should be LOW. No motors are connected. Thanks again.

Update:
It appears that the problem with the light timer code was the boolean operator &&. When replaced with the operator “logical or” it allows for the light to be on when either condition is met rather than when both conditions are met. It worked with my test relay, but not with the 4 channel relay 1100 miles away.

if (now.hour() <= 7 || now.hour() >= 19) { //Turns the grow light off between 7PM and 7AM (code in military time)
  digitalWrite (relayPin4, LOW);
  Serial.println("Grow Light Off Between 7PM & 7AM");
} 
else {
digitalWrite (relayPin4, HIGH);
Serial.print("Grow Light On Between 7AM & 7PM");

For some reason the soil resistivity sensor works exactly backwards to my understanding. When the sensorValue is below threshold value (600) that is when the soil is hydrated. I reversed the operator and HIGH/LOW settings (as listed below) to get the resistivity sensor to operate the relay “correctly”. It is blowing my mind.

int sensorValue = analogRead(Hygrometer);// read the soil conductivity on analog pin A2:
  Serial.println();
  Serial.println("Soil Moisture Reading:");
  Serial.print(sensorValue);
  if(sensorValue > thresholdValue){
  Serial.println("  Irrigation System On");
  digitalWrite(relayPin2, LOW);
  }
  else {
  Serial.println("  Irrigation System Off");
  digitalWrite(relayPin2, HIGH);
  }

Just to be clear, you do know that these relay boards are LOW true ?

i.e. digitalWrite (relayPin4, LOW); this energizes/picks the relay on the PCB.


if (now.hour() >=7 && now.hour() <= 19) { //Turns the grow light off between 7PM and 7AM (code in military time)
  digitalWrite (relayPin4, HIGH); // HIGH drops/de-energizes the relay
  Serial.println("Grow Light Off Between 7PM & 7AM");
} 
else {
digitalWrite (relayPin4, LOW);  //LOW energizes the relay
Serial.print("Grow Light On Between 7AM & 7PM");

Well, that would explain a lot of my confusion. If I had it in front of me I probably could have figured it out sooner. Gah. Trying to help with the project from far away.

Is the image in post #6 your relay board ?

This is a similar relay PCB, 8 channel relay board, showing the input for the 1st relay.

As you can see, the optoisolator LED will turn on when a LOW is placed on IN1.

When opto LED is ON this turns the opto transistor ON, turning Q1 ON, therefore picking/energizing the relay.

It’s this one. https://www.amazon.com/gp/product/B01HEQF5HU/ref=ppx_yo_dt_b_asin_title_o04_s00?ie=UTF8&psc=1

looks like the same relay PCB.

Thanks, this may be enough to get me going. I’m still trying to focus and get the “other end” of the project working.

I modified and compiled all of the code together. It seems to be working for me but I only have a clock and (HIGH) relay on my end, thus the wonky values in the screenshot. I will get it tested when my project manager gets off work. Please take a look and see if there are any potential problems.

/********************************
  name: 5V relay module, DS18B20 temperature module
  function: This program shows how DS18B20 temperature sensors turns on
  devices or power sockets connected to a 5V relay module
********************************/
// First we include the libraries
#include <OneWire.h> 
#include <DallasTemperature.h>
#include <Wire.h>
#include "RTClib.h" //RTClib by Adafruit Version 1.12.5

#define ONE_WIRE_BUS 2 // Data wire (DS18B20 sensors) is plugged into pin 2 on the Arduino 

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
const int relayPin1 = 8; //Coordinates relay inputs to Arduino outputs
const int relayPin2 = 9; //Coordinates relay inputs to Arduino outputs
const int relayPin3 = 10; //Coordinates relay inputs to Arduino outputs
const int relayPin4 = 11; //Coordinates relay inputs to Arduino outputs
int Hygrometer = A2;
int thresholdValue = 600;// you can adjust the wetness of the soil by changing the threshold value
uint8_t sensor1[8] = { 0x28, 0x3E, 0x80, 0xC1, 0x17, 0x20, 0x06, 0xB1 };
uint8_t sensor2[8] = { 0x28, 0x77, 0x92, 0xB5, 0x17, 0x20, 0x06, 0x0B };

OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices -DS18B20
DallasTemperature sensors(&oneWire);// Pass our oneWire reference to Dallas Temperature.
RTC_DS3231 rtc; //Initialize RTC module
//RTC_DS1307 rtc;



void setup(){
  Serial.begin(9600);
  pinMode(relayPin1, OUTPUT);
  pinMode(relayPin2, OUTPUT);
  pinMode(relayPin3, OUTPUT);
  pinMode(relayPin4, OUTPUT);
  pinMode(Hygrometer, INPUT);
  digitalWrite(relayPin1, HIGH);
  digitalWrite(relayPin2, HIGH);
  digitalWrite(relayPin3, HIGH);
  digitalWrite(relayPin4, HIGH);
//Serial.println("Dallas Temperature IC Control Library Demo"); 
// Start up the library
delay(1000);//Wait 1 second before accessing Sensor 
sensors.begin();
delay(1000);
Wire.begin();
delay(1000);
rtc.begin();

    // Following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  
void loop()
{
   DateTime now = rtc.now();
    Serial.println();
    Serial.println("Current Date & Time: ");
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

    delay(1000);

   
if (now.hour() <= 7 || now.hour() >= 19) { //Turns the grow light off between 7PM and 7AM (code in military time)
  digitalWrite (relayPin4, HIGH);
  Serial.println("Grow Light Off Between 7PM & 7AM");
} 
else {
digitalWrite (relayPin4, LOW);
Serial.println("Grow Light On Between 7AM & 7PM");
}

//Soil Moisture/Plant irrigation System
int sensorValue = analogRead(Hygrometer);// read the soil conductivity on analog pin A2:
  Serial.println();
  Serial.print("Soil Moisture Reading:");
  Serial.println(sensorValue);
  if(sensorValue > thresholdValue){
  Serial.println("  Irrigation System On");
  digitalWrite(relayPin2, HIGH);
  }
  else {
  Serial.println("  Irrigation System Off");
  digitalWrite(relayPin2, LOW);
  }
  Serial.println();
  delay(1000);

//Thermo-hydraulic plant root temperature management system
  Serial.println("Requesting temperatures:");
  sensors.requestTemperatures(); // Send the command to get temperatures

  Serial.print(" Sensor 1(*F): ");
  Serial.println(sensors.getTempF(sensor1));

  Serial.print(" Sensor 2(*F): ");
  Serial.println(sensors.getTempF(sensor2));

  delay(2000);

if(sensors.getTempCByIndex(0) < 22 ){
digitalWrite(relayPin1, LOW);
Serial.println("Soil radiator is On");
}
if(sensors.getTempCByIndex(0) >= 22 ){
digitalWrite(relayPin1, HIGH);
Serial.println("Soil Radiator is Off"); 
}
if(sensors.getTempCByIndex(1) < 26 ){
digitalWrite(relayPin3, LOW);
Serial.println("Sump Heater is On");
}
if(sensors.getTempCByIndex(1) >= 26 ){
digitalWrite(relayPin3, HIGH);
Serial.println("Sump Heater is Off");
Serial.println();
Serial.println();
}
}

Project is due tomorrow, so I hope this works.

Always format your sketches.

In the Arduino IDE, use Ctrl T or CMD T to format your code then copy the complete sketch.

Check that your serial print statements match what actually happens.

Note: once the time to your RTC is set, you do not need to set it again.

I think you are saying to hash out or delete line 56 in the void setup loop once the time has been set the first time. I had to restart the IDE to get the autoformat function to work. I did try it when you initially suggested it. :+1:

It has been awhile since I used forums. The kids these days seem to be mostly using social media. A lot of information and etiquette seems to have gotten lost. I really appreciate your help.

I purchased an Arduino Uno based starter kit several years ago, completed a simple sketch, got frustrated, and put it in a drawer. I have been helping my fiancé with school projects lately though and have been forcing it. It interests me but e-v-e-r-y-t-h-i-n-g interests me.

/********************************
Name: 5V relay module, DHT 11 humidity and temperature sensor module, DS18B20
temperature module function: This program shows how the DHT 11 temperature and
humidity sensor and the DS18B20 temperature sensor turns on devices or power
sockets connected to a 5V relay module
********************************/
// First we include the libraries
#include "RTClib.h" //RTClib by Adafruit Version 1.12.5
#include <DallasTemperature.h>
#include <OneWire.h>
#include <Wire.h>

#define ONE_WIRE_BUS                                                           \
  2 // Data wire (DS18B20 sensors) is plugged into pin 2 on the Arduino

char daysOfTheWeek[7][12] = {"Sunday",   "Monday", "Tuesday", "Wednesday",
                             "Thursday", "Friday", "Saturday"};
const int relayPin1 = 8;  // Coordinates relay inputs to Arduino outputs
const int relayPin2 = 9;  // Coordinates relay inputs to Arduino outputs
const int relayPin3 = 10; // Coordinates relay inputs to Arduino outputs
const int relayPin4 = 11; // Coordinates relay inputs to Arduino outputs
int Hygrometer = A2;
int thresholdValue = 600; // you can adjust the wetness of the soil by changing
                          // the threshold value
uint8_t sensor1[8] = {0x28, 0x3E, 0x80, 0xC1, 0x17, 0x20, 0x06, 0xB1};
uint8_t sensor2[8] = {0x28, 0x77, 0x92, 0xB5, 0x17, 0x20, 0x06, 0x0B};

OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with
                               // any OneWire devices -DS18B20
DallasTemperature
    sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.
RTC_DS3231 rtc;        // Initialize RTC module
// RTC_DS1307 rtc;

void setup() {
  Serial.begin(9600);
  pinMode(relayPin1, OUTPUT);
  pinMode(relayPin2, OUTPUT);
  pinMode(relayPin3, OUTPUT);
  pinMode(relayPin4, OUTPUT);
  pinMode(Hygrometer, INPUT);
  digitalWrite(relayPin1, HIGH);
  digitalWrite(relayPin2, HIGH);
  digitalWrite(relayPin3, HIGH);
  digitalWrite(relayPin4, HIGH);
  // Serial.println("Dallas Temperature IC Control Library Demo");
  // Start up the library
  delay(1000); // Wait 1 second before accessing Sensor
  sensors.begin();
  delay(1000);
  Wire.begin();
  delay(1000);
  rtc.begin();

  // Following line sets the RTC to the date & time this sketch was compiled
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}

void loop() {
  DateTime now = rtc.now();
  Serial.println();
  Serial.println("Current Date & Time: ");
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(") ");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();

  delay(1000);

  if (now.hour() <= 7 ||
      now.hour() >= 19) { // Turns the grow light off between 7PM and 7AM (code
                          // in military time)
    digitalWrite(relayPin4, HIGH);
    Serial.println("Grow Light Off Between 7PM & 7AM");
  } else {
    digitalWrite(relayPin4, LOW);
    Serial.println("Grow Light On Between 7AM & 7PM");
  }

  // Soil Moisture/Plant irrigation System
  int sensorValue =
      analogRead(Hygrometer); // read the soil conductivity on analog pin A2:
  Serial.println();
  Serial.print("Soil Moisture Reading:");
  Serial.println(sensorValue);
  if (sensorValue > thresholdValue) {
    Serial.println("  Irrigation System On");
    digitalWrite(relayPin2, HIGH);
  } else {
    Serial.println("  Irrigation System Off");
    digitalWrite(relayPin2, LOW);
  }
  Serial.println();
  delay(1000);

  // Thermo-hydraulic plant root temperature management system
  Serial.println("Requesting temperatures:");
  sensors.requestTemperatures(); // Send the command to get temperatures

  Serial.print(" Sensor 1(*F): ");
  Serial.println(sensors.getTempF(sensor1));

  Serial.print(" Sensor 2(*F): ");
  Serial.println(sensors.getTempF(sensor2));

  delay(2000);

  if (sensors.getTempCByIndex(0) < 22) {
    digitalWrite(relayPin1, LOW);
    Serial.println("Soil radiator is On");
  }
  if (sensors.getTempCByIndex(0) >= 22) {
    digitalWrite(relayPin1, HIGH);
    Serial.println("Soil Radiator is Off");
  }
  if (sensors.getTempCByIndex(1) < 26) {
    digitalWrite(relayPin3, LOW);
    Serial.println("Sump Heater is On");
  }
  if (sensors.getTempCByIndex(1) >= 26) {
    digitalWrite(relayPin3, HIGH);
    Serial.println("Sump Heater is Off");
    Serial.println();
    Serial.println();
  }
}

We couldn't have gotten it working in time without your help. The professors were impressed (Tuesday morning - so there was a big time crunch) during the presentation. MJ was just legalized there so the application possibilities are evident. My future FIL was proud of her, & future MIL was impressed and messaged me. The last time she messaged was 2019. (She has been and is still a tough one to give her acceptance. I'm so too old to be expected to meet parental expectations.) This was the last project before graduation tomorrow. There has been a long time and a lot of life experience that has transpired since she started college about 20 years ago. I know this was not really major project but it made a huge difference in our lives.

Thanks Larry.

We used the stepdown converter to power the relay and the 5v circuit. The motor noise absolutely would not allow the relay to be powered by Arduino.