Jumping back to "void loop();"?

Is it possible to go back the beginning of the sketch, using the statement "void Loop;" in the middle of a sketch?

I cannot get the following to do what I want or expect it to do.

The code between the void loop() statement and the if statement includes reading an input- valueA. The code in the voidSomething Else() will make valueB equal to valueA. Once this is done, with valueB equal to valueA, I want to go back to the void loop() statement and watch for the next input change to valueA.

void loop()
{
(some code here, including reading valueA...)
}
if(valueA == valueB)

void loop(); //since valueA is equal to valueB, restart the main loop again, waiting for a change in valueA

else

void somethingElse; // valueA does not equal to valueB; therefore valueA has been changed; go to somethingElse below, and do something to make them equal, and then go to void loop()

It appears that the IF statement is being operated on, but the jumping to the void loop() does not happen, even when I change the sketch to
if(valueA == valueA)
to force a return.

Have I missed something? Is there something I am not understanding? Thank you.

You can always rely on,
return;
to take you back to the start of the loop function.

i don't see why you have to exit the loop to begin with...

void loop() {

some code and read A

if (a!=b) {

somethingelse();
}

}

void somethingelse() {
a =b;
}

does the same thing your doing, i think

The below compiles: you can call loop() from loop() but your syntax is wrong.... you don't use the word void in the call. I'm not sure how the coding gurus will respond to such recursion though.

void setup() {
}

void loop() {
  loop();
}

LarryD:
You can always rely on,
return;
to take you back to the start of the loop function.

Return takes you back to calling function doesn't it? Not sure what's calling loop()- the invisible main()?

I didn't quite follow the logic of what the OP's trying to do, but I'm sure it can be handled by better logic as Qds shows.

JimboZA:
The below compiles: you can call loop() from loop() but your syntax is wrong.... you don't use the word void in the call. I'm not sure how the coding gurus will respond to such recursion though.

void setup() {

}

void loop() {
  loop();
}

Every time you call a function, a return address is pushed onto a stack, which is popped back off by the return (if you call a function with arguments, those too are pushed onto the stack as well). Since you never pop that address off the stack in your example, I would think the above would clobber it in a short order on the Arduino (causing it to lock up or something), but I haven't tried it.

JimboZA:
Return takes you back to calling function doesn't it? Not sure what's calling loop()- the invisible main()?

Yes - there is a main() function that is generated as part of the source before compilation that looks something like:

int main(void) {
  init();

  setup();

  for (;;) {
    loop();
  }
}

Thanks for comments.
I have written a very short sketch to try out my ideas, and illustrate perhaps more clearly what I am wanting to achieve:

void setup()
{
   Serial.begin(9600);
}
void loop()
{
  delay(2000);
  Serial.print("at loop");  
  Serial.println();
  delay(2000);
  
 void restart();
 {
  Serial.print("at start");
        Serial.println();
        delay(2000);
 
    void restart();
 }    
    Serial.print("after start");
    Serial.println();  
    delay(2000);
}

On the serial monitor, I wanted to see:

"at loop"
"at start"
"at start"
"at start"
etc

But instead I saw:
"at loop"
"at start"
"after start"
"at loop"
"at start"
"after start"
etc

Suggestions would be appreciated.

The Arduino reference shows a "goto" function- which, although described as being not generally acceptable, should fix my difficulty, but I am not sure how to use it. Thank you.

Looks like you're trying to define restart and call it at the same time, the ";" on the end of the first one means it declares it but there's nothing inside.

Rather declare restart right at the bottom, below the closing "}" of loop(). Inside restart, where you cal itself, lose the word "void" because that's for when you declare a function, not call it.

void setup(){}

void loop()
{
//call restart here....
}

void restart(){
//do stuff including calling restart
}

What part of:-

JimboZA:
you don't use the word void in the call.

Are you having difficulty with?

You are totally off beam here. If you think you want to do this then you have not got the idea of program flow in your head.

