Coding timed events

I am building a project that triggers relays high or low based on RTC time or DHT22 sensor values. My sketch sets the clock based on the current time that it is compiled and uploaded. After that is where I run into trouble. The "if" statements used by the DHT22 work perfectly, but for some reason, I can't wrap my brain around an efficient way for the sketch to query the clock and execute a command. Below is the except of code dealing with the timed events. My notes are commented out. The only "time" library I'm using currently is RTClib.

RTC.adjust(DateTime(__DATE__, __TIME__));  //this captures the time from the computer that is uploading sketch to Arduino
                                             // so ensure that the uploading computer has the correct time.
  delay(1000);
}

void loop()
{
  DateTime now = RTC.now();
  //
  // Because time is a direction in motion, >= will usually apply for testing as forward in time is upwards in count.
  //
  //int twelveHour = now.hour() - 12; // Variable used to display 13+ hours in 12 hour format
  //int zeroHour = 12;                // Variable use to convert "0" zero hour to display it as 12:00+
  Serial.print('-');
  Serial.print(' ');
  //if (now.hour() == 0){              // First we test if the hour reads "0"
  //Serial.print(zeroHour);           // if yes, serial print a "12" instead
  //}
  //else if (now.hour() >= 13){       // if no, Second we test if the hour reads "13 or more"
  //Serial.print(twelveHour);         // if yes, serial print that current hour minus 12
  //}
  //else 
  {
  
  Serial.print(now.hour(), DEC);    // if no, Third we conclude that the am hours are being displayed correctly.
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.print(' ');
  Serial.print('-');
  Serial.print(' ');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print('/');
  Serial.print(now.year(), DEC);
  Serial.print(' ');
  Serial.print('-');
  Serial.println();

  // Coded alarm triggers for Relays A-D.  Adjust hours and minutes in accordance with 24 hour time format.
  //
  //****************** 18/6 Light Cycle - RELAY_A ****************************//
  if (now.hour() >= 6 && now.minute() >= 0) {  // Turn on time for Veg Lights, ON at 6am
    digitalWrite(Relay_A, RELAY_ON);
    Serial.print("\t");
    Serial.print(F("Lights On"));  //  Text printed to serial monitor
    Serial.print("\t");
  }
  else if (now.hour() >= 0 && now.minute() >= 0) // "else if" was needed to create opposition to lights on
  {  // Turn off time for Veg Lights, OFF at 12am
    digitalWrite(Relay_A, RELAY_OFF);
    Serial.print("\t");
    Serial.print(F("Lights OFf"));  //  Text printed to serial monitor
    Serial.print("\t");
  }
  delay(500);
  //******************** FEED TIMES - RELAY_B ****************************************//
  if (now.hour() == 9 && now.minute() >= 0) {  // Turn on time for FeedPump1, ON 9am
    digitalWrite(Relay_B, RELAY_ON);
    Serial.print("\t");
    Serial.print(F("First 10 Minute Feeding"));  //  Text printed to serial monitor
    Serial.print("\t");
  }
  else if (now.hour() == 9 && now.minute() >= 10) {  // Turn off time for FeedPump1, OFF 9:10am
    digitalWrite(Relay_B, RELAY_OFF);
  }
  if (now.hour() == 18 && now.minute() >= 0) {  // Turn on time for FeedPump1, ON 6pm
    digitalWrite(Relay_B, RELAY_ON);
    Serial.print("\t");
    Serial.print(F("Second 10 Minute Feeding"));  //  Text printed to serial monitor
    Serial.print("\t");
  }
  else if (now.hour() == 18 && now.minute() >= 10) {  // Turn off time for FeedPump1, OFF 6:10pm
    digitalWrite(Relay_B, RELAY_OFF);
  }
  delay(500);
  //********************** Heat Mat for Clones - RELAY_C *******************************//
  if (now.hour() >= 2 && now.minute() == 0) {  // Turn on time for HeatMat, ON at 2am
    digitalWrite(Relay_C, RELAY_ON);
  }
  else if (now.hour() == 2 && now.minute() == 50) {  // Turn off time for HeatMat, OFF at 2:50am, will soon be reassigned
    digitalWrite(Relay_C, RELAY_OFF);           // trigger based on DHT values
  }
  delay(500);

As far as I can tell, the events trigger on, but the weakness of my code is that nothing ever triggers off again because everything is always true and I don't know how to make the oppositions false. I thought the inclusion of "else if" would give me the needed opposition, but I was mistaken. Is it possible to do what I want to do in code, or does this NEED to be ironed out in a library?

TYIA

I am building a project that triggers relays high or low based on RTC time

Which RTC? What library are you using?

It is not clear why you are testing for >= instead of ==. Typically, you want to make changes at specific time. Once the pins are turn on or off, there is no need turn them on again, or off again, over and over.

You could speed up your testing by using minute() and second(), instead of hour() and minute().

Oh, sorry, I forgot those. I'm using RTClib and HERE is the link to adafruit that was in the READ ME file. I'm using the DS3231 Chronodot in this project. My board is a Mega2650 r3 clone. Initially, I had a problem with ==, but I later discovered that problem was constantly updating my code and uploading it. Well doing that caused the sketch not to trigger if say an event was planned for == 9:00 and I upload a new sketch at 9:02, the event would be skipped.

Please excuse me as I have not yet learned to think like a programmer. As a gardener, I know what needs to get done throughout the day, but scheduling events in code is way more thought out and concise.

I will adopt testing in min/sec vs hour/min. That would save me days literally, thanks!

Also, on a slightly different note, I cut the reset-en trace 5 days ago that lead to AVRDUDE errors. Yesterday, I soldered a toggle switch pigtail back on and it works well again. This allows for fluid time keeping in and out of serial. |500x375

Ok, let’s say we want to turn a thingy on between 6:00 and 6:30 PM

#define MINUTESERIAL(hour, minute) ((hour)*60+(minute))
#define NOWSERIAL MINUTESERIAL(now.hour(), now.minute())

boolean thingyIsOn;

void loop() {
  …

  if(NOWSERIAL >= MINUTESERIAL(18, 0) && NOWSERIAL < MINUTESERIAL(18,30)) {
    // time is between 6 and 6:30 PM
    if(!thingyIsOn) {
        turn_the_thingy_on();
        thingyIsOn = true;
    }
  }
  else {
    if(thingyIsOn) {
        turn_the_thingy_off();
        thingyIsOn = false;
    }
  }

  …  
}

A generalisation of this is to define a function thingyShouldBeOn(). Like so:

void loop() {
  …

  if(thingyShouldBeOn()) {
    if(!thingyIsOn) {
        turn_the_thingy_on();
        thingyIsOn = true;
    }
  }
  else {
    if(thingyIsOn) {
        turn_the_thingy_off();
        thingyIsOn = false;
    }
  }

  …  
}

boolean thingyShouldBeOn() {
  return NOWSERIAL >= MINUTESERIAL(18, 0) && NOWSERIAL < MINUTESERIAL(18,30);
}

You can then do interesting things by having several thingies and having complex schedules for each thingy.

const int NUMBER_OF_THINGS = 15; // or whatever

boolean thingyIsOn[NUMBER_OF_THINGS];

void loop() {
  …

  for(int i=0; i<NUMBER_OF_THINGS; i++) {
    if(thingyShouldBeOn(i)) {
      if(!thingyIsOn[i]) {
          turn_the_thingy_on(i);
          thingyIsOn[i] = true;
      }
    }
    else {
      if(thingyIsOn[i]) {
          turn_the_thingy_off(i);
          thingyIsOn[i] = false;
      }
    }
  }
  …  
}

boolean thingyShouldBeOn(i) {
  // work out if thingy i should be on.
  // this function turns on thingy 4 at 18:04 and of at 18:34

  return NOWSERIAL >= MINUTESERIAL(18, i) && NOWSERIAL < MINUTESERIAL(18,30 + i);
}

Thanks PaulMurray, the moment I saw your inclusion of boolean, I knew there was the opposition I knew I needed, but the NOT statements and i++ arrays are still outside of my comprehension level. I mean, I've been through the array tutorials, and have a fair understanding of them, but when used above, I guess it just threw me for a bit of a loop. The !NOT, is that like an "anti-question"?

Edit1 - I went through a tutorial on boolean and (!)not on youtube, then came back and revisited your reply. I think I see a bit more clearly, but get lost again b/c there are too many different "thingys". Could I trouble you to use different names for just one more brief code example? Also, are you implying to have those names be defined at the beginning as a global? This would go along way when I share this project with people that have not yet heard of Arduino. I do wish to share this project with other gardeners and having all the changes to be made mostly in one place if possible will assist greatly.