Executing an independent function whilst a switch case's code is running?

Hey guys,

I'm currently using switch case statements to execute various sequences of events, however, I was wondering if it's possible to execute a separate function (each time a button is pressed), whilst still running the switch case statement.

For example, if I had my switch statement running a Nema 23, along with 2 Nema 17's, and 2 regular 24v DC Motors, and I wanted to turn my 3rd Nema 17 stepper motor a certain number of revolutions and then stop, whilst the switch statement is still running. Is this possible? I'm thinking the switch case via serial monitor may not be the best solution long term for me.

I would truly appreciate any input.

I'm currently using Serial Monitor to input commands to run the corresponding switch cases.

Hardware:
Arduino Mega 2560
3 Nema 17, and 1 Nema 23 stepper motors
2 24v 5500 RPM Brushless DC Motors with 4kgf.cm of holding torque

Thank you for your time. :slight_smile:

Not sure what you mean.

If you mean, can you call a function from within a case, then yes. The function will run and return to the case where it was called.

Maybe post some code that helps us know what you are trying to do.

paulsamaroo:
whilst still running the switch case statement.

A SWITCH CASE does not run, it just makes a decision.

Maybe have a look at how the code is organized in Several Things at a Time

Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.

...R

switch/case is a means of causing a selected part of your code to execute when a certain condition is true. As long as the code being executed is non blocking then when the switch/case ends other code not associated with it can be executed

Note that in order for this to work it is crucial none of the code in the sketch should block the free running of the loop() function so that switch/case is entered frequently

The program should not spend a lot of time in the switch structure, a few milliseconds at most if you are writing non-blocking code. The loop() should repeat 100s of times per second. So you poll the button switch and and run your switch structure each time through loop. See the several things at a time tutorial.
Non-blocking timing tutorials:
Several things at a time.
Beginner's guide to millis().
Blink without delay().

It rather depends whether you are running time consuming code in your switch - especially delay. If so, getting a timely action when a button is pressed is tricky unless you have multiple threads or cores.

Thank you everyone for your responses. For ease of reference, and so that we can all be on the same page, I have added my code in the Original Post.

Currently, the way how my code is structured, I can execute case "c" to adjust height, but in order to do that, I will have to cause case "a" to stop.

UKHeliBob:
switch/case is a means of causing a selected part of your code to execute when a certain condition is true. As long as the code being executed is non blocking then when the switch/case ends other code not associated with it can be executed

Note that in order for this to work it is crucial none of the code in the sketch should block the free running of the loop() function so that switch/case is entered frequently

I don't think that I have any code that blocks the free running of the loop() function here. :slight_smile: However, if I do, please feel free to enlighten me.

EDIT: okay...seems like it's not allowing me to post the code...as it exceeds the maximum number of characters allowed.

the way how my code is structured, I can execute case "c" to adjust height, but in order to do that, I will have to cause case "a" to stop.

The whole point of switch/case is that only the code for one case runs at a time, so if you need to do 2 things at the same time then do not make them dependent on the same switch/case

UKHeliBob:
The whole point of switch/case is that only the code for one case runs at a time, so if you need to do 2 things at the same time then do not make them dependent on the same switch/case

Okay, but is it actually possible for the independent function to be executed using the same serial monitor?

Okay, but is it actually possible for the independent function to be executed using the same serial monitor?

Yes. If the code you have written is non blocking, your code can read from the monitor when you break from the switch statements.

paulsamaroo:
Okay, but is it actually possible for the independent function to be executed using the same serial monitor?

You are not making much sense

If you want the program to react to different commands entered through the Serial monitor (is that what you want to do ?) then the answer is yes, of course. Read the serial input when it becomes available, parse the input and act on it

Remember, no blocking code unless you want your sketch to come to a halt waiting for input

paulsamaroo:
Okay, but is it actually possible for the independent function to be executed using the same serial monitor?

It is hard for me to understand what you mean by " executed using the same serial monitor". Technically unless you have more than one processor you cannot do more than one thing at once. However it has always been the case that if your code doesn't block you can handle more than one operation in series during your loop() processing which is almost always sufficient to meet the timing needs of most applications. Study the following tutorials and you will get my meaning:

Arduino Multiple Things

Several Things at a Time

UKHeliBob:
You are not making much sense

If you want the program to react to different commands entered through the Serial monitor (is that what you want to do ?) then the answer is yes, of course. Read the serial input when it becomes available, parse the input and act on it

Remember, no blocking code unless you want your sketch to come to a halt waiting for input

Please see code below for reference. I would like to run function moveMotor2(); each time I enter "b" in the serial monitor.