The Arduino reference shows a "goto" function- which, although described as being not generally acceptable, should fix my difficulty, but I am not sure how to use it

If you don't know how to use goto then you don't need to. The only reason for using it is in some very advanced and obscure coding, for a beginner like you and 99.999999% of programs it is wrong.

This is an X/Y problem. http://xyproblem.info/
Tell us what you actually want to do.
What ever it is it will not involve tricks like you are trying to pull.

Grumpy_Mike:
What ever it is it will not involve tricks like you are trying to pull.

Agree completely. It would be hard to over-emphasize that.

...R

@gerrymcc

Post your code.

http://snippets-r-us.com/

I have been trying to minimise the effort from other good people, but...
I am an RF and microwave engineer, not a programmer. I have done some programming- beginning with Fortran and Hollerith cards, and progressing. I look after an RF measurement lab.
I have built a box with some microwave RF switches to help in my work. To change the overal signal path through the box, several RF switches have to be set.
The RF switches are set using either a front panel rotary switch, or via the Arduino USB port. A front panel toggle switch determines manual or USB control. In either case, LEDs on the box indicate the present position of the RF switches. When in USB mode, the computer driving the box also needs to know the present position of the RF switches.
In manual mode, I read the rotary switch position (2 bits) to decode the setting and generate a setting code to set the RF switches in the setting positions required for the chosen signal path.
In USB mode, the number sent from the computer represents the desired microwave position. This is converted into the same setting code to set the RF switches in the required positions.
Having set the RF switches, I then read their internal position indicators and generate a current position code. This then generates a number made available via the USB port to the controlling computer. It is also used to set the LEDs indicating the present switch positions and hence the present signal path.
In operation:
I need to run around a small loop checking for any input changes- firstly, a change from manual to USB control, or vice-versa. Then, if this is unchanged, I need to check if the present RF switch position code matches the last setting code. If it does, then I go round this small loop again. If there has been a change, I then need to go back to the beginning of the setting procedure again- reading the new required position, determine the new setting code, setting the switches, reading the indicators, setting the LEDs and generating the new current position code. This will be used next time around the top, small loop.
My present problem:
Determining USB or front panel manual control is the first task after the 'void Loop' statement. I can compare the last setting code with the present position code, but I do not know how to essentially go right back to the beginning and start the whole process again. I am looking for help with the Arduino Goto..Return type statements.
I have the box and sketch working in manual control and I have had it working with USB control and reading back, using the Serial Monoitor. The structure is clumsy and not totally satisfactory, and I am looking to tidy it up.

I have never done any C/C++ coding. I do not know the structure or the language or key words of C/C++. I do not comprehensively understand the meaning of the curley brackets used so extensively. The several books I have bought on Arduno projects do not address some of the questions and issues I have.

My present code is posted in my next reply

