Using serial event

Hello,
I am trying to implement a program that responds to serial events. I would like to be able to serve serial events that raise up during the time that the previous serial event is serving.
For example my controller is waiting for a serial event, when the serial event raise up it starts to move a stepper motor (changing states - delay - changing states - delay etc), if during the movement of stepper motor a new serial event occurs I would like to send back that the stepper motor is working but it seems that is not possible to serve a new serial event while I am serving the old one.

Is this possible?

this the serialEvent() function:

void serialEvent()
{
  //Read everything in buffer
  String buffer;
  buffer = read_buffer();
  char inChar = buffer[0];
    
  
  /*COMMAND: 'a'*/
  /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  if(inChar == 'a')
  {
    if(sendSensorStates() <= 0)
    {
      //message not sent
      //try again
      if(sendSensorStates() <= 0)
      {
        //message not sent again, send error
        Serial.println("Error 1");
      }
    }
  }
  /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  
  /*COMMAND: 'b'*/
  /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/  
  if(inChar == 'b')
  {
    //Send device identify string
    //Serial.println(recognizeString);
    Serial.println(recognizeString);
  }    
  /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  
  /*COMMAND: 'c'*/
  /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/  
  if(inChar == 'c')
  {
    int nProblem = 0;
    //MOVE to home position
    while(true)
    {
      
      if(digitalRead(optSensorBack) == 0)
      {
        stepsCount = 0;
        break;
      }
      if(stepsCount > maxSteps)
      {
        nProblem = 1;
        break;
      }
      moveStepper(STEPS, BACKWARD);
      stepsCount++;
    }
    if(nProblem == 0)
    {
      Serial.write("Moved to home position.");
    }
    else
    {
      Serial.write("Stepper did maximum steps but still home position was not reached.");
    }
  }
  /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 

  /*COMMAND: 'd'*/
  /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/  
  if(inChar == 'd')
  {
    //MOVE to print position
    int nProblem = 0;
    while(true)
    {
      
      if(digitalRead(optSensorFront) == 1)
      {
        stepsCount = 0;
        break;
      }
      if(stepsCount > maxSteps)
      {
        nProblem = 1;
        break;
      }
      moveStepper(STEPS,FORWARD);
      stepsCount++;
    }
    if(nProblem == 0)
    {
      Serial.write("Moved to print position.");
    }
    else
    {
      Serial.write("Stepper did maximum steps but still print position was not reached.");
    }
  }
  /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/  
 
  /*COMMAND: 'e'*/
  /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/  
  if(inChar == 'e')
  {
    //Expecting string format: e-f-50 --> move forward 50 steps
    //e-b-70 --> move backward 70 steps
    int stepsCount = 0;
    int nProblem = 0;
    
    //exctract number of steps
    int steps = return_int_from_string(buffer);
    
    if(buffer[2] == 'f')
    {
      //run forward
      while(stepsCount < steps)
      {
        
        if(digitalRead(optSensorFront) == 1)
        {
          stepsCount = 0;
          break;
        }
        if(stepsCount > maxSteps)
        {
          nProblem = 1;
          break;
        }
        moveStepper(1,FORWARD);
        stepsCount++;
      }
      if(nProblem == 0)
      {
        Serial.println("Stepper moved forward ");
        Serial.println(steps, DEC);
        Serial.println(" steps.");
      }
      else
      {
        Serial.println("Stepper moved forward maximum steps:");
        Serial.println(stepsCount, DEC);
        Serial.println(" steps.");
      }
    }
    if(buffer[2] == 'b')
    {
      //run backwords
      while(stepsCount < steps)
      {
        
        if(digitalRead(optSensorBack) == 0)
        {
          stepsCount = 0;
          break;
        }
        if(stepsCount > maxSteps)
        {
          nProblem = 1;
          break;
        }
        moveStepper(1,BACKWARD);
        stepsCount++;
      }
      if(nProblem == 0)
      {
        Serial.println("Stepper moved backward ");
        Serial.println(steps, DEC);
        Serial.println(" steps.");
      }
      else
      {
        Serial.println("Stepper moved backward maximum steps:");
        Serial.println(stepsCount, DEC);
        Serial.println(" steps.");
      }
    }
  }
  /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
if(inChar == 'c')
  {
    int nProblem = 0;
    //MOVE to home position
    while(true)
    {
      
      if(digitalRead(optSensorBack) == 0)
      {
        stepsCount = 0;
        break;
      }
      if(stepsCount > maxSteps)
      {
        nProblem = 1;
        break;
      }
      moveStepper(STEPS, BACKWARD);
      stepsCount++;
    }
    if(nProblem == 0)
    {
      Serial.write("Moved to home position.");
    }
    else
    {
      Serial.write("Stepper did maximum steps but still home position was not reached.");
    }
  }

Your problem is in blocks like these. This bit blocks the rest of the program until one of those conditions is satisfied and the while loop gets broken. If that takes 3 milliseconds or 3 years, nothing else is happening here. You've trapped it in that loop.

If you want to be able to respond to things while something else is happening then you need to think differently about programming. Instead of writing a block to get stuck in the takes a job from start to finish, think instead about setting a state that makes sure a certain function gets called that will make incremental progress on the job.

Think about your while loop. There's no reason why that can't exit, turn control back over to loop long enough to check for a serial event, and then re-enter and do its next iteration. Well, if you write it smart there's no reason it shouldn't be able to do that.

Google up "finite state machine" and see if you don't get some ideas.

Hello Delta_G,
An event in arduino is served as an interrupt for processor? If this is true there is no reason for the processor to stop the while loop serve the interrupt (offcourse it depends of how big is the interrupt stack for arduino processor) and then return back to while loop.

serialEvent() is a very unfortunate choice of name. It is exactly equivalent to this code

void loop() {
  // other stuff
  if (Serial.available() > 0) {
     mySerialEvent()
  }
}

void mySerialEvent() {
   // code to deal with serial data
}

In my view you are better off not using serialEvent() and just handling serial input in your own function and at your own time. There are three different examples of simple reliable non-blocking code in serial input basics. One of them will probably be suitable.

Another option, if the stepper motor timing is very critical, is to ensure that no data that is received is longer than 64 bytes (so that it all fits in the input buffer). Then you can read the data at leisure when the stepper move is finished and when you have read the data you can send a request for the next piece of data.

...R

An event in arduino is served as an interrupt for processor?

No. Only you understand what "an event" is. The Arduino doesn't, and we don't.

The arrival of serial data is NOT an event.

offcourse it depends of how big is the interrupt stack for arduino processor

One per type of interrupt. That is why interrupt handlers need to be fast - so that aren't farting around when the next interrupt, of any type, happens.

Hello guys,
Thank you all for your help. From your response I know now that i cant use serial event function as an interrupt. So its not possible to send the current state of arduino (for example stepper motor is now moving)

So its not possible to send the current state of arduino (for example stepper motor is now moving)

Why do you think that?

lepass_7:
From your response I know now that i cant use serial event function as an interrupt.

So its not possible to send the current state of arduino (for example stepper motor is now moving)

This is a non-sequitur

...R