Chicken Coop - LCD + 2 Fans + 2 Lights + RTC + DHT11 + Stepper

I apologize if this was not clear in my initial post but like I said, we are limited to 9500 characters. And to PaulS suggestion that that does not include attached code, yes PaulS the 9500 character limit does include attached code. Deleting the comment lines out of my code is what got me under 9500 characters.

The 9500 character limit refers to posted code. That is code in this box. And text. But, see down there? Below this window? The Additional Options link. Well, OK, so it does not look a lot like a link. But, it is. Select that. You can attach much larger than 9500 character files.

I am happy to hear that you are developing the code in pieces. That wasn't clear from your post.

I still think that those delays have got to go. The millis() function and a state machine (what do I need to do on this pass through loop, if is is time to do anything) is much better than sitting on your hands for relatively long periods of time.

Got it. Was just following instructions. The forum says to post code between `` using the #.

Anyways... Which delays do you suggest I delete? All of them? Are you suggesting the delays are causing the issue? If I don't have any delays, won't that cause a display issue on the LCD (i.e. the data won't be displayed long enough for anyone to read it)?

What is the millis() function?

Anyways... Which delays do you suggest I delete? All of them?

If I ask you to make me breakfast, consisting of eggs, bacon, toast, and coffee, can you figure out how to make all the food get done at the same time? Or, am I going to gets eggs, then, some time later, bacon, then, some time later, toast, and finally, after I've finished eating, the coffee will be ready?

Yes, all of the delays.

Are you suggesting the delays are causing the issue?

I don't understand what the issue is. I don't see any serial out put that says "Time to turn the relay on" and "Time to turn the relay off", annotated to note whether that happened, or not. Calls to delay() do not belong in a sketch that is doing more than blinking an LED.

If I don't have any delays, won't that cause a display issue on the LCD (i.e. the data won't be displayed long enough for anyone to read it)?

Not if you don't immediately overwrite the data. See the comments above.

What is the millis() function?

Is it necessary to point out that up there at the top of the page there is a link that says Main Site, and that on that page there is one that says Reference, and that on that page all the Arduino-specific functions are documented?

And to think I questioned whether posting here would be of any help or if I would just receive smart ass comments...

Code that I meant to turn relays on and off:

    if (LightOn == false) {

      //Calculate current time + delay minuts (Sleep variable time) to give a wide window making sure we can hit the start time.
      //If the program starts after this window then the relay will not start until StartHr & StartMin the following day.

      DelayFuture = CalcFuture(Start,0L,0L,Sleep,0L);

    if ((int)now.hour() >= StartHrRelay_3 && (int)now.hour() <= DelayFuture.hour() && (int)now.minute() >= StartMinRelay_3 && (int)now.minute() <= DelayFuture.minute()) {

      //Set future DateTime used to determine the duration of light on time

      future = CalcFuture(now,DurDay3,DurHour3,DurMinute3,DurSecond3);

    //Turn on light
      LightOn = true;
      digitalWrite(Relay_3, RELAY_ON);

      Serial.println("\r\nLight On\r\n");

    }
    }

  else {

  //Check current time - turn off light when conditions are met

    if ((int)now.day() >= (int)future.day() && (int)now.hour() >= (int)future.hour() && (int)now.minute() >= (int)future.minute()) {

    //Turn off light
      LightOn = false;
      digitalWrite(Relay_3, RELAY_OFF);

      Serial.print("\r\nLight Off\r\n");

    }
  }
    delay((Sleep*MultiMinute));

  //Check status of light

    if (LightOn == false) {

      //Calculate current time + delay minuts (Sleep variable time) to give a wide window making sure we can hit the start time.
      //If the program starts after this window then the relay will not start until StartHr & StartMin the following day.

      DelayFuture = CalcFuture(Start,0L,0L,Sleep,0L);

    if ((int)now.hour() >= StartHrRelay_4 && (int)now.hour() <= DelayFuture.hour() && (int)now.minute() >= StartMinRelay_4 && (int)now.minute() <= DelayFuture.minute()) {

      //Set future DateTime used to determine the duration of light on time

      future = CalcFuture(now,DurDay4,DurHour4,DurMinute4,DurSecond4);

    //Turn on light
      LightOn = true;
      digitalWrite(Relay_4, RELAY_ON);

      Serial.println("\r\nLight On\r\n");

    }
    }

  else {

  //Check current time - turn off light when conditions are met

    if ((int)now.day() >= (int)future.day() && (int)now.hour() >= (int)future.hour() && (int)now.minute() >= (int)future.minute()) {

    //Turn off light
      LightOn = false;
      digitalWrite(Relay_4, RELAY_OFF);

      Serial.print("\r\nLight Off\r\n");

    }
  }
    delay((Sleep*MultiMinute));
  //Chimney fan (Relay_1) on-off temperature
  if (dht.readTemperature() >= 20) {
    digitalWrite(Relay_1, RELAY_OFF);
  }
  else if (dht.readTemperature() < 18) {
    digitalWrite(Relay_1, RELAY_ON);
  }
  
  //Window fan (Relay_2) on-off temperature
  if (dht.readTemperature() >= 25) {
    digitalWrite(Relay_2, RELAY_OFF);
  }
  else if (dht.readTemperature() < 23) {
    digitalWrite(Relay_2, RELAY_ON);
  }
    if ((int)now.hour() >= StartHrRelay_3 && (int)now.hour() <= DelayFuture.hour() && (int)now.minute() >= StartMinRelay_3 && (int)now.minute() <= DelayFuture.minute()) {

Doesn't now.hour() return an int? Why is it necessary to cast to int?

Nested ifs are far easier to understand and debug, in my opinion, than compound ifs.

Please, do yourself, and us, a favor. Put each { on a new line, use the return key more often, and use Tools + Auto Format.

You have Serial.print() statements in your code. You are not sharing what you see, bogart.

Doesn't now.hour() return an int? Why is it necessary to cast to int?

No idea, I didn't write that code. I borrowed it from someone else's project. If it doesn't need to be there, or if it should be changed to something different, what do you suggest?

I've now used Tools + Auto Format. Didn't even know that feature existed. Other than making my code look pretty, I don't think it will solve my issue. But then again, neither will removing the delays.

Other than making my code look pretty, I don't think it will solve my issue.

No, but it makes it easier to see the structure.

But then again, neither will removing the delays.

Maybe not. But you aren't being clear on what the problem is, or where in the code/when the problem occurs.

If it doesn't need to be there, or if it should be changed to something different, what do you suggest?

I suggest that you look at the documentation for the class that now is an instance of, and determine what type the hour(), minute(), and second() functions return, and determine whether it is necessary to cast that value to a different type.

Thanks for your help PaulS.

Anyone else??? Paul doesn't seem to understand the issue.

Attached is my code. The delays are still in but I have Auto Formatted it. Seems to me that if I delete the delays the loop will cycle through too fast for the information to be displayed on the LCD.

Test.ino (9.88 KB)

Paul doesn't seem to understand the issue.

Perhaps because you have not stated the problem clearly enough.

Something like this. I see this in the serial monitor:

Time to turn the relay.

My code looks like this:

Serial.print("Time to turn the relay on");
digitalWrite(relayPin, HIGH);

The relay does not come on.

Now, something like that would be easy to troubleshoot.

Read up ^. The relays cycle when using a test code (i.e. one that cycles the relay and does nothing else) but don't with the attached code. The test code I used was essentially the same code as you listed in your preceding post.

I think its time for you to move on PaulS. This issue seem to be above your level of competency. Thanks for your help.

One last post, then I'll leave you alone.
Why are you reading the temperature so many times?

  float h = dht.readHumidity();
  float t = dht.readTemperature();

  if (dht.readTemperature() >= 20)
  {
    digitalWrite(Relay_1, RELAY_OFF);
  }
  else if (dht.readTemperature() < 18)
  {
    digitalWrite(Relay_1, RELAY_ON);
  }

  //Window fan (Relay_2) on-off temperature
  if (dht.readTemperature() >= 25)
  {
    digitalWrite(Relay_2, RELAY_OFF);
  }
  else if (dht.readTemperature() < 23)
  {
    digitalWrite(Relay_2, RELAY_ON);
  }

Where are the serial print statements to show whether the relay is to be turned on or off? What actually happens?

I know that it is frustrating when code doesn't work as you want, but, you need to remember that we can't see what you are seeing. If you don't show serial output, we can't see it. If you don't say what the relays are actually doing, we don't know.

Anyway, I wish you luck in solving your problem.

Maybe that is what is missing, the serial print statements. Maybe serial print statements should replace dht.readTemperature().

I don't know what the relays are doing with that code. As I said, they don't seem to be doing anything.

Attached is my revised code using PaulS's suggestions. I haven't been able to test it, because the USB chip on my Arduino burned up, but I've ordered a replacement.

Test.ino (10.7 KB)

Why write the data unless it has changed? is what I think the center of the issue here.
What the total center that is being asked is why do anything that doesn't need to be done. millisec() is great for that I've heard/.

Bob

I'm not sure what millisec() does. I've never heard of it and can't find any documentation on it.

I have however removed my delays and inserted millis()s. I've never used this function before and am not sure if I did it correct. Attached is my code.

Test.ino (11 KB)

There is a page here you might find useful Arduino - Home
and Specifically:millis() - Arduino Reference
For further reading try the Blink without delay Sketch. I've taken the liberty of posting it here for your perusal...
Please read the comments...

// constants won't change. Used here to 
// set pin numbers:
const int ledPin =  13;      // the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // interval at which to blink (milliseconds)

void setup() 
{
  pinMode(ledPin, OUTPUT);     // set the digital pin as output:  
}
void loop()
{
  // here is where you'd put code that needs to be running all the time.
  // check to see if it's time to blink the LED; that is, if the 
  // difference between the current time and last time you blinked 
  // the LED is bigger than the interval at which you want to 
  // blink the LED.
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) 
  {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;     
    if (ledState == LOW)   // if the LED is off turn it on and vice-versa:
      ledState = HIGH;
    else
      ledState = LOW; // set the LED with the ledState of the variable:    
    digitalWrite(ledPin, ledState);
  }
}

Bob

Thanks Bob.

I had used a different tutorial to create my code around the millis() function. The reference you provided makes more sense though...

Test.ino (11.4 KB)

This issue seem to be above your level of competency.

R i i i i i i g h t! - Scotty

Op, have you ever tested the code you wrote or borrowed with simple LEDs instead of going straight for the relay board? If the LEDs don't behave what the relays should, you have a software problem. If they do behave the way you intended your relays do, you have hardware problem.