How to break out of the main loop

I'm new to this platform and I'm a bit lost.

I've read that arduino is basically C++, but in my sketch folder all I can see are source files with .ino extension, where (afaik) you need to stick to the setup and loop template.

I'm fine with the setup, but having to loop always is kind of a waste. For instance, it would be nice if I could write a sketch where there are only interrupt handlers and no loop is needed.

Is there a way not to loop? For instance, by returning a special value in loop()? Or maybe there's some kind of mechanism to disable the loop, like detecting the empty function in preprocessing stage and removing the call in the main code?

BTW, where's the source code for the main entry point? I'm looking for the source files where constants like HIGH and LOW are defined, and also the point where the calls to the sketch are made. I'd like to read them to better understand the platform. And perhaps there's a way to compile a customized "main" with no loop?

Thanks in advance.

PS: I've been glancing through the sources at github, but I think these are the sources for the java IDE. Can anyone point me to the correct folder for the Arduino Uno?

You can have your own main function, e.g.

int main (void) {
  init();
  
  //Your code here
}

Stick that in a sketch and you get rid of setup and loop.

But...
Why do you need to? Just leave loop empty and the compiler will optimise the call to loop away. You will simply be left with this in the main function:

init();
setup();
for(;;){
}

Besides, why do you need to disable loop. You have to have some form of loop, even if you only use interrupt handlers for everything, otherwise the processor would reach the end of the program and reset.


Oh, and all the source can be found here:
\hardware\arduino\cores\arduino
With constants being defined in "Arduino.h" and the main file being "main.cpp"

One counter-example is the TV-B-gone kit that Adafruit (and presumably others) sell. The code does all of the work in the setup function, and then tells the processor to turn itself off. Pressing the button, turns on the power (briefly), it sends out the pulses to mimic a lot of controllers, and then turns itself off. I suspect the number of programs that do this is rather small.

Whoa thats amazing, but how is that possible? Shouldn't the compiler complain that there are 2 functions with the same signature?

Now that makes more sense. I didn't know what kind of compiler was the IDE using, so I assumed a very primitive one. Glad to see I was wrong.

Isn't there a way of waiting/sleeping but at the same time ensuring interrupts are handled? What I don't want is to busy-wait with no reason.

Thanks for the info!

What I don't want is to busy-wait with no reason.

What else did you have in mind?

AWOL:

What I don't want is to busy-wait with no reason.

What else did you have in mind?

I'd like to save as much battery as possible while waiting for incoming interrupts.

You can go into power down sleep mode, use an interrupt to wake up and do something, then go back into sleep mode.

The files you seek are in the arduino folders installed as part of the IDE, look around a little.

If you want to save battery, use a promini with no USB/Serial chip, power it via the VCC pin, remove the power LED and the regulator.

Or build up an ardweeny and leave those parts off.

buffer_overfly:
I'm fine with the setup, but having to loop always is kind of a waste. For instance, it would be nice if I could write a sketch where there are only interrupt handlers and no loop is needed.

I think that you are looking for this:

Event-Driven Programming for Arduino

buffer_overfly:
Now that makes more sense. I didn't know what kind of compiler was the IDE using, so I assumed a very primitive one. Glad to see I was wrong.

The IDE uses avr-gcc. On my system (Windows), it's version 4.3.2. It's not the absolute latest (e.g. no C++11 extensions), but it's no slouch either.

MichaelMeissner:
One counter-example is the TV-B-gone kit that Adafruit (and presumably others) sell. The code does all of the work in the setup function, and then tells the processor to turn itself off. Pressing the button, turns on the power (briefly), it sends out the pulses to mimic a lot of controllers, and then turns itself off. I suspect the number of programs that do this is rather small.

Even then, you still have to have a loop, even if it is just while(1);. If you don't the program will end and the processor reset (or worse, keep incrementing through random segments of code).

What you do is put inside the main loop a statement which instructs the processor to go into power down or sleep mode. Then your interrupt (e.g. button) wakes the processor up, executes the ISR that was called by the interrupt event. Once the ISR exits, the program returns to the loop in which it meets the statement which puts it into power down mode. The cycle repeats.

Sleep -> Interrupt -> ISR -> Sleep

Notice the loop?

I've attached one of my programs as an example of both of these (using my own main() function) and using power down mode and an interrupt source to wake back up.
This code is for a dice which you have a button attached to INT0 of an ATTiny45. When you press the button, it will trigger a level interrupt which will wake the ATTiny from power down mode. While you are holding the button the dice will keep counting through an array of random numbers. When you release the button, it will display the number for ~4seconds (using the watchdog timer as a 4 second timer), and then return to power down mode.
In the actual project I added circuitry to convert a noise signal from a ball bearing shake sensor into a high for no shake and a low for shaking. That way you can simply shake the dice and it will display a new number on 7 LEDs arranged in a dice face.
The whole circuit was designed to draw ~1mA when displaying a number and ~2uA when in power down mode (that includes all external circuitry - dual comparator, RC filters, shake sensor pullup resistor etc.). It can be run off a coin cell and would last around 10 years if not shaken.


P.S.
It would be very bad to put the sleep code at the end of the ISR routines as you would have to reenable interrupts inside the ISR at the end just before you called sleep. Next ISR request will do the same until you eventually have a stack overflow from so many nestled function calls.

TinyDice.zip (5.9 KB)

buffer_overfly:
I'd like to save as much battery as possible while waiting for incoming interrupts.

However that is nothing to do with breaking out of the main loop. You need to go to sleep, wake up, and handle interrupts appropriately.

Depending on what you have connected (and if you need to wake up periodically) you can get current consumption to below 1 µA.