user20191: I'm struggling with something. My CPU sits in a switch case state machine like this:
switch(expression) {

   case constant-expression_1  :
      statement(s);
      break; /* optional */

   case constant-expression_2  :
      statement(s);
      break; /* optional */

   /* you can have any number of case statements */
   default : /* Optional */
   statement(s);
}

I have an interrupt that occurs on a button press. In the interrupt, I change the switch expression to the case I want to go next, like this:
void ISR(void){
   expression = constant-expression_2;
}

After the interrupt has been handled, I want the CPU to return directly to the case being switched to, and to not continue where it left off.
Does anyone have any good ideas on how to implement this, if it's possible? I'd prefer to not have to wait for the code to finish what was happening in the previous case before going to the one being switched to.
Thanks in advance!

user2881: Most of the time this isn't a problem, because code normally runs pretty fast. The problem, most of the time, is the use of delays. What I did was use my own delay function that checks if the expression has changed, and if so, immediately returns.
Below is my code. I had to modify it a bit, so it might not work out of the box, but will give you the idea as to how.
volatile byte expression;
volatile boolean expressionChanged = false;

switch(expression) {

   case constant-expression_1  :
      statement(s);
      myDelay(1000);
      statement(s);
      break; /* optional */

   case constant-expression_2  :
      statement(s);
      myDelay(500);
      statement(s);
      break; /* optional */

   /* you can have any number of case statements */
   default : /* Optional */
      statement(s);
}

void myDelay(int ms)
{
    uint32_t start = micros();
    while (ms > 0 && !expressionChanged)
    {
        //yield();not implemented in arduino
        if ( (micros() - start) >= 1000)
        {
            ms--;
            start += 1000;
        }
    }   
}

void ISR(void){
   expression = constant-expression_2;
   expressionChanged = true;
}


user10794: First, put your major processing into functions. That looks better anyway. eg.
switch(expression) {

   case constant-expression_1  :
      function1 ();
      break; /* optional */

   case constant-expression_2  :
      function2 ();
      break; /* optional */

   /* you can have any number of case statements */
   default : /* Optional */
      function_default ();
}

Now inside your functions do a return if you notice the expression has changed. This will get you out of any number of nested loops. For your 30 sensors, for example, you can now have a loop.
void function1 ()
  {
  for (int i = 0; i < 30; i++)
    {
    if (expression_changed)
       return;
    // take sensor reading
    }
  }  // end of function1

Also, as Gerben suggested, replace any delay calls with a function that does the delay, however which ends early if the expression changes. It can return a boolean to let you know this happened. eg.
boolean myDelay(int ms)
  {
    uint32_t start = micros();
    while (ms > 0)
    {
        if (expression_changed)
           return true;   // early return
        if ( (micros() - start) >= 1000)
        {
            ms--;
            start += 1000;
        }
    }   
  return false;   // normal return
  }

Now any function that needs delays can use that, like this:
void function2 ()
  {
  do_something ();
  if (myDelay (1000))  
     return;   // bail out
  do_something_else ();
  }  // end of function1


My problem is, one of my cases includes a communication transceiver method, which can take a lot of time to get through

There must be logical spots where you can just test the expression and do a return (preferably cleaning up anything that needs it) when required.

20191: <p>I'm struggling with something. My CPU sits in a switch case state machine like this:</p>

<pre><code>switch(expression) {

   case constant-expression_1  :
      statement(s);
      break; /* optional */

   case constant-expression_2  :
      statement(s);
      break; /* optional */

   /* you can have any number of case statements */
   default : /* Optional */
   statement(s);
}
</code></pre>

<p>I have an interrupt that occurs on a button press. In the interrupt, I change the switch expression to the case I want to go next, like this:</p>

<pre><code>void ISR(void){
   expression = constant-expression_2;
}
</code></pre>

<p>After the interrupt has been handled, I want the CPU to return directly to the case being switched to, and to not continue where it left off.</p>

<p>Does anyone have any good ideas on how to implement this, if it's possible? I'd prefer to not have to wait for the code to finish what was happening in the previous case before going to the one being switched to.</p>

<p>Thanks in advance!</p>
 2881: <p>Most of the time this isn't a problem, because code normally runs pretty fast. The problem, most of the time, is the use of <code>delay</code>s. What I did was use my own delay function that checks if the expression has changed, and if so, immediately returns.</p>

<p>Below is my code. I had to modify it a bit, so it might not work out of the box, but will give you the idea as to how.</p>

<pre><code>volatile byte expression;
volatile boolean expressionChanged = false;

switch(expression) {

   case constant-expression_1  :
      statement(s);
      myDelay(1000);
      statement(s);
      break; /* optional */

   case constant-expression_2  :
      statement(s);
      myDelay(500);
      statement(s);
      break; /* optional */

   /* you can have any number of case statements */
   default : /* Optional */
      statement(s);
}

void myDelay(int ms)
{
    uint32_t start = micros();
    while (ms &gt; 0 &amp;&amp; !expressionChanged)
    {
        //yield();not implemented in arduino
        if ( (micros() - start) &gt;= 1000)
        {
            ms--;
            start += 1000;
        }
    }   
}

void ISR(void){
   expression = constant-expression_2;
   expressionChanged = true;
}
</code></pre>
 10794: 

<p>First, put your major processing into functions. That looks better anyway. eg.</p>

<pre class="lang-C++ prettyprint-override"><code>switch(expression) {

   case constant-expression_1  :
      function1 ();
      break; /* optional */

   case constant-expression_2  :
      function2 ();
      break; /* optional */

   /* you can have any number of case statements */
   default : /* Optional */
      function_default ();
}
</code></pre>

<p>Now inside your functions do a <code>return</code> if you notice the expression has changed. This will get you out of any number of nested loops. For your 30 sensors, for example, you can now have a loop.</p>

<pre class="lang-C++ prettyprint-override"><code>void function1 ()
  {
  for (int i = 0; i &lt; 30; i++)
    {
    if (expression_changed)
       return;
    // take sensor reading
    }
  }  // end of function1
</code></pre>

<p>Also, as Gerben suggested, replace any <code>delay</code> calls with a function that does the delay, however which ends early if the expression changes. It can return a boolean to let you know this happened. eg.</p>

<pre class="lang-C++ prettyprint-override"><code>boolean myDelay(int ms)
  {
    uint32_t start = micros();
    while (ms &gt; 0)
    {
        if (expression_changed)
           return true;   // early return
        if ( (micros() - start) &gt;= 1000)
        {
            ms--;
            start += 1000;
        }
    }   
  return false;   // normal return
  }
</code></pre>

<p>Now any function that needs delays can use that, like this:</p>

<pre class="lang-C++ prettyprint-override"><code>void function2 ()
  {
  do_something ();
  if (myDelay (1000))  
     return;   // bail out
  do_something_else ();
  }  // end of function1
</code></pre>

<blockquote>
  <p>My problem is, one of my cases includes a communication transceiver method, which can take a lot of time to get through</p>
</blockquote>

<p>There must be logical spots where you can just test the expression and do a <code>return</code> (preferably cleaning up anything that needs it) when required.</p>
