1

I am building a project when I need my arduino to execute some code at two given hours of the day, for example one at 19:00 and another at 06:00. I know that with a RTC module I can do this easily, however how can I do that without a RTC module? I do not want to have to connect my arduino to a computer neither to the internet. It does not also have to be precise, a couple of minutes off would be ok.

My board is an Uno R3.

  • 2
    It depends on your arduino board. Is there a resonator or a crystal? If you have a crystal then you could use the time and timealarms libraries and let the time library run on millis(). You can also use millis() for 11 hours and 13 hours without the time library, because millis() can count up to 50 days. – Jot Apr 11 '18 at 22:19
  • @Jot My board is an Arduino Uno Rev3. – Tiago Apr 11 '18 at 22:27
  • the esp8266 can read time from NTP service on Internet – Juraj Apr 12 '18 at 4:33
  • 3
    Any built-in time facilities are highly inaccurate, from my experience 1-3 minutes off / day - after a month it could easily be executed an hour earlier/later than intedned. You need either RTC or NTP. – wondra Apr 12 '18 at 5:51
  • 1
    @wondra that is probably with a resonator. I have a uno clone with a crystal and it is less than one hour off per year. – Jot Apr 12 '18 at 22:57
4

If you start with the "BlinkWithoutDelay" sketch that comes with the Arduino IDE, you can execute your code alternating between 11 hours and 13 hours.

// Power up the circuit at exactly 06:00.
unsigned long delayInterval = 0;
unsigned long previousMillis = 0;
bool twoHoursAdded = false;

void setup(){

}

void loop(){

  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis >= delayInterval){

    // previousMillis = currentMillis;

    // Use this "method" of incrementing the previousMillis variable
    // instead of the code used in the BlinkWithoutDelay sketch.
    previousMillis += delayInterval; 

    if(twoHoursAdded == false){
      delayInterval = 1000UL * 60UL * 60UL * 13UL;
      twoHoursAdded = true;
    }
    else{
      delayInterval = 1000UL * 60UL * 60UL * 11UL;
      twoHoursAdded = false;
    }

    // Your code here that is run at 06:00 and 19:00.

  }
}

"Down sides" to using this code.

  1. If there is a "power failure", the timing will be off, WAY off until you reboot the Arduino at exactly the right time.
  2. You have to power up the Arduino at exactly the right moment for "it's" timing to match your "clock" timing.

If it's within your budget, have a look at the DS3231 modules available on aliexpress.com / ebay.com. They have a lithium battery backup incase of power outage and are really easy to connect to your Arduino using I2C. There are several libraries on Github that simplify using the DS3231 modules.

-1

I am not sure why you are opposed to the RTC or whether you were excluding all external circuitry for the solution. So, I am just throwing this out there...

A CMOS-4060 ripple counter can be programmed for just about any time period and using two of them would give you two separate time constants.

enter image description here

source Substitute the relay for a signal wire to the CPU.

The Cmos 4060 is a 14-bit binary counter. However - only ten of those bits are connected to output pins. The remaining bits - Q1, Q2, Q3 and Q11 - do exist. You just can't reach them.

The 4060 also has two inverters - connected in series across pins 11, 10 & 9. Together with R3, R4, R5 and C3 - they form a simple oscillator.

While the oscillator is running - the 14-bit counter counts the number of oscillations - and the state of the count is reflected in the output pins.

By adjusting R4 you can alter the frequency of the oscillator. So you can control the speed at which the count progresses. In other words - you can decide how long it will take for any given output pin to go high.

When that pin goes high - it switches the transistor - and the transistor in turn operates the relay.

In single-shot mode - the output pin does a second job. It uses D1 to disable the oscillator - so the count stops with the output pin high. .

If you want to use the timer in repeating mode - simply leave out D1. The count will carry on indefinitely. And the output pin will continue to switch the transistor on and off - at the same regular time intervals.

For example, if you want a period of 9 Hours - the Range table shows that you can use the output at Pin 2. You need Pin 2 to go high after 9 x 60 x 60 = 32 400 seconds. The Setup table tells you to divide this by 512 - giving about 63 seconds. Adjust R4 so that the Yellow LED lights 63 seconds after power is applied. This will give an output at Pin 2 after about 9 Hours.

If you increase the value of R3 - and reduce R4 by the corresponding amount - you can set the time delay more precisely. Select a value for R3 that takes you close to the time you're after. And use the reduced value pot - to make the fine adjustment. Note that even finer adjustments are possible with a multi-turn pot.


As mentioned with VE7JRO's solution, this solution (while being pretty accurate) will eventually drift with time and must be powered up at an exact time that is synchronized with the desired trip times.

  • 2
    This is terrible advice. Why would anyone want to add a dozen extra parts only to have a time source that is way worse than the internal timebase of the Arduino Uno? In terms of frequency stability, an RC oscillator like this is about the worst you can get. The ceramic resonator clocking the Arduino is way better, and the quartz crystal of an RTC module is better yet. People go to the trouble of adding an RTC only because it is a better timebase than the millis() they already have. – Edgar Bonet Jun 19 '18 at 7:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.