Here is my present code. I can control the switches manually, and I can use the Serial Monitor to set the switches in Remote.
Unfortunately, including all the explanatory comments above the code exceeds the allowable number of characters.

 */
 //  I/O pins and their pin names
 int switch_A = 2; // TTL output to RF switch A, HIGH = Port 2 connected, LOW = Ports 2 or 3
 int switch_B1 = 3;  // TTL output to RF switch B, LOW (HIGH)= Port 3 connected;
                     //switchB_A and switchB_B are to tbe complementary
 int switch_B2 = 4;  // TTL output to RF switch B, (HIGH) LOW= Port 4 connected
                     //switchB_A and switchB_B are to tbe complementary
 int ledPort2 = 5;  //TTL output to LED for RF port 2
 int ledPort3 = 6;  //TTL output to LED for RF port 3
 int ledPort4 = 7;  //TTL output to LED for RF port 4
 int ledLocRem = 8;  //TTL output to LED for LOC/REM indication; LOW = remote
 int rfAposnInd = 9;  //TTL input from RF switch A indicator
 int rfBposnInd = 10;  //TTL input from RF switch B indicator
 int locRemsw = 11;  //TTL input from Local/Remote switch
 int manSw0 = 12;  //TTL input Bit 0 from front panel manual switch
 int manSw1 = 13;  //TTL input Bit 1 from front panel manual switch
 
 //  Defining required variables
 byte locRemswVal = HIGH;  // seting intial value of Loc/Rem switch
 byte manSw0Val = LOW, manSw1Val = LOW;  // seting intial values of manual switch, bits 0 & 1 
 int rfAposnIndVal =0, rfBposnIndVal = 0 ;  // setting intial values of RF switch A & B  indicators
 int manualSwitchComposite = 0; //defining composite value of man switche0 value- 0, 1 or 2
 int switchSettingPortValue = 22; //integer, from manual or USB, which determines which RF switches have been set.  22 = Port 2 etc
 int rfSwCompVal = 0; //composite value of two switch position indicators, for ATMS to use only
 int remoteSwSet = 0; // Value of remote input (0, 1, 2) frin USB port to set switches
 int switchPortVal = 0; //new value of switch setting value to give more logical values
 int currentlySetPort = 0; // value of this read of manual switch setting in Local mod, to check if switch has changed next loop
 int currentPortVal = 55; //initial value of value for ATMS to read to know present port

 //
 void setup()
 {
 
  // defining TTL ouptut pins 
   pinMode(switch_A, OUTPUT); // TTL output to RF switch A
   pinMode(switch_B1, OUTPUT);  // TTL output to RF switch B1
   pinMode(switch_B2, OUTPUT);  // TTL output to RF switch B2
   pinMode(ledPort2, OUTPUT);  //TTL output to LED for RF port 2
   pinMode(ledPort3, OUTPUT);  //TTL output to LED for RF port 3
   pinMode(ledPort4, OUTPUT);  //TTL output to LED for RF port 4
   pinMode(ledLocRem, OUTPUT);  //TTL output to LED for LOC/REM indication
  // setting internal pull-ups for TTL inputs
   digitalWrite(rfAposnInd, HIGH);  //TTL input from RF switch A indicator
   digitalWrite(rfBposnInd, HIGH);  //TTL input from RF switch B indicator
   digitalWrite(locRemsw, HIGH);  //TTL input from Local/Remote switch; HIGH = Local
   digitalWrite(manSw0, HIGH);  //TTL Bit 0 input from front panel manual 2 pole 3 posn switch
   digitalWrite(manSw1, HIGH);  //TTL Bit 1 input from front panel manual 2 pole 3 posn switch
   //
   // Set RF switches, LEDS to Port 2 to begin.
   //
    
    digitalWrite(switch_A, HIGH); //  Set RF switches- switch A set HIGH
    digitalWrite(switch_B1, LOW); // Set RF switches- switch B1 set LOW
    digitalWrite(switch_B2, HIGH); // Set RF switches- switch B2 set HIGH
     delay (200);
    digitalWrite(ledPort2, HIGH);
    digitalWrite(ledPort3, LOW);
    digitalWrite(ledPort4, LOW);
    Serial.begin(9600);
}

