2

So i'm making an interface that will have a digital clock....once a secondd.. i'd like to do other things at different intervals but if I delay(1000) then I have to wait that second which is now the minimum other things have to run at..

3
1

If you want a clock, your best option is... to buy a clock. Or, more precisely, an RTC module. Not only will it be way more accurate than your Arduino, it will also be able to keep the time off battery when your project is powered off.

If you really want to rely on the (unreliable) timing capabilities of your Arduino, you may want to try the millis()-based fake RTC provided by the Adafruit RTClib library: RTC_Millis. Example usage:

#include <RTClib.h>

RTC_Millis clock;

void setup() {
    Serial.begin(9600);
    clock.begin(DateTime(F(__DATE__), F(__TIME__)));
}

void loop() {
    static DateTime last_time;
    DateTime now = clock.now();
    if (now != last_time) {
        char buffer[] = "hh:mm:ss";
        Serial.println(now.toString(buffer));
        last_time = now;
    }
}

Note the test if (now != last_time), which is equivalent to the test if (currentMillis - previousMillis >= interval) of the Blink Without Delay tutorial (the RTC has a resolution of one second). It allows the code to be non-blocking.

Note also that, if you are willing to measure you clock's drift rate, you could calibrate-out that drift by using RTC_micros instead, and calling the adjustDrift() method in setup().

1

As said in the comments: you should read up on State Machines and have a close look at the Blink Without Delay example.

To get you started with an example closer to what you want to achieve, have a look at the code below; it will count seconds without blocking the loop.

unsigned long int secondsTimerMillis;
int seconds, minutes, hours = 0;
int secondsInterval = 1000; //ms

void setup() {
  Serial.begin(9600);
  // More setup() stuff goes here
  secondsTimerMillis = 0; 
}

void loop() {
  if ((millis() - secondsTimerMillis) >= secondsInterval) {
    seconds++;
    secondsTimerMillis = millis();
    Serial.println(seconds);
    // More stuff you want to do every second goes here
  }
  // More loop() stuff goes here
}

This is just the basic mechanism, and it won't be very accurate without some way of adjusting the clock every now and again.

You will also have to add code for checking seconds == 60 and increase minutes / reset seconds when needed; the same goes for hours.

Having/handling other events at other intervals is just more of the same.

Note that using a Real Time Clock as the basis for your timing would make your life programming much easier, and your clock more accurate, but I am assuming you want to do this "by hand".

-1

The short answer, to keep in mind while studying the above suggested reading, is to run your timer faster, maybe delay(1) or delay(10) or whatever is fast enough to service your other functions, then just make the "clock" be one of those functions that counts up the total small delays to get your 1 second delay. This assumes that your other functions don't take too much time to run, which will throw off the 1-sec timing count. So a better way than a simple count is to have the clock function read the current time and compare to the start time. When it reaches 1 second, you set a new start time.

2
  • 1
    Please add some example code, because your description is not very clear. Your first suggestion (adding up delays) sounds like it will produce code that’s hard to maintain and troubleshoot. The second suggestion is simply the kind of code that’s used in examples like the Arduino “blinkWithoutDelay” example and is much more useful. – StarCat Dec 13 '20 at 14:44
  • 1
    Given that the millis() / Blink Without Delay technique is simple and well documented, it seems counter-productive to suggest to the OP that he combines shorter delays. – Edgar Bonet Dec 13 '20 at 20:07

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.