Probably the Simplest of Timing Questions but it has me Stumped!

Hi Everyone,

First ever post and only the second sketch I have ever written so please bear with me.

Basically I am trying to automate an indoor garden turning some power LEDS on and off and reading the outside and inside temperatures from 2 x DS18S20 temp sensors.

I have got the temp sensors up and running and reporting to the serial monitor without any major problems and have managed to get the lights to turn off on 12 hour cycles using the ‘millis’ function which I understand the principles behind. However I now want to modify the code so that I can have a 10 hour dark and 14 hour light period. I have been looking all afternoon at ways to do it using but cant work it out. I cant seem to find anything online that answers my question without completely complete confusing me with commands I don’t yet understand. Thought I would post something on hear to see if someone could point me in the right direction.

I am mega eager to learn but as I said this is only the second piece of code I have ever written so apologies for what is almost certainly the simplest of questions. Any help would be really gratefully received.

This is what I have created so far which works fine:

#include <OneWire.h> 
#include <DallasTemperature.h>

OneWire oneWire(8);
DallasTemperature sensors(&oneWire); 

int LEDS=13;
int second=1000;
unsigned long minute= 60000;
unsigned long hour= 3600000; 
unsigned long halfday= 43200000;
unsigned long previousMillis=0; 

 
void setup()
{
   pinMode(LEDS, OUTPUT);
   sensors.begin(); //sets up sensors which is the 
   Serial.begin(9600);
}
  
 
void loop()

{
  //Reading 2 x DS18S20 Temp Sensors
  
  sensors.requestTemperatures();
  float CurrentTemp1; 
  CurrentTemp1 = sensors.getTempCByIndex(0);   
  
  float CurrentTemp2; //sets a 'float' type variable called 'Current temp
  CurrentTemp2 = sensors.getTempCByIndex(1); 
  
  Serial.println("Inside Temp ="); 
  Serial.println(CurrentTemp1);
  Serial.println("Outside Temp ="); 
  Serial.println(CurrentTemp2);
  
  
    //Lights Toggling On/OFF on 12hour cycle
  
  unsigned long currentMillis = millis();
 
  if ((unsigned long)(currentMillis - previousMillis) >= hour) 
  
      {
        
      digitalWrite(LEDS, !digitalRead(LEDS)); // Toggle the LED on Pin 13
      previousMillis = currentMillis;
      
      }
        
}

Many thanks

Mickey

Do you care when the light and dark periods are relative to real-world time?

If not, just have a state variable recording whether it's currently 'light' or 'dark' and use that to determine which duration to apply in your time calculation.

click the MODIFY button in the upper right of the post window. Highlight all you code. click the "#" CODE TAGS button on the toolbar above just to the left of the QUOTE button. click SAVE (at the bottom). When you post code on the forum, please make a habit of using the code tags "#" button.

@ Peter

Thanks for coming back to me.

Yes I do want it in sync with real world time, however accuracy is not critical. What I planned to do was to simply start the programme running by pressing reset and having the night time cycle run first. It would then simply be a case of starting the programme running in the evening and then it would naturally sync with real world time if that makes any sense?

Saying that I think means that your suggestion will actually work. The only problem is I really don't understand how to record a state variable. Do you mean a Boolean? If so how would this work?

Would it be a case of declaring a boolean for light and one for dark, then nesting the current 'if' statement inside another 'if' statement? Apologies for my lack of knowledge, I haven't got to anything with Booleans in it in the book I am reading.

Best regards

Mickey

If you are anywhere near to natural light it would be quite easy to make the lights trigger based on the actual light level, using an LDR as a light sensor. For example you could detect dawn/dusk transitions and use that to start your daily cycle.

To make a fixed 10 hour off / 14 hour on cycle, you just need to keep track of the current state.

boolean lightsOn = false;

...

if(lightsOn)
{
    if(millius() - previousMillis >= LIGHT_DURATION)
    {
        turnLightsOff();
        lightsOn = false;
        previousMillis += LIGHT_DURATION;
    }
}
else
{
    if(millius() - previousMillis >= DARK_DURATION)
    {
        turnLightsOn();
        lightsOn = true;
        previousMillis += DARK_DURATION;
    }
}

You get the idea.

Thanks very much thats great, really appreciate your help.

I actually manged to get it working without using a boolean before I read your post. what I did was to assign a state value to light and dark have them switching which seems to be working:

int state=0; 

....


unsigned long currentMillis = millis(); //creates a snapshot of the millis


if (state == 0) //
    {
      Serial.println("Night Time"); 
      digitalWrite(LEDS, LOW);
      
      if ((unsigned long)(currentMillis - previousMillis) >= hour)  
  
      {
            
      previousMillis = currentMillis;                              
      state = 1 - state; // Makes state now equal 1            
      }
      
    }


 if (state == 1)   
    {
      Serial.println("Day Time");       
      digitalWrite(LEDS, HIGH);          
      if ((unsigned long)(currentMillis - previousMillis) >= hour) 
  
      {
      
      previousMillis = currentMillis;                      
      state = 1 - state; // returns state back to zero      
      
      }

I will do a bit more reading on Boolean and implement your version I think as it seems much more efficient although essentially doing the same thing.

I did think of using a photosensor which would be much easier to do but I wanted to bottom out how to do this first as it was bugging me and I hate not understanding things.

Really appreciate your help in pointing my in the right direction. Learnt a lot through this exercise and it seems to be working nicely.

:)

Cheers

Mickey