Noisy power supply to servo

I have a question that seem quite common. However, I thought I was taking into account the advice given here, and yet I'm still having problems.

I am trying to power a simple SG90 servo. I'm using the 'sweep.ino' Example sketch.
According to the advice given here, I'm trying to use an external power supply. Because of the nature of my project, I would like to use batteries and a voltage regulator LM340 (datasheet).

Here is my circuit

The servo is very noisy (as in audible), and jittery. it even stops sometimes in the middle of a sweep for a few seconds.

I looked at the voltages at the signal and power lines and I observe that the power voltage is extremely noisy, sometimes drops below 3V (that's when the servo stops).

Using a bench power supply produces a much cleaner power. I can check also check that the servo draws about 100mA when moving, and up to 600mA when stalled, but seems well within the range of the voltage regulator...

I also added a larger capacitor (470uF) to the output of the voltage regulator, which does smooth out the noise, but it is still present.

Any suggestions?

Here are the traces with a 0.1uF capacitor. Yellow is the PWM signal, blue is the power supply voltage.

Welcome to the forum.
Thank you for the schematic and the scope screendump.

How strong is the 9V battery ? A small 9V battery is for a smoke detector, it is often not even good enough for a Arduino Uno. It can provide maybe 50mA to 150mA.

If the stall current is 600mA, the means that the current peak when the servo starts to move is also 600mA. There must be enough power for that.

If there is a current peak of 600mA, then that current peak goes through the servo motor and into the GND wire. That current peak through the GND wire can disturb all the GND points that the current peak meets on its way back to the power supply.

Thank you for your help. Are AA batteries any better?

AA batteries are way better than a 9V smoke alarm battery. They have the current capacity to run a servo. And a 4 AA cell pack (6V) will not need a regulator to power the servo.

Thanks,
So I tried with 4xAA in series. Although the servo did not stop anymore, I cannot say the movements are any smoother, or the voltage any less noisy. Is this really the best that can be achieved with servos, or am I missing something??
My test circuit is

Output

Of course, I wouldn't care about this voltage fluctuations if the movements of the servo were smooth, but I can feel the servo jumps every time the voltage takes a relatively long (>= 20ms) dip like that.

Try putting 10uF and a 0.1uF caps across the servo power supply. The 10uF to smooth out power fluctuations and the 0.1uF to bypass higher frequency noise.

servo caps

The voltage drops a lot. You need good batteries, a good battery-holder and normal wires.

Rechargeable NiMH battery from a well known brand (Eneloop, GP) should be okay.
The jumper wires (which are often in a starter kit) are not normal wires, they are super thin wires.

The capacitors of 10µF and 100nF are good, but I would use 100...1000µF and 100nF.

Manufacturers try to sell a servo motor by boasting about the high torque and trying hard to avoid to tell the current that is required.
For example the Towerpro MG91 has a stall current of 480mA according to some websites, but the manufacturer does not tell what the stall current is: https://www.towerpro.com.tw/product/mg91/
This is a servo motor with a small torque. It probably has a low stall current, but the manufacturer does not give that information: https://www.active-robots.com/motors-wheels/servo-motors/hitec-hs322hd-servo.html

Can you tell what your project is ?

Thank you for your help. For my information, can you explain why the 2 caps? If I remember my lessons, 2caps in parallel add up, so that would be the same as a 10.1uF cap, which does not seem that different from just a 10uF cap?

It's because electrolytic capacitors (such as the 10uF capacitor) tend to have a rising impedance at high frequencies, so they don't filter out high frequencies all that well. A non-electrolytic capacitor, such as a 0.1uF ceramic capacitor, doesn't suffer that problem so it filters high frequencies very well.

Thus: the 10uF electrolytic for the lower noise frequencies, and the 100nF ceramic for the higher frequencies.

1 Like

Thank you for your help.
I ended up putting in 2200uF cap to smooth out the voltage drops.It works OK (still not great, but I could learn to live with it).

I am building a device that measure the dynamic resistance exerted by some material at different angles. The load cell is attached to the servo, and should describe a smooth arc, and I take measurements of the load throughout that arc.

Now, more problems arose when I try to connect the HX711 amplifier and take measurements, and I'm at a loss as to what the problem is.

Test circuit is (Note that behavior is the same if I use a bench power supply instead of the batteries)

Test code is

#include <Servo.h>            //Servo library
#include "HX711.h"            //Header file for the load cell amplifer/serial data converter
Servo servo;
HX711 cell;

#define DOUT  3
#define CLK  2
#define SERVO_PIN 10
#define ANGLE_MAX 180
#define ANGLE_MIN 100
#define ANGLE_STEP 1

void setup()
{
  //initialize load cell
  cell.begin(DOUT, CLK);
  servo.attach(SERVO_PIN);      // attach the signal pin of servo to pin 10 of arduino motor shield

  servo.write(ANGLE_MIN); //bring servo to its baseline angle
}

float angle;

void loop() {
  cell.get_units();
  angle += ANGLE_STEP;
  servo.write(angle);
  delay(20);
  if (angle >= ANGLE_MAX) {
    angle = ANGLE_MIN;
    servo.write(angle);
    delay(500);
  }
}

When I run this code, the movements are very jumpy, and the voltage drops a lot at those moments

If I comment the line cell.get_units(); then the movements are much smoother (again, not perfect, but acceptable)

Any ideas?

This is weird, and it needs someone smarter than me to get to the bottom of it.

At first I thought that cell.get_units()was taking a variable - and sometimes rather long - time to run, hence causing hesitations in the movement of the servo. HOWEVER, your servo is actually jumping backwards slightly, which is puzzling to me.

I suggest you make the 20 inside delay(20) into a const value (same with the delay(500), as it's not good to have "magic numbers" in your code like this. Or you could use #defines.

Then, if it were me on my own, I'd begin by making changing the inter-step delay on the servo to something much longer, to slow the whole thing down, and see if you can observe exactly what is happening with those jumps. Do they still occur? Are they definitely backward jumps, or just hesitations?

Then I would put a Serial.println(angle) just above servo.write(angle) and do one complete sweep to see if I can catch odd jumps in the value of angle in the serial port monitor on your PC.

I wonder if HX711 does some background activities off a timer, or something.

Anyway, until someone smarter comes along, have a play along the lines I suggested and report back your findings.

Make a small test-sketch for just the servo motor. It is normal to have a few test-sketches when making a project.

Use a int for the angle, not a float.

Try a full sweep:

void loop() 
{
  servo.write( 0);
  delay( 2000);
  servo.write( 180);
  delay( 2000);
}

Then try a slow motion:

int angle = 0;

void setup()
{
  attach ...
  servo.write( angle);
  delay( 2000);
}

void loop() 
{
  servo.write( angle);
  angle++;

  if( angle > 180)
  {
    while(true);     // halt the sketch
  }

  delay( 20);
}

@SteveThackery @Koepel Thank you, I appreciate your help. At this point, it looks like you are both thinking this is a software problem, rather than a problem with the power supply, is that right?

No, not necessarily. I was suggesting the first steps towards getting a fuller understanding of what's happening while we wait for someone with specific expertise to come along. In particular, someone who's smart enough to take a look inside HX711.h and see if there's anything interesting going on.

What efforts have you made to debug this yourself?

I think the issue could be cheap wires or cheap battery holder - most cheap AA battery holders are not designed for high currents, and servos pull lots of current -
the issue is they are rivetted, not welded, leading to excess contact resistance.

Cheap hook up wires for breadboards often cannot carry more than a few 100mA, totally unsuitable for motors/servos. Breadboards themselves aren't designed for
high currents either and contact resistance can be an issue. 0.6--0.7mm diameter
solid core wire is my go-to choice for high current capable prototyping wire, can
carry several amps, will fit in a breadboard or screw-terminals.

After digging around, it seems I'm not the first experiencing issues with trying to use Servo and HX711 at the same time. See here, here and related post here.

I've implemented the fix that was proposed a few days ago on the HX711 github, which does improve the behavior of the device. However, I am not sure what unintended consequence that might have, and I don't want to risk having the HX711 go into powerdown mode.

For the moment, I'm using the non-blocking HX711 library, which seem to work just as well.

Thanks everyone for you help

The program does not seem to be waiting long enough for the servo to return to it's home position before being commanded to rotate again.
Paul

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