servo case structure issue

Hello,

I have created a FSM for my servo. It has two states. I am using a switch/case structure but the motor is getting ‘stuck’ in the first case and Im not sure why.

code:

#include <Servo.h>

#define one 1
#define two 2


Servo myservo1; //projector platform servo

unsigned long Timer1; //define timer variable for state 1 if statement

void setup()
{
  myservo1.attach(9);
}

void loop(){
  
  static int state = one; // initial state is one.
  
  switch(state)
  {
    case one:
    myservo1.writeMicroseconds(1374); // servo is moving cw
    delay(5000);
    myservo1.writeMicroseconds(1474); // servo is stationary
    Timer1 = millis();
    if (millis() - Timer1 > 5000)
    {
      state = two;
    }
break;

    case two:
    for(int speedv1 = 0; speedv1 <= 100; speedv1 += 2) // loop to ramp up speed of servos
    {
      myservo1.writeMicroseconds(1474 + speedv1); // speed increase by 2 each iteration (servo 1) until servo reaches fullspeed (ACW)
      delay(40); // delay between loop iterations
    }
    delay(5000);
    for(int speedv2 = 0; speedv2 <= 100; speedv2 += 2) // loop to ramp down servo speed
    {
      myservo1.writeMicroseconds(1574 - speedv2); // speed decrease by 2 each iteration (servo 1) until servo stops
      delay(40); //delay between loop iterations 
    }
    delay(2000);
    state = one;
    break;
  }
}

The motor seems to get stuck at myservo1.writeMicroseconds(1374); on the first line of case 1. By stuck I mean the motor just continues to rotate in a clockwise fashion and does not progress to the next writeMicroseconds() statement after the delay. Appreciate the help.

Thanks

Where do these commands come from ? I looked at servo library tutorial and didn’t seem them. Can you post a link to where you are getting these commands ?

 myservo1.writeMicroseconds(1374);

For my continuous rotation servo writeMicroseconds() allows me to control the speed and direction or rotation by writing values from 1374 to 1574 (1374 is full speed in one direction, 1574 is full speed in the opposite direction and 1474 cause the motor to be stationary. These values depends on the specific servo you are using)

raschemmel:
Where do these commands come from ? I looked at servo library tutorial and didn't seem them. Can you post a link to where you are getting these commands ?

 myservo1.writeMicroseconds(1374);

Read the Servo Library section in the Arduino Reference section. From this and other posts you don't seem to be familiar with the concept of continuous rotation servos.

...R

Anyone think they may have a solution to my FSM issue ?

Here it is:

    Timer1 = millis();
    if (millis() - Timer1 > 5000)
    {
      state = two;
    }

I'm not clear what you're trying to do here but you store millis in Timer1 and immediately check to see whether five seconds have passed since you did it. That will never be the case so you never change to state two.

@wildbill

Thanks for your reply. I was under the presumption that the if statement would constantly be run until 5 seconds had passed, and the if statement condition would be met, resulting in a switch to case two.

Ive removed the if statement and the timer variable and replaced it with a 5 second delay:

switch (state)
  {
    case one:
    myservo1.writeMicroseconds(1374);
    delay(5000);
    myservo1.writeMicroseconds(1474);
    delay(5000);
    state = two;
    break;

    case two:
    for(int speedv1 = 0; speedv1 <= 100; speedv1 += 2) // loop to ramp up speed of servos
    {
      myservo1.writeMicroseconds(1474 + speedv1); // speed increase by 2 each iteration (servo 1) until servo reaches fullspeed (ACW)
      delay(40); // delay between loop iterations
    }
    delay(5000);
    for(int speedv2 = 0; speedv2 <= 100; speedv2 += 2) // loop to ramp down servo speed
    {
      myservo1.writeMicroseconds(1574 - speedv2); // speed decrease by 2 each iteration (servo 1) until servo stops
      delay(40); //delay between loop iterations 
    }
    delay(2000);
    state = one;
    break;
  }
}]

For some reason, the first state is run successfully, but then it just repeats itself and there is no transition to state two. Why would this occur as I clearly set the variable state as two…

From that snippet (hint: post the whole thing) it looks as though there should be a transition to state two. It may simply be that the transition occurs but that the state two code doesn't do what you expect. Prove it to yourself with a serial.print statement in each case.

sorry here is the whole thing:

#include <Servo.h>

#define one 0
#define two 1


Servo myservo1; //projector platform servo

unsigned long Timer1; //define timer variable for state 1 if statement

void setup()
{
  myservo1.attach(9);
}

void loop(){
  
  int state; 
  
  state = one;
  
  switch (state)
  {
    case one:
    myservo1.writeMicroseconds(1374);
    delay(5000);
    myservo1.writeMicroseconds(1474);
    delay(5000);
    state = two;
    break;

    case two:
    for(int speedv1 = 0; speedv1 <= 100; speedv1 += 2) // loop to ramp up speed of servos
    {
      myservo1.writeMicroseconds(1474 + speedv1); // speed increase by 2 each iteration (servo 1) until servo reaches fullspeed (ACW)
      delay(40); // delay between loop iterations
    }
    delay(5000);
    for(int speedv2 = 0; speedv2 <= 100; speedv2 += 2) // loop to ramp down servo speed
    {
      myservo1.writeMicroseconds(1574 - speedv2); // speed decrease by 2 each iteration (servo 1) until servo stops
      delay(40); //delay between loop iterations 
    }
    delay(2000);
    state = one;
    break;
  }
}

You broke it! this was good:

  static int state = one; // initial state is one.

This, not so much:

  int state; 
  
  state = one;

The newer code sets state to one on every iteration of loop. Hence you never see state two being executed.

Just checked the code in state 2 and it does what i expect it to do. I swapped the code for each state so state one now does the code that was in state two, and vise-versa. The same thing occurs. The code is successfully run, but then it just repeats itself and does not transition to the next case : /

@wildbill

Argghhhh. Cant believe it was that...Thanks for the help, the code now works well and transition appropriately.

Appreciate the advise !

Read the Servo Library section in the Arduino Reference section. From this and other posts you don’t seem to be familiar with the concept of continuous rotation servos.

Not at all. Never used these kind. I’ve used industrial servos with encoders , driven by DeviceNet drivers but not the 5V continuous rotation servo that I think is being used in this post. Also, I have only been learning software (C++) since last Oct so there’s still quite a bit I haven’t done yet. That’s why I asked. When I run across a post dealing with something I haven’t worked with I try to learn whatever I can from it. As you can imagine, it often takes more than one post to learn a subject. This one was educational because the OP failed to notice he was setting the state to ONE at the beginning of his main loop and couldn’t understand why it kept repeating. It’s a beginner mistake but I didn’t see it because I didn’t know what I was looking at or didn’t know where to look. Now I know.