void loop(){

    if(Serial.available() > 0){
       state = Serial.read();
    }

    switch (state) {
       case 'a':
       stepper1.setMaxSpeed(5000);
       stepper1.setAcceleration(5000);
       moveMotor2();
       stepper1.move(stepper1.currentPosition() + 5000);

       break;
    }
     
     stepper1.run();
}

      void moveMotor2(){
      if(state == 'b'){
          *move motor*
      } 
}

That isn't going to work, is it ?

Suppose that you enter 'a'. state is set to 'a' and the program executes the code including the call to moveMotor2(). In moveMotor() what are the chances of state equalling 'b' ?

You probably want something more like this

void loop()
{
  if (Serial.available() > 0)
  {
    state = Serial.read();
  }
  switch (state)
  {
    case 'a':
      stepper1.setMaxSpeed(5000);
      stepper1.setAcceleration(5000);
      stepper1.move(stepper1.currentPosition() + 5000);
      break;
    case 'b':
      moveMotor2();
      break;
  }
  stepper1.run();
}

void moveMotor2()
{
  *move motor*
}

UKHeliBob:
That isn't going to work, is it ?

Suppose that you enter 'a'. state is set to 'a' and the program executes the code including the call to moveMotor2(). In moveMotor() what are the chances of state equalling 'b' ?

You probably want something more like this

void loop()

{
 if (Serial.available() > 0)
 {
   state = Serial.read();
 }
 switch (state)
 {
   case 'a':
     stepper1.setMaxSpeed(5000);
     stepper1.setAcceleration(5000);
     stepper1.move(stepper1.currentPosition() + 5000);
     break;
   case 'b':
     moveMotor2();
     break;
 }
 stepper1.run();
}

void moveMotor2()
{
 move motor
}

right...but if I enter 'b' in Serial Monitor, wouldn't that then stop the code that's constantly running in case 'a'? Reason why I ask, is because that's what I've tried before lol. :slight_smile:

if I enter 'b' in Serial Monitor, wouldn't that then stop the code that's constantly running in case 'a'?

Yes. Whether that is a problem depends on the code for case 'a'. I think that it is time for you to explain what you want to happen

UKHeliBob:
Yes. Whether that is a problem depends on the code for case 'a'. I think that it is time for you to explain what you want to happen

Okay, so in case 'a', I have 4 separate motors running simultaneously. The goal is to have a 5th motor operate only when a command is entered, in parallel with the initial 4 motors.

case 'a': //Faster Oscillation and Ball Shoot Speed
      Serial.print("Initiating Pro Mode");
      ballHopperStepper.setMaxSpeed(5000);
      ballHopperStepper.setAcceleration(5000);
      oscillateFunctionPro();
      ballHopperStepper.move(ballHopperStepper.currentPosition() + 5000);

      pwm_value1 = 250;
      pwm_value2 = 250;

      break;

oscillateFunctionPro();

void oscillateFunctionPro() {
  unsigned long currentTime = millis();
  switch (oscState) {
    case OSC_ROTATE_LEFT:
      // moving left, see if we are done
      if (oscillationStepper.distanceToGo() == 0) {
        // we are done moving, transition to waiting
        oscState = OSC_PAUSE;
        oscStateBegin = currentTime;
      }
      break;

    case OSC_PAUSE:
      // waiting before moving again
      if (currentTime - oscStateBegin >= oscProDelayDuration ) {
        // we are done waiting, move again
        if ( oscDirection == OSC_ROTATE_LEFT ) {
          oscDirection = OSC_ROTATE_RIGHT;
          oscillationStepper.move(1500);
          Serial.print("Rotate Right: ");
          Serial.println(oscillationStepper.currentPosition());
        }
        else {
          oscDirection = OSC_ROTATE_LEFT;
          oscillationStepper.move(-1500);
          Serial.print("Rotate Left: ");
          Serial.println(oscillationStepper.currentPosition());
        }
        oscStateBegin = currentTime;
      }

      break;

    case OSC_ROTATE_RIGHT:
      // moving right, see if we are done
      if (oscillationStepper.distanceToGo() == 0) {
        // we are done moving, transition to waiting
        oscState = OSC_PAUSE;
        oscStateBegin = currentTime;
      }
      break;
  }

}

Look at the code that you posted. It is not very easy to follow with all of that color crap. Can you post code without the color crap?

groundFungus:
Look at the code that you posted. It is not very easy to follow with all of that color crap. Can you post code without the color crap?

yea I fixed it. Sorry about that; idk why it's automatically posting like that.

idk why it’s automatically posting like that.

My bet is that you have the WYSIWYG option turned on for replies, and you pasted code into a code block. It looks OK but when you review or post it the spurious color tags are added

I only worked out what caused the problem yesterday having seen it a few times and I have opened a problem report for it on GitHub. If you have the option turned on I suggest that you turn it off