Although I did much FORTRAN programming in the 70's & 80's, I've been away from it and am new to C programming. I want to test a condition that is running in void loop() and if that condition is not met, I want to jump back to void setup() where things happen just once, do it's thing and drop back into void loop() again, etc. It would have been easy in FORTRAN to use the Go To, but in C I see it is discouraged, plus apparently in C goto only jumps to a subsequent statement, not a previous section.
In C++ you can call a function (subroutine) to do the procedure that you want setup() to do. So you don't go back to setup(), you call the function. Functions
If you want more help, post the code that you are working on and describe what you want to do in detail.
Thank you for replies so far...yes, subroutines were a staple of FORTRAN. Some of what I have in void setup() certainly could be arranged in their own functions and called when needed using if/else statements.
This question has been answered, but here is an example to add more color.
Instead of writing something like:
void setup() {
// code to do XYZ
}
void loop() {
if (condition) {
setup();
}
}
You may want to write:
void xyz() {
// code to do XYZ
}
void setup() {
xyz();
}
void loop() {
if (condition) {
xyz();
}
}
That is because setup and loop are special functions that are invoked by the system. In terms of best practices, you should never call them explicitly, as that can cause all sorts of issues related to maintainability.
lpasqualis:
That is because setup and loop are special functions that are invoked by the system.
You should never call them explicitly, as that can cause all sorts of issues.
I disagree.
There is nothing special to both functions besides their automatic invocation.
setup() can be called without problems from loop() (if setup() does not call loop()),
loop() can be called without problems from setup() (if loop() does not call setup()).
When calling setup() from setup() or loop() from loop() one has to limit the recursion,
or the stack overflows.
Restarting loop() from loop() can be achieved by a return;.
Once the code has finished in setup() and moved into loop() there is absolutely no reason why setup() cannot be called just like any other function.
Of course it is an entirely different question whether it would make sense to call setup() when one takes account of the code that may be in it. If only part of the code in setup() needs to be run again then the idea of putting that piece of code into a function that could be called from setup() and from elsewhere - as illustrated by @lpasqualis
It says: "The setup function will only run once, after each powerup or reset of the Arduino board."
I know you can call it if you want, and I understand that the documentation refers to the automatic behaviour only, but it is a basic assumption that people make when they write a sketch. Invoking it from elsewhere will cause some grief if anyone other than you (or you two months later) need to maintain that code.
In other words, it is not good practice IMHO. It creates spaghetti code that lead to all sorts of issues.
A very interesting doubt but the necessity to call Setup() seems unnecessary in Most of the situations. If such a scenario exists, then there is something wrong in approach. Setup() as a general programming ethics must be used only to set your working environment and any need to reset at runtime seems illogical.
This is a great question.
Lets look at where the Arduino IDE makes us start
Remember that C starts with main()
int main(void)
{
init();
initVariant();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
there it is how setup and loop are called
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
setup() and loop() are simple calls to functions nothing special
while calling loop() within loop would ultimately crash the uno calling setup has no real detrimental effect. (someone show me if i'm wrong.)
so the answer is you you can call setup again if you really want to.
note that
for(;;){
}
creates an endless loop
Now with that said...
I personally would create a function that setup calls that has has only the code you need for the purpose
Example:
int value;
setup(){
Serial.begin(9600); // should only be triggered once
restart(); // can be triggered multiple times
}
loop(){
if(needsReset){
needsReset = 0;
Restart();
}
value--;
if (Value == 5) needsReset++;
// other code
}
restart(){
value = 99;
}
The thing to clarify is why the OP wants to call setup()? Does she/he expects a full reset (where all things start fresh again, stack, heap, relevant global variables set to 0, etc) which setup() then will NOT do, or just to benefit from some already written initialization code (at the risk of calling twice and wrongly some xxx.begin() and other class initializer that we usually have in setup() too)
For a full reset see #1
For an intellectually satisfying code architecture if it's partial reset then see #6
I want to jump back to void setup() where things happen just once, do it's thing and drop back into void loop() again
So you want it done more than once?
Restructure so that whatever-it-is you want to do is in a function and call that whenever you feel like it. Of course you can call setup whenever you want to, if you want to.
This is an X-Y problem - what is the real problem you want to solve? Calling setup more than once is just your guess at a solution.
Thanks to all for your responses, they have been helpful, except for holmes4... in the 60's and 70's FORTRAN had no such statements such as void setup(), or void loop() so I find your comment not pertinent to the discussion and irrelevant.
Disclaimer: I have never looked at Fortran, just now is the first time.
No, Fortran does not have setup() and loop() unless you wrote them yourself. But Fortran does have functions and setup() and loop() are nothing more than that.
Did you ever write some code in Fortran in the line of
function func1(i) result(j)
integer, intent(in) :: i ! input
integer :: j ! output
j = i**2 + i**3
end function func1
function func2(i) result(j)
integer, intent(in) :: i ! input
integer :: j ! output
j = i**2 + i**3
end function func2
program xfunc
implicit none
integer :: i
integer :: func1
i = 3
print*,"sum of the square and cube of",i," is",func1(i)
go to func2
end program xfunc
You can basically replace func1() by setup and func2() by loop (for this, just forget about the arguments).
I think that holmes4' comment is very valid in relation to your original question.
@timberrock - When i read answers like yours, I wish there was a way to ignore some members forever in the future.
you have quite some nerves distributing good and bad points to contributors looking to help you out. Holmes4 point about functions and code structure was totally relevant - just that you did not get it. It shows that after reading all the comments you still don't get what a function is, what the structure of an arduino sketch is, what's the purpose of setup and loop are.... So YOUR comment is not pertinent, is arrogant and you did not show much intelligence there.
As you did not take a minute to explain your context further and ignored everyone else asks and questions to help you out in your poor contribution to your own thread, I let you enjoy your next misguided comments alone with whomever feels you are worth investing their personal time.
have fun in the forum - remind me to stay out of your threads if by mistake I try to contribute ever again.
Thank you for those that have provided constructive comments to my original query despite limited up-front info. Gives me much to work with for my current and future project. Appreciated and look forward to future associations.
However, as a newb, I find it distressing that there are some "policemen" on this forum that feel it necessary to interject themselves into threads with derogatory rather than constructive comments...perhaps because of their own shortcomings.
Sure - for a good example of a bad cop, loop at post #15
timberrock:
Thanks to all for your responses, they have been helpful, except for holmes4... in the 60's and 70's FORTRAN had no such statements such as void setup(), or void loop() so I find your comment not pertinent to the discussion and irrelevant.
and take the time to self reflect... how was that constructive or thankful for his time.