8h 10h and 12h light timer, without rtc

Disclaimer Im fairly new to arduino

Hello everyone thanks for taking the time to read :slight_smile:

So I'd really love to implement arduino into gardening and I'm aware thats been done so many times.

But I cant find anywhere that would tell me how to set up a simple 8h, 10h and 12h light on period (with buttons) with an arduino and relay while not using an rtc module.

Is it possible? Would i have to have the delay set at (1000000) for example, could the arduino count that long? or is there another possible way?

Any help and advice would be greatly appreciated.

You can use the Arduino as a clock but the 16 MHz resonator is only about 0.5% accurate. That means your clock may be off as much as 7.2 minutes a day. It will also not be able to remember what time it is if it ever looses power.

You can get a basic DS1307 RTC module or a precision DS3231 RTC Module for under $5.

Would i have to have the delay set at (1000000) for example, could the arduino count that long?

Yes, that's the general idea. But 1000000 is only 16 mins 40 seconds. For 8 hours, you can use delay(86060*1000). In theory, delay() can go up to around 24 days, but...

The problem with using delay() like that is that the Arduino will do nothing else for 8 hours. That may be OK, but if you want it respond to other button presses, because you want to cancel or choose a different time, it won't even see the button presses. For this reason, using delay() for a second or more is something only beginners do. As soon as you become a little more competent, you will want to switch to using millis().

const unsigned long OneHour = 60UL * 60UL * 1000UL;
const unsigned long EightHours = 8 * OneHour;
const unsigned long TenHours = 10 * OneHour;
const unsigned long TwelveHours = 12 * OneHour;
const unsigned long TwentyFourHours = 24 * OneHour;

// Default to 8 on, 16 off.
unsigned long OnTime = EightHours;

unsigned long StartTime;

const byte RelayPin = 3;
const bool RelayOnValue = LOW;
const bool RelayOffValue = HIGH;
bool RelayState = RelayOnValue;

const byte TenHourButtonPin = 4;

void setup()
  StartTime = millis();
  digitalWrite(RelayPin, RelayState);
  pinMode(RelayPin, OUTPUT);
  pinMode(TenHourButtonPin, INPUT_PULLUP);

void loop()
  unsigned long currentMillis = millis();
  unsigned long interval = (RelayState == RelayOnValue) ? OnTime : TwentyFourHours - OnTime;

  if (currentMillis - StartTime >= interval)
    RelayState = !RelayState;
    digitalWrite(RelayPin, RelayState);
    StartTime += interval;

  // Start 10 on, 14 off cycle
  if (!digitalRead(TenHourButtonPin))
    OnTime = TenHours;
    StartTime = currentMillis;
    RelayState = RelayOnValue;
    digitalWrite(RelayPin, RelayState);

we tend to like solutions that will resolve problems over long periods.

A cheap clone will have a resonator. the errors will be in multiple minutes per day
some Arduinos will have crystals and the errors will be greatly reduced.

all microcontrollers without an RTC will add or subtract seconds or minutes per day.

An RTC can be had for a few dollars and be added to almost any microcontroller.

a micro-controller that has Wifi and can access the internet, can pull time from the internet.
I imagine that if you have a home WiFi, that there might be some way to pull time from you cell phone or computer or any other device on the WiFi, probably more trouble than needed.

if you are fine with your device adding a couple minutes per day, then there is no need.
if you are doing something like watering plants, you can use a sensor to sense sunrise and just set your water schedule to be an hour after sunrise, 45 minutes before, an hour after sunset, 53 minutes before... etc.

Since the sun rise and setting times change daily, you can write some code to follow the change and even allow to cloudy days.

The answer is how concerned are you that if, after a month, the start time if off by an hour ?

if the problem is not the accuracy of the timer, then use a 1s timer interrupt where each second a variable is incremented. if the variable is 28800, about 8hours passed. then do whatever you want, and reset the variable back to 0.

this way you dont occupy the arduino fot 8hours straight.

if the problem is not the accuracy of the timer, then use a 1s timer interrupt

An interrupt from where/what? The OP is asking about solutions that do not require an rtc.

If you mean an interrupt from an internal avr timer, then that is a pointless suggestion. There is already a 1ms interrupt set up for you, which increments millis().