void loop()
{
   locRemswVal = digitalRead(locRemsw);
    if (locRemswVal == LOW)  // read local/remote switch on front panel;
    {
      // in local mode, so read manual switch
    digitalWrite(ledLocRem, LOW); // set ledLocRem low, turning off led, indicating local mode
    manSw1Val = digitalRead(manSw1);  //read value of second bit of front panel manual switch, D13
    manSw0Val = digitalRead(manSw0);  //read value of second bit of front panel manual switch
    manSw1Val = manSw1Val << 1;  //shift this read bit one place to the left, but retain name
    manualSwitchComposite = manSw0Val + manSw1Val;  //combine value of two switch inputs into one 2 bit byte
   
     if (manualSwitchComposite == 2)  //  Port 4; D12 = 0; D13 = 1
     {
      switchPortVal = 444;
      }
    else if (manualSwitchComposite == 1)  // Port 2; D12 = 1; D13 = 0
      {
      switchPortVal = 222;
      }
    else  //switchSettingVal == 0, by default)
      {
      switchPortVal = 333; // Port 3; D12 = 0; D13 = 0
      ///
      }
      if(switchPortVal == currentlySetPort) //no change in manual switch setting since last loop
     {
      void loop();
      }
      else
      {
      void setSwitchesLeds();
      }
    } 
  // now in Remote mode
   else
    {
     digitalWrite(ledLocRem, HIGH); // set ledLocRem high, turning oon led, indicating remote mode
    //
    delay(100);
   
    if (Serial.available() == 0)
    {
    void loop();
    }
    else 
    {
    remoteSwSet = Serial.read();
    remoteSwSet = (remoteSwSet - 48); // converting ASCII to number
    //Serial.print(remoteSwSet);
  //Serial.println();
      if (remoteSwSet == 2)
      {
        switchPortVal = 222;
      }
       else if (remoteSwSet == 3)
      {
      switchPortVal = 333;
      }
      else
      {
      switchPortVal = 444;
      }
    }
    }
  
    // setSwitches is a function to set the switches

  void setSwitchesLeds();  //setting the RF switch positions; depends on value of switchSettingVal
    
    if(currentlySetPort == switchSettingPortValue)  //present port selected = currently requested port
    {
     
     void loop();  //no need to do anything, so go back the beginning of loop
    }
     
      if (switchPortVal == 222)  //  Switch setting = 1, 1-0, Port 2 is selected from front panel or USB- set switches
      {
      digitalWrite(switch_A, HIGH); //  Set RF switches- switch A set HIGH
      digitalWrite(switch_B1, LOW); // Set RF switches- switch B1 set LOW
      digitalWrite(switch_B2, HIGH); // Set RF switches- switch B2 set HIGH
      }
      if (switchPortVal == 333)  //  Switch setting = 1, 0-1, Port 3 is selected from front panel or USB- set switches
      {
      digitalWrite(switch_A, LOW);  // Set RF switches- switch A set LOW
      digitalWrite(switch_B1, LOW); // Set RF switches- switch B1 set HIGH
      digitalWrite(switch_B2, HIGH); // Set RF switches- switch B2 set LOW
      }
      if (switchPortVal == 444)  //Switch setting = 0, 0-0, Port 4 is selected from front panel or USB- set switches
      {
      digitalWrite(switch_A, LOW); //  Set RF switches- switch A set LOW
      digitalWrite(switch_B1, HIGH); //  Set RF switches- switch B1 set LOW
      digitalWrite(switch_B2, LOW); //  Set RF switches- switch B2 set HIGH
      }
  
    delay (50);
  
    // Reading actual positions of RF switches to confirm setting
  
    rfAposnIndVal = digitalRead(rfAposnInd);  //read position indicator of switch A
    rfBposnIndVal = digitalRead(rfBposnInd);  //read position indicator of switch B
    
  if (rfAposnIndVal == HIGH)  // if switch A indicator is HIGH, this can only mean that Port 2 is selected, so set LEDs
  {
     digitalWrite(ledPort2, HIGH);
     digitalWrite(ledPort3, LOW);
     digitalWrite(ledPort4, LOW);
     currentlySetPort = 222;
     currentPortVal = 22;
  }
  if (rfAposnIndVal == LOW && rfBposnIndVal == LOW)  //if switch A is LOW and Switch B is HIGH, this means Port 3 is selected- set LEDs
  {
     digitalWrite(ledPort2, LOW);
     digitalWrite(ledPort3, HIGH);
     digitalWrite(ledPort4, LOW);
     currentlySetPort = 333;
     currentPortVal = 33;
  }
 if (rfAposnIndVal == LOW && rfBposnIndVal == HIGH)  //if switch A is LOW and Switch B is LOW, this means Port 4 is selected- set LEDs
   {
     digitalWrite(ledPort2, LOW);
     digitalWrite(ledPort3, LOW);
     digitalWrite(ledPort4, HIGH);
     currentlySetPort = 444;
     currentPortVal = 44;
   }
   }

