Is it possible to digitally turn off a servo without a relay?

Hi,

I'm using 28 servos in a project I'm working on. Each servo is ~5v. Even though there are 28 servos, at any given time only 4 will move.

I would like to use only one or two 5v power supplies. I can't do that if all of the servos stay on all the time.

To solve the problem, I would like to turn off the 24 that aren't moving until I need them. This would mean that at any given time I would only have 4 motors on simultaneously. I can do this with relays, but I was wondering if there is another way? Someone recommended I just drop the PWM, but I've looked into this and it doesn't seem to be a viable solution (if it is, I can't figure out how to drop it).

I'm using the
#include <Servo.h>
library to change the position of the motors.

Each motor is controlled by a Pro Mini (28 Pro Mini's total). A single Mega will synch them all (1 Mega total).

Any suggestions would be a great help :slight_smile:

Thanks!

if you detach the servo it will draw minimum current from the power supply, but when reattached, it will jump to the default (usually 90 deg.) position unless you save the position before detaching and reload it before reattaching.

Thanks for your help! But I'm afraid I don't know what you mean. When you say detach, do you mean unplug? Isn't that essentially what a relay does? And if so, how do you do this without a relay?

No, detach is not like a relay.
It is a method in the servo library like attach is.
It stops the ppm signal for that servo.
Most servos then stop applying power to the motor.
When you later attach, the servo starts working again to move to/stay at the position defined by the signal.
Power to the servo is never shut off, but most servos draw very little current when not actively receiving a signal.

Be aware, a servo that receives no signal does not maintain position and will likely move if any ant force is applied.

As vinceherman points out, when you later do a myservo.attach() to re-attach after a myservo.detach() it will go to 90 by default.

To prevent that (unless it happens to be what you want) you would do a myservo.write() before the myservo.attach(), telling it where to go. All being well, that will be where you were anyway, before the detach(). And if it's moved, you shouldn't have detached it in the first place, since while it was attached it will (should...) have held position under load.

The value you put in the new attach() will possibly be a number (if that's what you did before) or a variable with the last known commanded position (if that's what you did before).

So you could go:

myServo.write(127); //if you knew this
myServo.attach(pinNum);

Or:

myServo.write(thePos); //if this is up to date
myServo.attach(pinNum);

BUT maybe you don't actually know the number or have it in a variable. You might have started knowing the value in a variable but have done some arithmetic to it, and not have it readily available.

You might have done this during the course of the servo's last attachment:

pos=30;
.
.
myServo.write(pos);
.
.
myServo.write(pos+20);

... and not have kept track of its last commanded position being 50. If that's the case, use servo.read() to fetch back the servo's last known commanded position:

thePos=myServo.read();
myServo.write(thePos);
myServo.attach(pinNum);

(Note I always refer to the servo's last commanded position. Unless you have a (fairly uncommon) feedback servo, you don't actually know where a servo is, just where you sent it.)

Thanks for all of your help everyone.

For those who are looking at this thread later on, here's an example of code I wrote based on the suggestions of everyone that helped me out.

This uses the detatch method and waits 9 seconds both while attached, and while not attached so you can test if the motor is being sent PWM just by trying to move the motor's position with your hands.

#include <Servo.h>
Servo myServo;
int servoPin = 5;

void setup() {
  myServo.attach(servoPin);
  Serial.begin(9600);
  myServo.write(90);
}

void loop() {
  myServo.attach(servoPin);
  myServo.write(45);
  delay(9000); //Delay 9 seconds while attached. (if you push the motor with your hand it will electrically resist here)
  myServo.detach();

  myServo.attach(servoPin);
  myServo.write(135);
  delay(1000); //Wait for servo to move to desired position before detatching.
  myServo.detach();
  delay(9000); //Delay 9 seconds while NOT attached. (if you push the motor with your hand it will NOT electrically resist here)
 }

Thanks again for all your help!