Skip to main content
added missing bracket
Source Link
chrisl
  • 16.5k
  • 2
  • 17
  • 27
int state = 0;

void loop(){
    switch(state){
        case 0:
            if(Serial.available()>0){
                int input = Serial.read();
                //take appropriate action
                state = 1; //do state transistion
            }
            break;
        case 1:
            if(Serial.available()>0){
                int input = Serial.read();
                //take appropriate action
                state = 0; //do state transition
            }
            break;
    }
}
int state = 0;

void loop(){
    switch(state){
        case 0:
            if(Serial.available()>0){
                int input = Serial.read();
                //take appropriate action
                state = 1; //do state transistion
            }
            break;
        case 1:
            if(Serial.available()>0){
                int input = Serial.read();
                //take appropriate action
                state = 0; //do state transition
            break;
    }
}
int state = 0;

void loop(){
    switch(state){
        case 0:
            if(Serial.available()>0){
                int input = Serial.read();
                //take appropriate action
                state = 1; //do state transistion
            }
            break;
        case 1:
            if(Serial.available()>0){
                int input = Serial.read();
                //take appropriate action
                state = 0; //do state transition
            }
            break;
    }
}
Adding graphs for the FSM explanation
Source Link
chrisl
  • 16.5k
  • 2
  • 17
  • 27

EDIT: For giving a better explanation about finite state machines, I've drawn a graphical representation of the states. Mostly it is way easier to code, when you first have drawn such a graph to visualize the codes functionality. Note, that this is the logic from your code. You may want it to work another way, but this is beyond the scope and only for understanding. Also note the different numbers of the states than I used above, which I only change, because I needed more states.

See first this graph:

enter image description here

We begin in state 0, where we are waiting for user input through serial. If we go some input, we make a decision: If the value is 111, we will transition to the next state (state 1) to position the gun, else we will wait again for more input. In stage 1, we are positioning the gun and go directly to state 2. There we are again waiting for user input. If we received something, we will again make a decision: On the value 107 we will do the transition to state 3 to shoot, else we will go to state 0, to ask again for positioning, like we did before. In state 3 we are shooting and directly go to state 0 again. This is rather strict division into states.

Since in state 1 and 3 we are only doing a short action and then going directly to another state, we might cut those states away, implementing the corresponding code in the transition from state 0 to 2 and vice versa. This is the logic from my FSM code example above (action together with transition). The graph would look like this:

enter image description here

Which version you should implement depends on other factors. If you are OK with the action code to be blocking, you can implement version 2, since it has less states. If you want to write the action in a non-blocking style, you might find version 1 easier to implement.

EDIT: For giving a better explanation about finite state machines, I've drawn a graphical representation of the states. Mostly it is way easier to code, when you first have drawn such a graph to visualize the codes functionality. Note, that this is the logic from your code. You may want it to work another way, but this is beyond the scope and only for understanding. Also note the different numbers of the states than I used above, which I only change, because I needed more states.

See first this graph:

enter image description here

We begin in state 0, where we are waiting for user input through serial. If we go some input, we make a decision: If the value is 111, we will transition to the next state (state 1) to position the gun, else we will wait again for more input. In stage 1, we are positioning the gun and go directly to state 2. There we are again waiting for user input. If we received something, we will again make a decision: On the value 107 we will do the transition to state 3 to shoot, else we will go to state 0, to ask again for positioning, like we did before. In state 3 we are shooting and directly go to state 0 again. This is rather strict division into states.

Since in state 1 and 3 we are only doing a short action and then going directly to another state, we might cut those states away, implementing the corresponding code in the transition from state 0 to 2 and vice versa. This is the logic from my FSM code example above (action together with transition). The graph would look like this:

enter image description here

Which version you should implement depends on other factors. If you are OK with the action code to be blocking, you can implement version 2, since it has less states. If you want to write the action in a non-blocking style, you might find version 1 easier to implement.

edited body
Source Link
Duncan C
  • 5.7k
  • 3
  • 18
  • 30

Without knowing, what exactly you want it to do (since you didn't tell us), I see 2 problems in your code:

  1. The code around the line marked with "from here" will ask the user over Serial, if he wants to shoot, but directly after it, it will read a value, without waiting for the user to input something. Serial.read() will not wait for data to arrive, it will just return -1 if nothing is in the buffer. You have to check, if there is actually something in the buffer with Serial.available() and only proceed, if there is actually data to read.

  2. In the following if-statement, you first write the value 60 to the servo and directly after it, without any delay, the value 0. The servo doesn't have enough time to get to 60 - or to even start to move - before you tell him to go to 0. The servo needs time for movements.


Apart from the specific problems with your code, I would use a finite state machine (FSM), to implement it, instead. You declare a global state variable, which represents the possible states, in which your machine can be. If I assume some type of gun/shooting device, these states could be ASK_USER_TO_POSITION_GUN' and 'ASK_USER_TO_SHOOT'. In each state you check the Serial interface (first with Serial.available()then reading withSerial.read()` if it returns something greater than 0) and based on that input you first take the appropriate action and then do the state transition, by changing the state variable.

As example of the general structure:

int state = 0;

void loop(){
    switch(state){
        case 0:
            if(Serial.available()>0){
                int input = Serial.read();
                //take appropriate action
                state = 1; //do state transistion
            }
            break;
        case 1:
            if(Serial.available()>0){
                int input = Serial.read();
                //take appropriate action
                state = 0; //do state transition
            break;
    }
}

PependingDepending on the exact actions to do, you can also tune this, by reading Serial outside of the switch statement and in the case statement only check the input variable. In this case reset the input variable after every interaction.

Without knowing, what exactly you want it to do (since you didn't tell us), I see 2 problems in your code:

  1. The code around the line marked with "from here" will ask the user over Serial, if he wants to shoot, but directly after it, it will read a value, without waiting for the user to input something. Serial.read() will not wait for data to arrive, it will just return -1 if nothing is in the buffer. You have to check, if there is actually something in the buffer with Serial.available() and only proceed, if there is actually data to read.

  2. In the following if-statement, you first write the value 60 to the servo and directly after it, without any delay, the value 0. The servo doesn't have enough time to get to 60 - or to even start to move - before you tell him to go to 0. The servo needs time for movements.


Apart from the specific problems with your code, I would use a finite state machine (FSM), to implement it, instead. You declare a global state variable, which represents the possible states, in which your machine can be. If I assume some type of gun/shooting device, these states could be ASK_USER_TO_POSITION_GUN' and 'ASK_USER_TO_SHOOT'. In each state you check the Serial interface (first with Serial.available()then reading withSerial.read()` if it returns something greater than 0) and based on that input you first take the appropriate action and then do the state transition, by changing the state variable.

As example of the general structure:

int state = 0;

void loop(){
    switch(state){
        case 0:
            if(Serial.available()>0){
                int input = Serial.read();
                //take appropriate action
                state = 1; //do state transistion
            }
            break;
        case 1:
            if(Serial.available()>0){
                int input = Serial.read();
                //take appropriate action
                state = 0; //do state transition
            break;
    }
}

Pepending on the exact actions to do, you can also tune this, by reading Serial outside of the switch statement and in the case statement only check the input variable. In this case reset the input variable after every interaction.

Without knowing, what exactly you want it to do (since you didn't tell us), I see 2 problems in your code:

  1. The code around the line marked with "from here" will ask the user over Serial, if he wants to shoot, but directly after it, it will read a value, without waiting for the user to input something. Serial.read() will not wait for data to arrive, it will just return -1 if nothing is in the buffer. You have to check, if there is actually something in the buffer with Serial.available() and only proceed, if there is actually data to read.

  2. In the following if-statement, you first write the value 60 to the servo and directly after it, without any delay, the value 0. The servo doesn't have enough time to get to 60 - or to even start to move - before you tell him to go to 0. The servo needs time for movements.


Apart from the specific problems with your code, I would use a finite state machine (FSM), to implement it, instead. You declare a global state variable, which represents the possible states, in which your machine can be. If I assume some type of gun/shooting device, these states could be ASK_USER_TO_POSITION_GUN' and 'ASK_USER_TO_SHOOT'. In each state you check the Serial interface (first with Serial.available()then reading withSerial.read()` if it returns something greater than 0) and based on that input you first take the appropriate action and then do the state transition, by changing the state variable.

As example of the general structure:

int state = 0;

void loop(){
    switch(state){
        case 0:
            if(Serial.available()>0){
                int input = Serial.read();
                //take appropriate action
                state = 1; //do state transistion
            }
            break;
        case 1:
            if(Serial.available()>0){
                int input = Serial.read();
                //take appropriate action
                state = 0; //do state transition
            break;
    }
}

Depending on the exact actions to do, you can also tune this, by reading Serial outside of the switch statement and in the case statement only check the input variable. In this case reset the input variable after every interaction.

Source Link
chrisl
  • 16.5k
  • 2
  • 17
  • 27
Loading