Servo moves/ sweeps fine but hangs when asked to move more than 10 degrees

Hi all,

I purchased a servo link wanting to build a contraption that would basically work reading input from LDRs and moving the servo accordingly.

I'm no expert with servos so I'm trying to see if this thing is broken or if its working as it is supposed to.

Very first thing I did was to connect it to my lab bench power supply (7.2v 3 A limit - Made sure to share ground with Arduino-) loaded up the sweep example sketch from the IDE on my arduino UNO and I noticed the servo moving back and forth as it was supposed to, after that and since it was apparently working fine, I breadboarded it along with a pot (10k) and loaded up the knob sketch which worked perfectly as well.

After flawlessly passing both previous tests, I was ready to test and write down the actual "comfortable limits" -upper and lower- , so I coded a quick sketch (basic sketch, asking for input on serial and after entering the number the servo would move) and I quickly discovered that for some strange reason, my servo works fine when I ask it to move in 10 degree increments, but goes bananas when I want it to move in bigger increments (say 30 to 160, 20 to 160, etc etc etc) even if it is at 90 and I ask it to go to 110 the damned thing starts vibrating like crazy and does nothing, but if instead of 110 I modify the code and I input 100 (10 degree movement) the servo moves fine to where it should move.

I've spent several hours troubleshooting this thing, reading up online and trying to come up with a solution and I honestly couldn't find any. Tried 3 different Arduino Uno's including 2 original Arduinos and 1 clone, tried with an Original Arduino nano, and also tried with my esp8266, and same thing.

Issue is that I have no idea what the actual issue is, I don't know if the actual servo is busted, or if it is damaged or if it is power/software related issue.

On my side I basically tried every possible thing I could think of:

Tried 2 different lab bench power supplies, tried SLA battery with a Buck/Boost tried liPO, li-ion etc, I even tried different supply voltages from 6v all the way to 8v and same thing.

I also tried several different sketches inputting microseconds or direct pwm, heck even browsed and copy pasted as many sketches I could possibly find, I also modified the original sketches with different values, and nothing.

The actual circuitry/cabling was checked and checked again and I went as far as soldering everything into perfboard after trying 4 different breadboards (thinking it was a bad contact or connection)

But no, nothing... I honestly have no clue how come this thing works perfectly fine with the Knob example and follows the actual analog reading to the teeth and then it just goes bananas when asked to move in more than 20 degree increments. (modified the knob sketch too, turned the serial on and printed the actual reading and the servo movement and everything worked fine)

I'm trying to describe the situation to the best of my knowledge, there is no sketch to upload since I am basically using the default knob and sweep from the Arduino IDE and for the actual sketch that would fail is basically writing anything that would require the servo to move into a position 20 degrees over.

For the actual circuitry/cabling is simple, 3 wires from servo * signal, vcc and ground * signal to pin9, ground to arduino and pwr source and vcc to power source, on the arduino just 5v, vcc and ground + ground of the servo. (highly doubt is power or circuitry related since sweep and knob work fine)

All help, comments, questions appreciated in advance !

There are so many variables described in your post that it's almost impossible to work out what you've actually tested.

Try putting a longer delay() into your Knob sketch with the serial prints so it only reads the pot every second or so. Then that too can write to the servo in large increments. Does that also fail?

Also since that servo has "min working current" of 1A I'd guess that the stall current may be quite high. Can you try it with a power supply which can definitely supply over 3A, say 8-10A just for testing? I'd use a decent sized 2S Lipo (e.g. 2000mAh, 20C) but you just say you tried "lipo" with no details.

When it fails is it connected to any load? That will naturally increase the current it takes.

Steve

Post a wiring diagram of your work. Pencil, paper and a camera are good enough if you include proper detail like pin numbers.

It also helps to post actual photos of your project.

Post your code (use code tags). I know that you said that it is a simple modification of the tutorial but we still want to see it. Push up a sketch on to your arduino, ensure that it still demonstrates the bad behavior and then post that sketch here.

Do you have anything connected to the servo arm or is it just freely moving though air?

Great ideas slipstick, thank you for your comment and your time !

