2

I'm a very beginner with electronics and of course with Arduino. Actually I've been in the software field (.NET) for the past 12 years. I am trying to develop a simple system to run for longer using Arduino Nano. Longer means roughly it could be for years continuously, expecting normal wear and tear.

So what I understood is Arduino loop always executes based on any values from sensors while in the loop. And also Arduino has some interrupt mechanism too.

But since the looping system feels pretty awkward for some situations, I tried to stop the loop using exit(0); inside the loop. So loop will stop after the first execution.

I am trying to build an external simple interrupt hardware system (like any timer object in software) which interrupts Arduino in a specified interval, say 20 sec. So when that interrupt on that particular pin occurred we can call some function there to do the job and that's all from Arduino side and it can go back to sleep.

So I believe this will reduce the load on Arduino and of course since no looping it will not get heated at all. How can we make such a system (external timer) to interrupt Arduino in specific intervals? This is just a theory in mine, not an idea how to implement it in electronics.

How can I achieve this above scenario?

  • You can implement sleep timers in code. No need for external circuits – cde Aug 14 '17 at 6:03
6

So, since you're coming from the application domain there are some things you might want to consider:

  • Make sure to always stay inside the super loop. With an Arduino or any other Microcontroller (not using a RTOS) you do not have anything defined that's going to happen after the superloop. Everything that happens after this loop is basically undefined (it typically is a reboot or jump to a default interrupt handler but may also be a lockup). Simply telling the processor to "exit" will .. well, exit - but you have no idea where it's going after that. To allow for interrupts and further execution of your main code, you need to have your processor in a defined state (and that basically is the super-loop). as a comparison with your PC, after you exit a thread, the operating system will take over. On your Arduino there is no such concept. The super-loop IS your OS (well, at least it's some minimum implementation of a non-preemptive scheduler).
  • If you want to have only interrupt actions active while the processor is using only little power, you will need to use the processors sleep modes. These are modes, where special functionality is disabled but which keeps the processor alive or in some idle mode where it's actually just waiting. Whilst the Arduino may have various sleep modes, none of them are what can be achieved with other architectures, such as the MSP430 platform or some SAMxL platform. Those are dedicated as low power processor and provide the necessary deep sleep modes.
  • When using a deep sleep mode, it depends on the actual sleep mode which interrupts can wake the processor. Typically for the deepest sleep modes, only few interrupt sources will actually wake the processor up as all other peripherals are inactive either because their clock was gated or power was turned off for that function block.
  • You will always have some power drain for the processor but keep in mind that it's not only the processor which will require power. At some point, you have leakage currents through your capacitors/resistors and other ICs on your board which require power as well. When you're talking about "years", you will also need to account for the battery discharge as well. No battery is perfect.
  • Jack Ganssle is probably well known for his insight into anything related embedded, but he explicitly wrote some articles for ultra-low-power systems. You must read those if you want to start somewhere. While having the software side covered using low power techniques you will also need to tackle the hardware side, yet as I said - the Arduino wasn't made for such tasks even if it provides some basic sleep modes.
  • Thats really a great explanation. That means no need to worry about the continuous loop ever there is nothing in the loop? isnt it? – Sandeep Thomas Aug 14 '17 at 6:11
  • Not exactly. You will need to consider the loop, even if the processor does nothing, it still executes one operation (a NOP operation) all the time and thus requires more power. Only transitioning to a sleep mode will allow for reduced power. The loop itself is a concept to keep the processor in a defined state. – Tom L. Aug 14 '17 at 6:21
  • OK.. thats sounds great.. OK I will have a try with that.. – Sandeep Thomas Aug 14 '17 at 6:35
  • 1) Although they may not be as good sleepers as the other MCUs you mentioned, the AVRs can sleep pretty deep. I have one of them running since June 2012 off the same pair of AA cells. And it's awake more than 4 min/day. 2) An empty loop() does perform some CPU operations, but none of them is a nop. – Edgar Bonet Aug 15 '17 at 20:23
1

You wrote:

I'm a very beginner with electronics [...] the looping system feels pretty awkward

I think these two statements are highly correlated. It feels awkward to you simply because you are not used to it.

So what I understood is Arduino loop always executes based on any values from sensors while in the loop.

This sounds like a misunderstanding. The Arduino loop() is a function you write, and whether its behavior is “based on any values from sensors” or not is up to you. The main() function provided by the Arduino core library will just call your loop() repeatedly.

I tried to stop the loop using exit(0);

As explained by Tom L. in his answer, there is nowhere to exit to. In this kind of embedded system, exit() essentially means “stop doing any useful work”. On AVR microcontrollers (like in the Nano), exit() is implemented as an empty infinite loop running with interrupts disabled.

I believe [sleeping] will reduce the load on Arduino and of course since no looping it will not get heated at all.

Heat? What heat? The CPU core of the Arduino does not generate heat. Not at any significant level. Think about this: it's clocked at 16 MHz. Yes, those are megahertz: snail pace! The MCU can get hot if you have it source or sink too much current, but this is completely unrelated to CPU load.

I am trying to build an external simple interrupt hardware system [...] which interrupts Arduino in a specified interval, say 20 sec.

Since you come from the software world, you probably know about “premature optimization”: this is exactly what you are doing here. I recommend you stop right now. Do not build into your system complexity that may not be useful. Instead, start simple: read the Blink without delay[] Arduino tutorial, and apply this technique to solve your problem. In a nutshell, you will put, inside your loop(), something like:

if (millis() - previousMillis >= JOB_PERIOD) {
    do_the_job();
    previousMillis += JOB_PERIOD;
}

Note that the tutorial I mentioned would instead do something like previousMillis = millis();, which is fine if you want to ensure that JOB_PERIOD is the minimum time between the jobs. The code above, instead, assumes you want to enforce an average period.

Once you have this working, test it, and see whether you do need to optimize it. There are two aspects that could be optimized: current consumption and period accuracy. Either may be useful for your particular application. Or none. Or both. It all depends on your specific requirements.

Current consumption

There is a low hanging fruit here. You can put the CPU to sleep on every loop iteration, simply by calling sleep_mode():

#include <avr/sleep.h>

const uint32_t JOB_PERIOD = 20000;  // 20 seconds

void do_the_job()
{
    // The stuff you have to do every 20 seconds.
}

void loop()
{
    static uint32_t previousMillis;
    if (millis() - previousMillis >= JOB_PERIOD) {
        do_the_job();
        previousMillis += JOB_PERIOD;
    }
    sleep_mode();
}

The Arduino core library has a timer interrupt triggered every 1024 µs. This is the interrupt responsible of updating the variable that millis() returns, and it will wake you up. With the code above, the Arduino will be awake for only a few CPU cycles per iteration (update millis(), subtract, compare) and spend most of its time sleeping. In the default sleep mode, only the CPU does sleep. But it is also the only mode in which the timer does not sleep, and is thus the appropriate mode here.

The trick above should suppress most of the power consumption of the CPU. If it's still consuming too much for your liking (i.e. if you want your Nano to run for years on a couple of AA cells), you should know there are ways to push the microcontroller into the ultra-low power realm. But it is not so simple, and you will have to tune not only the software, but also the hardware. Your journey into microamp hunting should start by reading Power saving techniques for microprocessors, by Nick Gammon. The link has already been mentioned in Chirag Patel's answer.

Period accuracy

The Arduino Nano being clocked from a ceramic resonator, you should expect its timing accuracy to be pretty poor. The standard solution for when you need accurate timings is to use an RTC. You could query the RTC periodically to ask for the current time or, better yet, you can choose an RTC with “alarm” capability. This is not unlike an alarm clock: you program it to send you an interrupt signal at a time of your choosing. Read the manual of your RTC for details.

0

You can refer below links once for understanding sleep concept on Arduino.

1) http://playground.arduino.cc/Learning/ArduinoSleepCode

2) http://www.gammon.com.au/power

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.