Arduino Mega RESETS after entering in nested switch statements

Hi everyone…
I have a weird case here. I’m using an Arduino mega 2560 to control this prototype machine at my work. The machine has a series of NEMA steppers, and regular DC motors that are controlled through H bridges and DQ542MA drivers, also, some pressure, temperature, and end of race sensors.
Motors are driven by the AccelStepper library.
I made a python desktop application to send commands to the Arduino through serial communication. Then I made a dispatcher in the Arduino to hear those commands and execute them.
The dispatcher is just a function that takes the input command and uses it to enter a switch statement wherein each case is the code that has to be executed. Some of those cases have another switch statement that I use to execute a process (a combination of movements of different motors) step by step.

The problem here is that when I send the command for the first case in the mayor switch (that also has another switch inside) everything goes well, but if I send the command for the second (also with a second switch inside) Arduino resets itself.

I changed the order of the code and always resets in the second, I run the exact same code in an Arduino DUE and it never resets itself, so the problem is not the code.

My suspicion is that it has to be something related to the fact that the Arduino Mega is not the official, is one of those duplicates.

I’m sorry but I’m not allowed to paste the exact same code that I’m using, but here is an example.

const byte numChars = 32;
const char startMarker = '<';
const char endMarker = '>';
char receivedChars[numChars];
char tempChars[numChars];
int inst;
boolean newData  = false;
int inst, prev_inst;
bool debug=false;
int processState=0;
bool doInstruction;

void recvWithStartEndMarkers() {
     static boolean recvInProgress = false;
     static byte ndx = 0;
     char rc;

     while (Serial.available() > 0 && newData == false) {
         rc = Serial.read();

         if (recvInProgress == true) {
             if (rc != endMarker) {
                 receivedChars[ndx] = rc;
                 ndx++;
                 if (ndx >= numChars) {
                     ndx = numChars - 1;
                 }
             }
             else {
                 receivedChars[ndx] = '\0'; // terminate the string
                 recvInProgress = false;
                 ndx = 0;
                 newData = true;
             }
         }

         else if (rc == startMarker) {
             recvInProgress = true;
         }
     }
 }


void parseData() {      // split the data into its parts

      char * strtokIndx; // this is used by strtok() as an index      
      strtokIndx = strtok(tempChars,",");   
      if(strtokIndx != NULL){
        inst = atoi(strtokIndx); 
        if(inst != 2){
          processState=0;  
          prev_inst = inst;          
        }
      }
      else{
        inst = 99;
      }
}

void process_data(const int input_cmmd)
  {
      switch (input_cmmd)
        {
       case 0: 
            switch (processState)
            {     
              case 0:
               // A dummy step to visual check the machine
                if(not debug){processState++; doInstruction=true;}
                break;                
              case 1:
                if(doInstruction){
                  motor1.do_action();
                  doInstruction = false;
                  if(not debug){processState++;doInstruction=true;}                
                }
                break;               
              case 2:
                  if( motor1.done_action() ){
                    if(doInstruction){
                      motor2.do_action();
                      doInstruction = false;                   
                      if(not debug){processState++;doInstruction=true;}
                    }
                  }
                break;
              case 3:
                if( motor2.done_action() ){  
                  if(doInstruction){
                    motor3.do_action();
                    doInstruction = false;
                    if(not debug){processState++;doInstruction=true;}
                  }
                }
              break;
              default:   
                doInstruction = false;           
                break;                                
            }//End states 
            break; 
//---------------------------------------------------------//
         case 1: 
            switch (processState)
            {     
              case 0:
                if(not debug){processState++; doInstruction=true;}
                break;       
              case 1:
                if(doInstruction){
                  motor4.do_action();
                  doInstruction = false;
                  if(not debug){processState++;doInstruction=true;}
                }
                break;                                
              case 2:
                if( motor4.done_action() ){
                  if(doInstruction){
                    motor1.do_action();
                    doInstruction = false;
                    if(not debug){processState++;doInstruction=true;}
                  }                    
                }
                break;           
              case 3:
                  if( motor1.done_action() ){
                    if(doInstruction){
                      motor3.do_action();
                      doInstruction = false;
                      if(not debug){processState++;doInstruction=true;}
                    }
                  }
                break;              
              default:
                doInstruction = false;
                //Finish;
                break;                                   
            }//End states                      
            break; //End Insert Vial

//---------------------------------------------------------//                                  
        case 2:
            processState++;
            doInstruction = true;
            inst = prev_inst;
            break;     
        
        default:
          inst = 99;
          break;
//---------------------------------------------------------//                                  
        }  // end of switch     
  }  //end process data

void setup()
{
  Serial.begin(115200);
}

void loop(){
  recvWithStartEndMarkers();
  if (newData == true) {
      strcpy(tempChars, receivedChars);
      parseData();
      newData = false;
  }
 process_data(inst);
 motor1.run();
 motor2.run();
 motor3.run();
 motor4.run();
}

One of the problems that causes a microcontroller to restart is to exceed the stack capacity.

Hi!, thanks for answer my question so quickly. I'm sorry I should have commented that I measured the free memory with MemoryFree library at several places in the code, like just before and after entering the second switch case, and it always had more than 5 Kb of free memory.

Maybe I didn't do it so well, or the crash happens after my measures. I will read more about what you mention in the stackexchange link.

Thanks!.

Because this can be a software issue, you will need to provide a compilable example that shows the behaviour. Your code is missing includes. Links to libraries are also needed.

Because this can be a hardware issue, you will need to provide a full schematic as well as a list of all the components used.

The subtitle of this forum section is "For problems with Arduino itself, NOT your project".

Lastly, it will be very unlikely that this is due to the fact that you're using a clone. To eliminate, get the schematic of the clone and compare it to the schematic of the original; or easier, buy an original and test.

Hi sterretje, thanks for the reply.
I don't share a compilable example cause the intention was just to exemplify, I don't add all the libraries and code that I made and use because first, I'm not allowed, and second, it was already tested and the only part that is presenting issues is that switch statement, regardless of what is inside of it.

As I said, I already test the code in another official Arduino, I know DUE and MEGA are not the same, but the code runs flawlessly in the Arduino DUE, so I'm not so confident that the root of the problem is software related.

I test the problem disconnecting everything from the Arduino, except the USB connection, and the problem persists, so it not should be related to the electronic that I attached to the Arduino.

With respect to the Arduino clone, at first sight, I can notice that the clone has fewer components over the board, but I will try to find the schematic and compare.

Thanks for your help, is very appreciated.