Why didn't I think of that, I was already thinking of a "work around" seeing that it follows the analog reading just fine with 10 degree increments, making it go to X or Y range in a step by step manner somehow mapping it via software, but I should first try and modify the code and see if my increments are wider if it also becomes unresponsive guessing yes since it would act as basically a different write.

I could also try to cobble up something to measure the actual current and figure out if its indeed power related, (If you watch my video my Fluke Clamp meter was on the desk because I was basically analizing / observing current usage) although judging by the actual jittering and noise it makes, it is quite likely that the current would go up in order to try and somehow free the servo from that "virtual stall" it apparently is, on my bench power supply which is probably not the best and most accurate I did see that during the "virtual stalls" current went up significantly e.g, 1.3A or 1.5A but I took it with a grain of salt since that doesn't necessarily mean that the power source is the issue, it could also mean that the servo is somewhat completely lost in limbo not knowing where it is and where it should go, or did I get it wrong? otherwise my bench power supply is more than capable of providing more than 1.5A... The actual servo didn't draw it/required it. Sealed acid battery used is also more than capable of providing more than the required power and yet still observed same erratic behavior

I have also played around extensively with delay and it does the same thing (from 5 all the way to 8000)

I have also considered all the many variables that this issue could involve, and it is pretty hard in and on itself to try and describe the weird behavior of this servo, so I tried to be as thorough as I possibly could, but I have also recorded a video describing it, and uploaded it to youtube, maybe someone observed this issue before or saw it first hand and is able to give me a hand.

To vince, thank you as well for your time... In the actual video I uploaded you can get a graphical example and representation as well as seeing the actual behavior in real life, if its not too much trouble I would appreciate it if you could take a look at it.

I also understand why you might want to see the code, so I made sure and tried this attached one beforehand and used it when recording the video the knob example is the same one that comes by default in the Arduino IDE I have also used pin9 so I did not modify/nor touch any of its code therefore there is no reason for me to upload it.

#include <Servo.h>                    //Including the servo Library


int pos = 0;                          // Variable to store the servo position
int servoPin = 9;                     // Servo is hooked to pin 9
int servoDelay = 25;                  // 25 millisecond delay after each servo write

Servo Servotest;                      // Creating the servo object.


void setup()
{
  Serial.begin(9600);
  Servotest.attach(servoPin);         // Attaches the servo to pin servoPin, which should be pin 9
}


void loop() {

  Serial.println("Where would you like the Servotest? "); //prompt me for position
  while (Serial.available() == 0) {   //wait for my input
  }

  pos = Serial.parseInt();            //read input into position

  {
    Servotest.write(pos);             //set servo position to pos
    delay(servoDelay);                // waits 15ms for the servo to reach the position, played around a lot with this value slipstick.
  }
}

I will also upload the circuit as well and provide a picture of the setup for those not caring enough or not wanting to sit trough the vid.

Video is up - YouTube

Video

I can't guarantee this is the problem but the first thing I'd do is get rid of those croc clips. They do not provide a solid power connection at the sort of currents that servo needs. And also avoid any power/ground connections through a breadboard for the same reason...they're only intended for low current. Direct connection to power supply terminals or battery connector is what you need.

Steve

slipstick:
I can't guarantee this is the problem but the first thing I'd do is get rid of those croc clips. They do not provide a solid power connection at the sort of currents that servo needs. And also avoid any power/ground connections through a breadboard for the same reason...they're only intended for low current. Direct connection to power supply terminals or battery connector is what you need.

Steve

Hi Steve thank you again for your time, it is awfully hard to cover all the bases or go through pretty much everything I did / I have tried in order to make this damned thing work, unfortunately it would take me forever and I don't want to write a wall of text that would be a pain to read, but like you I also suspected that the culprit might be simply a bad/poor connection, so I took the time and made a dedicated perfboard to which I soldered everything, used thick and short wires coming out of the servo but it still did the same thing, for demonstration purposes only during the video I just simply used the breadboard along with dupont cables.

Any other clue/idea ? have you ever seen a servo acting like this? Do you think it may be faulty? (unfortunately I only have this one, no spare one to try )

O.k. it sounds like you've done all the tests reasonably possible. I've never seen a servo behaving in exactly that way and I have trouble working out what sort of fault could do that. I'm out of ideas, sorry.

