idea/approach help on simple farming project

Hey all,

im not new to arduino, and have manged to bang out a few workable projects. I need a bit of help on how to approach this new one.

goal (in human speak):

-for my chickens, I need to turn on a light at early dark
-that light needs to be on for four hours (roughly) from first dark.
-the light needs to be off after that fours hours, and not be on again until next dusk, when it start to get dark ( next day - i.e. light goes on about 6p, shuts off 10p, not on again until next night 6p).
-the loop itself cant delay 4 hours - some other stuff needs doing.

Whats working so far in prototype:
-can work the lights on relay control
-i have switch that overrides the light on/off state -works
-photo cell to tell when its dark.

Whats NOT working -
-"time" in the arduino is not my friend. I dont need a super accurate clock. I get its not RTC.
-I basically need a 4 hour count down timer function (when dark, light on from first dark for 4 hours)
-then another timer function to not check the state of dark again until the next day (maybe until light, or another timer?)
-also, not sure if I am putting always increment time values into long vars, if I am going to get an out of memory state one day doing long timers.

help needed -
just a bit of help on approach. I can muddle my way through the code if on the right path - yet I am not too proud to accept code examples if you have interesting stuff :slight_smile:

blink without delay is the key if you run powered.

if you want ultra low power, then you want a different approach.

you load how many second before you time-out and do a thing.

let's say the dusk comes at 6:00 pm,
sensor changes state.
timer begins
couts for around 4 hours
goes off

waits for next day dusk

Hello FOBI.

Perhaps I am thinking far too simplistic for your application; why not implement a 24hr calibration period at boot up? You already have the photo cell and you'll never have to worry about daylight savings time adjustments. Reset the millis() when dark initiates.

Dave -in -

not sure if I follow your advice. your second post is exactly what I am seeking. I can detect dusk. no problem. I can turn the lights on. no problem. its the delays that are killing me. when dusk, light on for 4 hrs, then not again until next dusk (on photo sensor detect).

to jmeller -

I am playing alot with millis, yet no pro at all.

what I am worried about is storing an increment value for 4 -6 hours.

like - on event (dark) - capture current millis - then when current millis is about 4 hours old - do new event (light off).

I could do that - but seems like a poor approach. really trying to verify if there is a better approach than millis. timerone interrupts?

really trying to verify if there is a better approach than millis.

Better is in the eye brain of the beholder.

What is your definition?

There is little to no reason not to use the millis technique.

BTW, an RTC is only ~$2.00


Millis() is the normal way of doing this, especially if power is not critical (not battery operated).

I guess you could use one of the timers for that as well, but it's not as easy.

You also won't need an RTC. Just record when it's dusk (i.e. your brightness reading goes below a certain value - make this so that you won't get affected by a particularly dark cloud, unless you want to), record the millis(), switch on the lights, and 14400000 milliseconds later you switch off your lights again.

your arduino IDE has the blink-without-delay as a free sketch for you to play with

open that, set the interval to 1440000 // 1,440,000 is 4 hours

you look at your light sensor and at dusk,
you start timing.
and turn the lights on.

after 4 hours, you turn the lights off

next morning, the light sensor will come on
then go off at dusk
and the system will repeat.

you can replace the fixed 1440000 with a pot
or with a display that has buttons.

you can have a couple switchs to set the timing.

you can have a feedback on your light sensor so that if it is cloudy, the lights come on to keep the perceived light at expected day light levels.

you can have a second timer that waits for 24 hours after the last time it turned on, and assuming it was a dark day and the outside sensor never came on, the 24 hour timer would turn the lights on for the alloted 4 hours....

BTY, you can have it set to time out to one hour...
then count 4 times.... or 6 times....

if you are having problems, let us know what you are having problems with and we can help out.

I am playing alot with millis, yet no pro at all.

what I am worried about is storing an increment value for 4 -6 hours.

this is where we tell you to read the sticky-post at the top of every forum on how to use this forum, and to read #7
then post your code and tell us what you are having problems with.
here is a clue. you need to have a separate variable, we call it a flag as a slang term. it does not have any use other than to flag a point in your sketch where/when a thing has changed.
int StartFlag ;
read the light sensor
if there is light, StartFlag = 1 // comes on in the moring
if there is no light, StartFlag= 2 // changes at dusk
if StartFlag == 2 {
StartFlag = 3 ; // set to 3 so you do not repeat this step in the same day
unsigned long currentMillis = millis();
turn on the lights

that loads your time

if (currentMillis - previousMillis >= interval) {
then turn off the lights

tomarrow, the light will have StartFlag back to 1 and the process will repeat.

I say tomarrow, or under a full moon, or from headlights, or a helocopter.....

you can have the same timing count for 20 hours ( repeat 5 times ) before it re-sets.

wow, thanks all. I really wish I did more Arduino projects, because this forum is full of really positive and helpful people.

I think based on the insight you all gave, I nailed it. I will be running this off battery (its in a chicken coop on solar!), and if battery consumption gets bad, ill go RTC I guess. Any comments or criticisms welcome on code below.


#include <math.h>
int lightOnButPin = 28; // Pin of physical button
int relayPin = 31; // Pin of Relay Module
int photoPin = A0; // Pin of phtocell Module
int lightLvl =0;
int nightTimerState =0;
int lightTimer = 5000;
int dayTimer = 10000;
unsigned long eventTriggerTime = 0;
unsigned long currentTime = 0;

void setup()
pinMode(relayPin, OUTPUT); // Set Pin connected to Relay as an OUTPUT
pinMode(lightOnButPin, INPUT); // Set Pin connected to Relay as an OUTPUT
digitalWrite(relayPin, LOW); // Set Pin to LOW to turn Relay OFF

void loop()

void NightCheck()
if (nightTimerState ==0)
if (lightLvl < 500)
digitalWrite(relayPin, HIGH); //turn light on
nightTimerState == 1; //set so it wont read the light level until the 12 hr (next day) timer has expired.
eventTriggerTime = millis(); //set the time the lights first came on within the 12 hr period.
eventTriggerTime = (eventTriggerTime / 100 + (eventTriggerTime % 100 > 2)) * 100; //this puts time into simplified value, always increments of 100. every 1000 is 1 second.
Serial.print(“light on”); //for testing, remove when running

void TimerWatch()
currentTime = millis();
currentTime = (currentTime / 100 + (currentTime % 100 > 2)) * 100; //this puts time into simplified value, always increments of 100. every 1000 is 1 second.
if (currentTime - eventTriggerTime >= lightTimer) //checking to see if the set time value (5 sec in test) has passed since the light went on.
digitalWrite(relayPin,LOW); //turn the light off
Serial.print(“light off”); //for testing, remove when running

if (currentTime -eventTriggerTime >= dayTimer) //check to see if since the time the lights came on, if 12 hrs has passed (10 sec in test)
nightTimerState = 0; //this will now allow the photo cell to be checked again, looking for next dusk/low light
eventTriggerTime = 0;
currentTime = 0;
Serial.print(“12hr done”); //for testing, remove when running


void Button()
if (digitalRead(lightOnButPin) == HIGH)
digitalWrite(relayPin, HIGH);

If you're using an Uno, you'll always have 50-100 mA of current, can't go less than that.
The Pro Micro should do a lot better as it has so little extras on board. Assuming you also run your lights off that battery, you won't notice the extra draw, it's much less than your lights take.