user72368: I'm working on a battery-powered project. I'm trying to write code, which checks the battery voltage every 30 minutes and changes the color of a LED accordingly. Should I still be using millis() or is there a more efficient way to create a timer which tracks these longer time periods? Should I be concerned that the value of millis resets every 50 days, with an example timer like this:
bool timer(unsigned long &last_time, unsigned long period)
{
  unsigned long now = millis();
  if (now - last_time >= period) {
    last_time = now;
    return true;
  }
  return false;
}


user10794: Your posted code will never fail.
See http://gammon.com.au/millis
Let me put it this way. Does your clock "fail" at midnight?
Subtracting the start time from time now always works (even after 50 days) because of the way unsigned integers work.

user7508: There are various notions of efficiency, depending on what resource you
want to optimize for. For a battery-powered project, the most relevant
is likely to be energy-efficiency. Then, your code may not be the main
issue.
If you plan for your LED to be turned on continuously, this is going to
significantly tax your battery. Your first concern should then be to
minimize the power drain of the LED itself: make the current through it
as low as convenient, and maybe consider powering it through a DC-DC
converter in order to avoid wasting too much energy in the series
resistor. If your Arduino has a power-indicator LED, you should also
unsolder it. If it has a second microcontroller that it always on (like
the Uno), you should find a way to disable it.
Regarding the energy consumption of the CPU running your code, the only
way to be energy-efficient is to have it sleep most of the time, and
wake it up only when there is useful job to do. Unfortunately, the
Arduino core provides no standard way to sleep. You may have to look
into architecture-specific solutions, or search for a library that
abstracts this for you. On an AVR, for example, you may be able to
significantly lower the consumption by calling
sleep_mode() once within your loop(). This will put your
device in a “shallow” sleep mode, and it will be woken up by the next
timer interrupt (these happen every 1.024 ms). If you want to go to
deep sleep, you will have to arrange a wake-up source other than the
timer interrupt. An RTC could be an option. However, if you do not need
the 30 minute period to be accurate, you may as well use the
watchdog timer (which is ultra-low power) as an interrupt source.
There are many other things to be aware of when you care about power
consumption. I recommend reading Power saving techniques for
microprocessors, by Nick Gammon, which covers most of the
relevant issues. Note, however, that it discusses mostly AVR.

user85299: A library I like for this kind of task is Ticker
#include <Ticker.h>

void batterycheck() {
    // called by battcheck ticker every 30 minutes
    // read_voltage...
    // set_led_color...
}

Ticker battcheck(batterycheck, 30*60*1000, 0);

setup() {
    battcheck.start();
}

loop() {
    battcheck.update();
}

There's no advantage over doing it manually but I found this library after writing almost exactly the same code for a project that had a bunch of timers running concurrently.

user4143: 
Should I still be using millis() or is there a more efficient way to create a timer which tracks these longer time periods?

For longer time periods you really should use an RTC. You will get much better accuracy (assuming accuracy is what you want). You can also use an alarm on the RTC and use it to trigger an interrupt every 30 minutes and wake the MCU from sleep (so as to save precious battery power) to check the voltage.

Should I be concerned that the value of millis resets every 50 days, with an example timer like this:

Using that method, where you subtract the previous time from the current time, no, there is nothing to worry about. That is the recommended method to work around the wrapping of the millis() count.

72368: <p>I'm working on a battery-powered project. I'm trying to write code, which checks the battery voltage every 30 minutes and changes the color of a LED accordingly. Should I still be using <code>millis()</code> or is there a more efficient way to create a timer which tracks these longer time periods? Should I be concerned that the value of millis resets every 50 days, with an example timer like this:</p>
<pre><code>bool timer(unsigned long &amp;last_time, unsigned long period)
{
  unsigned long now = millis();
  if (now - last_time &gt;= period) {
    last_time = now;
    return true;
  }
  return false;
}
</code></pre>
 10794: <p>Your posted code <strong>will never fail</strong>.</p>
<p>See <a href="http://gammon.com.au/millis" rel="nofollow noreferrer">http://gammon.com.au/millis</a></p>
<p>Let me put it this way. Does your clock &quot;fail&quot; at midnight?</p>
<p>Subtracting the <em>start time</em> from <em>time now</em> always works (even after 50 days) because of the way unsigned integers work.</p>
 7508: <p>There are various notions of efficiency, depending on what resource you
want to optimize for. For a battery-powered project, the most relevant
is likely to be <em>energy</em>-efficiency. Then, your code may not be the main
issue.</p>
<p>If you plan for your LED to be turned on continuously, this is going to
significantly tax your battery. Your first concern should then be to
minimize the power drain of the LED itself: make the current through it
as low as convenient, and maybe consider powering it through a DC-DC
converter in order to avoid wasting too much energy in the series
resistor. If your Arduino has a power-indicator LED, you should also
unsolder it. If it has a second microcontroller that it always on (like
the Uno), you should find a way to disable it.</p>
<p>Regarding the energy consumption of the CPU running your code, the only
way to be energy-efficient is to have it sleep most of the time, and
wake it up only when there is useful job to do. Unfortunately, the
Arduino core provides no standard way to sleep. You may have to look
into architecture-specific solutions, or search for a library that
abstracts this for you. On an AVR, for example, you may be able to
significantly lower the consumption by calling
<a href="https://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html" rel="nofollow noreferrer"><code>sleep_mode()</code></a> once within your <code>loop()</code>. This will put your
device in a “shallow” sleep mode, and it will be woken up by the next
timer interrupt (these happen every 1.024 ms). If you want to go to
deep sleep, you will have to arrange a wake-up source other than the
timer interrupt. An RTC could be an option. However, if you do not need
the 30 minute period to be accurate, you may as well use the
watchdog timer (which is ultra-low power) as an interrupt source.</p>
<p>There are many other things to be aware of when you care about power
consumption. I recommend reading <a href="https://www.gammon.com.au/power" rel="nofollow noreferrer">Power saving techniques for
microprocessors</a>, by Nick Gammon, which covers most of the
relevant issues. Note, however, that it discusses mostly AVR.</p>
 85299: <p>A library I like for this kind of task is Ticker</p>
<pre><code>#include &lt;Ticker.h&gt;

void batterycheck() {
    // called by battcheck ticker every 30 minutes
    // read_voltage...
    // set_led_color...
}

Ticker battcheck(batterycheck, 30*60*1000, 0);

setup() {
    battcheck.start();
}

loop() {
    battcheck.update();
}
</code></pre>
<p>There's no advantage over doing it manually but I found this library after writing almost exactly the same code for a project that had a bunch of timers running concurrently.</p>
 4143: <blockquote>
<p>Should I still be using millis() or is there a more efficient way to create a timer which tracks these longer time periods?</p>
</blockquote>
<p>For longer time periods you really should use an RTC. You will get much better accuracy (assuming accuracy is what you want). You can also use an alarm on the RTC and use it to trigger an interrupt every 30 minutes and wake the MCU from sleep (so as to save precious battery power) to check the voltage.</p>
<blockquote>
<p>Should I be concerned that the value of millis resets every 50 days, with an example timer like this:</p>
</blockquote>
<p>Using that method, where you subtract the previous time from the current time, no, there is nothing to worry about. That is the recommended method to work around the wrapping of the millis() count.</p>
