Servo's shaking, can't seem to fix it!

Hello there,

For a project me and my wife are building a "drumming" monkey using servo motors and an Arduino Uno board.
I've got a background in PLC/industrial programming and one day I also saw some C# code somewhere, so I decided to help her.

Basically, we've got 4 servo motors with very light wooden sticks attached, moving in a certain rhythm.

Our biggest problem is that the servo's shake violently, especially when idle between movements.
This wasn't the case, or maybe just not noticable when the servo's didn't have anything attached.

I've done my homework before posting here and tried various methods (most found on this forum), such as:
-connecting the grounds of my external power supply & Arduino
-trying to put various capacitors between the power supply + and -, also between the - and servo signal
-attaching/detaching the servo's when possible (only improved idle shaking, not while moving)

I'll post my code below, but there's been many changes in it for fixing other problems we ran into, so it's not very clean and there might be things we've overlooked.
I looked up most of the code online and changed it so it would fit our project. Most of it is just actual movements, nothing about them is definitive, this was mostly for testing.

It's a rather simple program but seeing as we're both very new to this, any help would be GREATLY appreciated!
Thanks in advance!

Components used;

  • Arduino UNO
  • External power supply (5V 2A (reused Philips charger/adapter)
  • 4 Servo motors (6V) Gotron | Analog micro servo 1.8kg/cm 120° rotation. | Elektronicaspecialist
  • A potentiometer to change the speed of the cycle
  • A start button (we removed the stop function during some issues, and now simply stop using the reset pin)
  • A 3-way switch to choose between 2 different rhythms/modes
#include <VarSpeedServo.h>
#include <ezButton.h>

VarSpeedServo servoArmL; 
VarSpeedServo servoArmR;
VarSpeedServo servoBeenL;
VarSpeedServo servoBeenR;

int TEN = 10;
int DER = 30;
int ZES = 60;
int HND = 100;

 const int buttonPin2 = 11;
 
 int buttonState1 = 0;
 int buttonState2 = 0; 
 const int analogInPin = A0;
 const int analogOutPin = 9;
 int sensorValue = 0;
 int potValue = 0;
ezButton button(2);

void setup() {
servoArmL.attach(3);
servoArmR.attach(5); 
servoBeenL.attach(6); 
servoBeenR.attach(8);
pinMode (buttonPin2, OUTPUT);

 while (!button.isPressed())
  button.loop(); 
  }

void loop() {

buttonState2 = digitalRead(buttonPin2);  
sensorValue = analogRead(analogInPin);
potValue = map(sensorValue, 0, 1023, 100, 255);

 analogWrite(analogOutPin, potValue); 
 delay(2);
 
  if (buttonState2 ==HIGH) {

      for (int a = 0; a <= 2; a++) { // 2x cycle

      for (int b = 0; b <= 4; b++) {// 4x part 1 of cycle
    
       servoArmR.write(ZES, potValue);
       servoBeenL.write(ZES, potValue);
       delay(150);

       servoArmR.write(TEN, potValue);
       servoBeenL.write(TEN, potValue);
    
       servoArmL.write(ZES, potValue);
       servoBeenR.write(ZES, potValue);
       delay(150);

       servoArmL.write(TEN, potValue);
       servoBeenR.write(TEN, potValue);
       delay(150);
       }
      
        for (int c = 0; c <= 2; c++) { //....

         servoArmR.write(ZES, potValue);
         servoBeenR.write(ZES, potValue);
         servoArmL.write(TEN, potValue);
         servoBeenL.write(TEN, potValue);
         servoArmR.wait();
         delay(10);
      
         servoArmR.write(TEN, potValue);
         servoBeenR.write(TEN, potValue);
         servoArmL.write(ZES, potValue);
         servoBeenL.write(ZES, potValue);
         servoArmL.wait();
         delay(10);
        }
          for (int d = 0; d <= 1; d++) {
          servoArmR.write(ZES, potValue);
          servoArmL.write(TEN, potValue);
          servoArmR.wait();
          delay(10);

          servoArmR.write(TEN, potValue);
          servoArmL.write(ZES, potValue);
          servoArmR.wait();
          delay(10);
         }
     }
        for (int e = 0; e <= 2; e++) {
            servoArmR.write(ZES, potValue);
            servoArmL.write(TEN, potValue);
            delay(10);

            servoArmR.write(TEN, potValue);
            servoArmR.write(ZES, potValue);
            delay(10);
            }
             
              for (int f = 0; f <= 4; f++) {
          
                servoArmR.write(ZES, potValue);
                servoBeenR.write(ZES, potValue);
                servoArmL.write(TEN, potValue);
                servoArmR.wait();
                delay(10);
        
                servoArmR.write(TEN, potValue);
                servoBeenR.write(TEN, potValue);
                servoArmL.write(ZES, potValue);
                servoBeenL.write(ZES, potValue);
                servoArmL.wait();
                delay(10);    

                servoArmR.write(TEN, potValue);
                servoBeenL.write(TEN, potValue);
                }               
                             
 }else{

for (int q = 0; q <= 2; q++) { 

  for (int i = 0; i <= 2; i++) {
  servoArmR.write(TEN, potValue);
  servoArmL.write(HND, potValue);
  servoArmL.wait();
  delay(150);

  servoArmR.write(HND, potValue);
  servoArmL.write(TEN, potValue);
  servoArmR.wait();
  delay(150);
 }

  for (int k = 0; k <= 3; k++) {
  servoArmR.write(TEN, potValue);
  servoBeenR.write(TEN, potValue);
  servoArmL.write(HND, potValue);
  delay(150);
  
  servoArmR.write(HND, potValue);
  servoBeenR.write(ZES, potValue);
  servoArmL.write(TEN, potValue);
  delay(150);
  
  servoBeenR.write(TEN, potValue);
  }
  
  for (int l = 0; l <= 3; l++) {
  servoArmR.write(TEN, potValue);
  servoBeenR.write(TEN, potValue);
  delay(150);
  
  servoArmR.write(HND, potValue);
  servoBeenR.write(ZES, potValue);
  delay(150);
  
  servoBeenR.write(TEN, potValue);
  }
 }
}

Shake_shake_shake.ino (4.85 KB)

power may not be enough. And in your code, using delay() function may make motor shaking. See how to control the speed of servo motor smoothly without using delay()

Without any load, the 4 servos together pulled 0.5A on full motion.
We tried using .wait functions instead of delays before, but that didn't seem to help, this was a while ago though.

I'll try to find another power supply and check out that link, thanks!

Without any load, the 4 servos together pulled 0.5A on full motion.

The startup current is 5 to 10 times the no load current. Count on 10x and you should be OK (5 Ampere power supply).

The usual rule of thumb is to budget 1 Ampere per servo, but that is too little for heavy duty servos.

Please use code tags when posting code. You can edit your post to add them.

A very good point, I did use the MAX function on my Fluke during startup to measure them though.
I'll try another power supply tomorrow.

Edited my code to be in the code tag, didn't see it at first. Thanks for the help!

By chance you routing power from the servo power supply, to a breadboard to the servos?

As hinted at by Idahowalker above, breadboards are not intended for high currents, and the tracks tend to burn if you use them with motors and servos.

I was indeed using the breadboard for connecting them, changed it to actual cable connections.

I changed the power supply to a big 12Ah battery, should be plenty of amps for 4 micro servo's.
After measuring the MAX current of 1 servo comes out at 1.2A, so my other power supply was on the light side.

This improved the shaking, but didn't cure it. Sometimes they shake wildly, sometimes they don't, it's pretty random.
I'll change my program to use millis() instead of delay(), hoping that will fix the remaining shaking.

In the end, I think the servo's might just be of poor quality, causing the problems. We'll probably upgrade them to higher quality ones next year, for the continuation of the project.

Thanks for the help already, it's greatly appreciated!

Using the standard millis() program, without anything added besides the right pin number changed nothing.
Those servo's we got are just unreliable and of low quality.

Atleast I learned alot for future projects!

I use metal geared servos. I have 2 LewanSoul LD-20MG's that have been in continuous operation for a bit over 3 years.

They do have metal gears.
I think the moment you attach something (a very light "stick" of 4mm plywood, almost like a popsicle stick), they just endlessly fight against gravity.

Idahowalker:
I use metal geared servos. I have 2 LewanSoul LD-20MG's that have been in continuous operation for a bit over 3 years.

Of course those servos are much larger, heavier and more expensive than the servos dragonbe is using.

Steve

slipstick:
Of course those servos are much larger, heavier and more expensive than the servos dragonbe is using.

Steve

Of course.