2

I want to use 2nd servo only when 1st is in up state by asking user whether he wants to fire or not.(code in bold is not working )

#include <Servo.h>

    Servo myservo;
    Servo trigervo;
    int pos = 0;
    int u = 0, p = 0, t = 0;
    int incomingByte = 0; // for incoming serial data

    void setup() {
      Serial.begin(9600);
      myservo.attach(9);
      trigervo.attach(10);
      pinMode(13, OUTPUT);
      myservo.write(0);
    }

    void loop() {
      if (Serial.available() > 0) {
        // read the incoming byte:
        incomingByte = Serial.read();
        Serial.print("I received: ");
        if (incomingByte == 111 && u == 0) {
          for (pos = 0; pos <= 80; pos += 1) {
            myservo.write(pos);
            delay(5); // 
            digitalWrite(13, HIGH);
          }
          u = 1;
          p = 0;
          Serial.println(incomingByte, DEC);
          Serial.print("Want to Shoot? \n");
          Serial.print("1\n");
          ***t = Serial.read(); // from here 
          if (t == 107) {
            Serial.print("2\n");
            trigervo.write(60);
            trigervo.write(0);
          } // to here, it is not working***
        } else if (incomingByte == 102 && p == 0) {

          for (pos = 100; pos >= 0; pos -= 1) {
            myservo.write(pos);
            delay(7);
            digitalWrite(13, HIGH);
          }
          u = 0;
          p = 1;
          Serial.println(incomingByte, DEC);
        }
        Serial.println(incomingByte, DEC);

      }
    }
2
  • 1
    read() doesn't wait. it returns -1 if there is nothing in the RX buffer
    – Juraj
    Commented Apr 14, 2019 at 16:56
  • 1
    you forgot to ask a question ... you also forgot to describe what happens when you run the program
    – jsotola
    Commented Apr 14, 2019 at 17:25

1 Answer 1

1

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.

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.

5
  • As you have asked I have changed the question to be pinpointed , please help me......
    – Aditya Raj
    Commented Apr 14, 2019 at 22:07
  • The answer stays the same. Your direct problems are the two stated above. Is this helping? If not: What prevents you from implementing this? Maybe I can write the answer more understandable, if I knew, what isn't clear about it.
    – chrisl
    Commented Apr 15, 2019 at 6:21
  • In case 0, I want to get value through serial read again and implement it by calling a function , in this case calling a trigger function.
    – Aditya Raj
    Commented Apr 15, 2019 at 8:34
  • I rejected your edit, because that is not the way a FSM works. In the states you are waiting for user input. Instead of directly (still in case 0) trying to read more data, you make a transition to the next state, where you are waiting for the new data. That makes the code way better structured and also the waiting for user input will not block the code execution, in case, that you want to do something simultaneously (like blinking an LED or other tasks). I will add a graphical representation of the FSM for your case, so it is better understandable.
    – chrisl
    Commented Apr 15, 2019 at 14:01
  • Ok now I am getting the idea of it
    – Aditya Raj
    Commented Apr 15, 2019 at 14:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.