Steve

No reason to be sorry ! thank you for your time and suggestions troubleshooting this thing!

I'll try and reach out to the seller and see if he is willing to help, highly doubt it but my options are somewhat limited and I am also all out of ideas/possible solutions.

xtrasback, you certainly are following a logical path for troubleshooting.

In the sketch that you loaded, can you add a serial print for the value of pos right before you write it to the servo? That will just help me confirm that you are writing what you expect to write.

What version of the IDE are you using? I am running 1.8.4
Have you done anything with the servo library like trying to install other versions?

vinceherman:
xtrasback, you certainly are following a logical path for troubleshooting.

In the sketch that you loaded, can you add a serial print for the value of pos right before you write it to the servo? That will just help me confirm that you are writing what you expect to write.

What version of the IDE are you using? I am running 1.8.4
Have you done anything with the servo library like trying to install other versions?

Hello Vince, thank you again for your time !

Well I honestly am giving it my best shot but I'm completely clueless as to what in the world could be going on, and my experience with servos is next to none which doesn't really help the situation hah, that's why I registered so guys like you could perhaps clue me in !

Today I completely disassembled the servo, to see if there was any obstruction in the gears or too much grease, but no, everything looked good on the gear side mechanical... Way too much grease perhaps but I gave everything a good clean and put some proper amount of brand new grease and voila !
On the other side tho, the PCB had some questionable blobs of solder especially the wires coming from the motor all horrible dry joints, so I replaced those with new ones and soldered them properly.... I also soldered the chips since apparently they were skimping on sodder or "forgot" to solder some of the legs on the pads on the smd chips, reassembled the whole thing, and even tho is seems to spin a lot smoother now it is still acting up.

In regards to your suggestions, I am running 1.8.7 on a Macbook Pro running MacOs Mojave 10.14.1 but I have also tried a different laptop running 1.8.7 IDE on windows 10.

I have not done anything whatsoever to the actual library, in fact I just recently installed 1.8.7 and the servo libraries are exactly as they come factory. I also tried running the servo without the library, just coding the parameters per manufacturer specs and still did the same thing.

I just modified my sketch and ran the tests you requested, but I have no idea how to show you the results other than uploading another video, so I just did that and here is the link. Video

For the actual code I used, I will also attach it to this post just in case note that I did play around with the delay function but it still did the same thing (Noticed something weird tho, the actual servo "thought" it moved all the way to 50 when in fact, -MECHANICALLY- it didn't, did you notice the same thing?)

#include <Servo.h>                         //Including the servo Library


int pos = 0;                                 // Variable to store the servo position
int servoPin = 9;                          // Servo is hooked to pin 9
int servoDelay = 25;                    // 25 millisecond delay after each servo write
int Cpos = 0;                               // Variable to store Current Servo position for Vince

Servo Servotest;                           // Creating the servo object.


void setup()
{
  Serial.begin(9600); 
  Servotest.attach(servoPin);              // Attaches the servo to pin servoPin, which should be pin 9
}


void loop() {

  Serial.print("Where would you like the Servotest? "); //prompt me for position
  Serial.println(" ");
  
  while (Serial.available() == 0) {     //wait for my input
  }
  pos = Serial.parseInt();                 //read input into position                 
  {
    Serial.println(" ");
    Cpos = Servotest.read();
    Serial.print("Current Servo position for Vince = ");   
    Serial.println(Cpos); 
    Servotest.write(pos);                  //set servo position to pos
    delay(servoDelay);                     // waits 15ms for the servo to reach the position, played around a lot with this value slipstick.
    Serial.println(" ");
    Serial.print("Desired position for Vince = ");   
    Serial.println(pos);
    Serial.println(" ");  
  }
}

Servo.read() doesn't tell you "where the servo thinks it is". It just returns the last command that was sent to the servo. There's no actual position feedback from the servo itself.

Steve

oops .. ! I looked up real quick at the reference and assumed, my bad. :-[
Well, that would explain why it wanted to start from 50 when in fact it wasn't anywhere near it !

hah thank you Steve.

I feel somewhat guilty for wasting so much time on a cheap Chinese servo, but hey at least I'll learn a thing or two about this whole ordeal along the way and that's why I keep at it.