Regarding angular duration

greetings, straight to the point, how to code this if i want

"go from 0 to 180 degree during 5000 ms"
"go from 0 to 180 degree in the time span of 5000ms"

im currently stuck with this https://textbin.net/jok5xa5alx

#include<Servo.h>
Servo myservo;
const int servoPin = 3;  // Servo pin
const int buttonPin = 4;
int buttonState = 0;
int directionState = 0;
int pos = 0;
void setup()
{
  myservo.attach(3);
  pinMode(buttonPin, INPUT);
}

void loop() {

  buttonState = digitalRead(buttonPin);
  if (directionState == 0) {
    if (buttonState == HIGH) {
      directionState = 1;
      for (pos = 0; pos < 180; pos += 1)
      {
        myservo.write(pos);
        delay(1000);
      }
    }
  } else if (directionState == 1) {
    if (buttonState == HIGH) {
      directionState = 0;

      for (pos = 180; pos >= 1; pos -= 1)
      {
        myservo.write(pos);
        delay(1000);
      }
    }
  }
}

the current delay is for the gap between each +1 degree until it hits 180. if i changed it to ++ or -- , it straight goes 0 to 180 to 0 instantly each time i push the button
im confused
also im on arduino uno

thx in advance

For help, please read and follow the instructions in the "How to get the best out of this forum" post, at the head of every forum topic.

Calculate yourself: 180 steps with a 1s delay after each step takes how many seconds?

5000 / 180 = 27.778, did you try:

delay(27);

?

yeah i kinda feel dumb now. thx tho

however, are there any way to make the rotation smoother? at some point, if the degree changes are too small, the servo doesnt rotate that much. and other time rotates quite some gap.
or is this limitation of the servo nature itself? not the code?

Why discard all the decimals? What about

delayMicroseconds(27778);

??
But it's even better to forgo the delays and manage the angular updates as timed events.

I think it is. The servo has a pot to determine its actual position. Friction on the wiper can lead to jumps as you observed. Also plastic vs. metal gears can lead to jumps. So it may be a matter of servo quality and price.

I'm stuck too - its adblocked.

your for loop will take 1 second per 1 degree so 180 sec in total?

The change in angle from your code is always 1 degree (nominal). What you may be falling over is that the Servo library uses a wide range of actual pulse widths (.544m - 2.4ms) and it' possible that your servo, whatever it is, doesn't respond to the very low or high values.

Try it with myservo.attach(3, 1000, 2000); to narrow the range and see if that helps.

Steve

mind to elaborate further?

I suppose you are familiar with the "Blink Without Delay" examples". If you aren't, take a look at them first.

To set up your code as timed events, you start by taking a timestamp and repeatedly check if the current time minus the timestamp has reached some set difference (27 ms, or whatever you'd like). In the meanwhile, you can do other things: this is the point. When the set difference is reached, you do whatever timed action you have to do, you take a new timestamp, and so on and so forth.

With this technique, you can add functions to the code, like reading a button that will stop the motor, invert the rotation, whatever. With delays, you cannot, because the µC spends most of the time waiting, and while it does, it can't detect a button press or take care of any other routine.

You might switch from degrees to servo.writeMicroseconds(). That will give you about 1000 steps from 0° to 180° instead of just 180 steps. It wont fix any problems internal to your servo but with a good servo it will be more and smaller steps.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.