Extended servo movement when powering board

Hi all,

I have a Nano programmed to operate a servo sweep when a momentary switch is activated (image attached), which is moving a lot when powering up the system.

I’ve read a few posts discussing a similar topic, though this one may be slightly different. When I power up the system, the connected servo goes through a full, or sometimes two full movements, before coming to rest. It may come to rest back at the “home” position, or it may come to rest at the other end of it’s movement, where it continues to apply force until the switch is manually activated. The behaviour is not uniform.

The desired outcome is to power up the Nano, and the servo remains in place (a small “twitch” as described in other posts would be fine) until the switch is pressed. The code is below (modified from the original by @zoomkat ); any advice on code or hardware changes would be much appreciated.

Many thanks

#include <Servo.h>
int button1 = 4; //button pin, connect to ground to move servo
int press1 = 0;
Servo myservo;
int pos = 0;    // variable to store the servo position

void setup()
{
  
  pinMode(button1, INPUT);
  digitalWrite(4, HIGH); //enable pullups to make pin high


}

void loop()
{
  myservo.attach(7);
  press1 = digitalRead(button1);
  if (press1 == LOW)
  {
    delay(250);
    for(pos = 0; pos < 37; pos += 1)  // goes from 0 degrees to 180 degrees
    {                                  // in steps of 1 degree
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(5);                       // waits 15ms for the servo to reach the position
    }
    delay(300);
    for(pos = 37; pos>=1; pos-= 1)     // goes from 180 degrees to 0 degrees
    {                               
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(5);                       // waits 15ms for the servo to reach the position
    }
      delay(1000);

  }
}

NANO_SERVO.jpg

Hi,
Put;

myservo.attach(7);

In setup() not loop();
Also try putting;

myservo.write(0);

after the above statement in setup().
This will make sure the servo hopefully initialises to 0deg.

Tom… :slight_smile:

Hi,
Have you tried using an external power supply for the servo? (Sorry misread diagram.)
OPs image.


Tom.. :slight_smile:

TomGeorge:
Also try putting;

myservo.write(0);

after the above statement in setup().
This will make sure the servo hopefully initialises to 0deg.

Usually it is not possible to know where the servo was when the system is turned off and in that case starting at the middle position is likely to minimise the start-up motion.

You can also do the servo.write() before the servo.attach()

…R

In Setup, try and use buttonpn1, INPUT_PULLUP

Since you're only using a range of 0-37 in your sweep (though you haven't bothered changing the comment that say 0-180) then 0 is a reasonable position to start.

So as already said, move the myservo.attach(7) into setup() and put a myservo.write(0) immediately BEFORE it. You can't completely stop the servo from moving on startup because it needs to be initialised and the servo could physically be positioned anywhere.

Steve

slipstick:
Since you're only using a range of 0-37 in your sweep (though you haven't bothered changing the comment that say 0-180) then 0 is a reasonable position to start.

I think that depends on what is connected to the servo. In some cases a full-speed sweep from 37 to 0 could cause damage.

In a model railway system I'm helping with I have found that starting at the centre (in this case at 18 or 19) is much more kind to the turnouts and the servos.

Another feature for the model railway will be servo operated uncouplers - the servo lifts an uncoupling ramp. The ramps will normally be down so it will probably make sense to start those servos at the down position.

...R

Robin2:
In a model railway system I'm helping with I have found that starting at the centre (in this case at 18 or 19) is much more kind to the turnouts and the servos.

It's an interesting point. The only catch with initialising in the centre is that you're more or less guaranteeing that the servo will twitch on startup because it will almost certainly have stopped at one end or the other. But I guess (I know amazingly little about model railways) at either end of travel the servo is loaded whereas in the middle there's no load on it so that makes perfect sense in that case.

I wonder what the OP is using his servo for.

Steve

Thanks for all the suggestions. I tried all of them; I got a reliable result when I used

  myservo.write(0);

and myservo.attach(7); in the setup. Interestingly it didn't matter which was first.

However, when I connected my proper switch (a 100m, yes 100m) cable, I still had one full movement of the servo. I don't think it was a debouncing issue, as the problem only occured at startup. On a whim I added delay(1000); so that setup is now

void setup()
{
  
  pinMode(button1, INPUT);
  digitalWrite(4, HIGH); //enable pullups to make pin high
  delay(1000);
  myservo.attach(7);
  myservo.write(0);

  

}

and that is working perfectly. Unfortunately I don't understand what the delay is doing; I'm guessing there was some interference during powerup, and the delay holds any action, once 1 second has passed, the interference is gone and the system is stable??

Any thoughts? Thanks again

MarcusG:
However, when I connected my proper switch (a 100m, yes 100m) cable, I still had one full movement of the servo. I don't think it was a debouncing issue, as the problem only occured at startup. On a whim I added

Try and fit a 1K pullup resistor between pin 4 and 5V.
The internal pullup may not be low enough in resistance to pull the input high on power up quick enough.

100m of cable is a nice capacitor.

It may be advisable for you to put an optocoupler in the input circuit, that 100m is a good aerial.

Tom.... :slight_smile: