Arm Mbed and Pelion Device Management support forum

Serial Interrupt only Processes first if statement of handler

Hi all, I am encountering a strange issue with my code. I am designing a state machine in a NUCLEO 410RB, and I am using a NEXTION NX8048T050 touch screen as a GUI for people to set certain parameters to be passed to the state machine.

Now state machine wise, I have not encountered any problems, however, the issue is that when I implement the Serial interrupt handler which consists of a few if statements, only the first if statement is processed. For example, if my code were like this:

void stop_handler(){
  if (readbytes()==OPENED){
        pc.printf("OPEN PRESSED");
  }

  if (readbytes()==CLOSED){
    pc.printf("CLOSE PRESSED");
  }

  
  if (readbytes()==STARTED){
          SPIN_SPD = parameters[0];
          SPIN_DUR = parameters[1];
          MAG_DUR = parameters[2];
          MIX_DUR = parameters[3];
          start_flag = true;
          pc.printf("%d, %d, %d, %d\n", parameters[0], parameters[1], parameters[2], parameters[3]);
          pc.printf("%d", start_flag);
  }

  if (readbytes()==CANCEL){
    pc.printf("END");
  }

}

I would only ever be able to see the ‘OPENED PRESSED’ message on my serial terminal, any other actions do not trigger any other messages. But if i were to rearrange it, for example:

void stop_handler(){
  if (readbytes()==STARTED){
              SPIN_SPD = parameters[0];
              SPIN_DUR = parameters[1];
              MAG_DUR = parameters[2];
              MIX_DUR = parameters[3];
              start_flag = true;
              pc.printf("%d, %d, %d, %d\n", parameters[0], parameters[1], parameters[2], parameters[3]);
              pc.printf("%d", start_flag);

      }      
  if (readbytes()==OPENED){
        pc.printf("OPEN PRESSED");
      }

  if (readbytes()==CLOSED){
    pc.printf("CLOSE PRESSED");
  }


  if (readbytes()==CANCEL){
    pc.printf("END");        
  }

}

I would be able to start my machine proper, with the relevant messages showing. But I won’t be able to access the if statements if i pressed “OPEN” or “CANCEL”. Below is the main loop

int main() {
  // put your setup code here, to run once:
 
    initialise();
    prime_SM();
    

  
  while(1) {
    state_machine();

Below is the prime_SM function & initialise function

void prime_SM(){
  NVIC_SetPriority(USART6_IRQn, 1);
  
  Nextion.attach(stop_handler, Serial::RxIrq);
  pc.printf("PRIMED\n");
 
}

void initialise(){
    wait(2);
    Nextion.puts(INITIALISE);
}

I would appreciate any insight to this

Hello,
Try to call the “readbytes()” function only once at the beginning of the “stop_handler”. Save the result into a local variable and then use that in the “if” tests. Or if you are sure that “readbytes()” always returns only one byte then you can use a “switch()” rather then “if” statements:

void stop_handler()
{
    switch (readbytes()) {
        case OPENED:
            pc.printf("OPEN PRESSED");
            break;

        case CLOSED:
            pc.printf("CLOSE PRESSED");
            break;

        case STARTED:
            SPIN_SPD = parameters[0];
            SPIN_DUR = parameters[1];
            MAG_DUR = parameters[2];
            MIX_DUR = parameters[3];
            start_flag = true;
            pc.printf("%d, %d, %d, %d\n", parameters[0], parameters[1], parameters[2], parameters[3]);
            pc.printf("%d", start_flag);
            break;

        case CANCEL:
            pc.printf("END");
            break;
    }
}

Thank you so much! It worked!

My question is: Why is it that switch case statements work as compared to if statements?

It will work with if statements in case of using readbytes() only once (as @hudakz suggested).
In your original scenario, there is nothing more to read after the first readbytes().