Firstly break up that massive loop() function, its never easy to work with monolithic
chunks of code like that, our brains have a small scratchpad memory that won't function
efficiently if overloaded - we can only think about 1 or 2 things at once, basically, so
code functions that only do one of two things:

void loop ()
{
  if (digitalRead(locRemsw) == LOW)  // read local/remote switch on front panel
    handle_manual_switch () ;
  else
    handle_remote_mode () ;
}

void handle_manual_switch ()
{ 
   ...
}

void handle_remote_mode ()
{
  ...
}

Once the structure is more clear like this it will be obvious which bit of code has
responsibility for what. For instance:

void handle_remote_mode ()
{
  if (Serial.available() == 0)
    return ;
  remoteSwSet = Serial.read();
  ...
}

Now seems very reasonable - the remote mode processing just returns if there's nothing
to do.

Thank you all for your patience and considerations. As I said, I was trying to minimise the amount of effort from good Forum members. But it back-fired on me.
I will spend some time rewriting the code as MarkT suggested, and see how I go..
This is a learning project for me. My next ptoject is more involved, but there are aspects of what is required in this one, which will also be used for the next project- primarily looping, local and USB control and USB reading of status.
Thank you all..

gerrymcc, from what you say in Reply# 10, this project is a prime candidate for the state machine paradigm.

I think it will stand you in good stead to look at any or all of:

http://www.objectmentor.com/resources/articles/umlfsm.pdf

http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html
http://hacking.majenko.co.uk/finite-state-machine

gerrymcc:
This is a learning project for me.

This Thread planning and implementing a program may have some useful bits.

...R

This is a problem:

 // setSwitches is a function to set the switches

  void setSwitchesLeds();  //setting the RF switch positions; depends on value of switchSettingVal

Firstly, this section is inside the loop function - you're not allowed to define one function inside another in C.

It compiles because of the semicolon on the end - the compiler interprets it as a function prototype, not the start of a function definition.

To fix this and get it to compile at least, delete the semicolon, put a closing brace above that line and an opening brace below. Then look at where you tried to call setSwitches and delete the word void.

if(valueA == valueB)

void loop();

If your code really looks like this you have a syntax misunderstanding. Seeing:

void loop ();

... anywhere in code is a function prototype, not a function declaration. Nor does it call the function.

Just as an example:

void setup ()
  {
  Serial.begin (115200);
  Serial.println ();
  Serial.println ("Starting up");
  }  // end of setup

void loop ()
  {
  if (1 == 1)
    void loop ();
    
  Serial.println ("test");
  delay (1000);
  }  // end of loop

You might expect that to never print "test" because 1 equals 1. However that code prints "test" every second.

Starting up
test
test
test
test
test

If you fix that, you have an even more insidious problem. Try this:

void setup ()
  {
  Serial.begin (115200);
  Serial.println ();
  Serial.println ("Starting up");
  }  // end of setup

void loop ()
  {

  if (1 == 1)
    loop ();
    
  Serial.println ("test");
  delay (1000);
  }  // end of loop

Now I am calling loop if 1 == 1 (which it will) but my output is now:

Star
Star
Star
Star
Star
Star
Star
Star
Star
Star
Star

This is because this is a recursive call: loop calls loop which calls loop which calls loop and so on. Thus the processor runs out of RAM and restarts, printing the "Starting" message again and again.


The simplest thing (which others have suggested) is to simply return. That means you stop executing loop, and start again from the beginning. Thus "test" is never printed.

void setup ()
  {
  Serial.begin (115200);
  Serial.println ();
  Serial.println ("Starting up");
  }  // end of setup

void loop ()
  {
  if (1 == 1)
    return;
    
  Serial.println ("test");
  delay (1000);
  }  // end of loop

However I agree with the other posters that spending time making your code modular (by using more functions) will pay off in the long run, when you hit other problems.