Single stepping servos for smooth movement- drifting toward dynamic target.

I'm new to coding but having lots of fun playing with arduino stuff. I recently built this circuit and am running this code (as an alternative to another tutorial that didn't have the servos returning to home).

Everything works overall, but the servo actions are really jerky. Judging from the feedback in serial monitor part of the problem lies in the physical construction of the thumb-joystick and use of micro potentiometers. I can move the stick a few degrees before the numbers start to change and then the servos jump toward the desired position.

What I'd like to code is a program that will observe the current stick coordinates and move toward them while hitting each step in between them. So instead of targeting from 0 deg to 10 deg, it would move to 1,2,3,4,5,6,7,8,9, to arrive at 10 degrees. That makes sense, right? If it's ridiculously slow then maybe we step by a larger value but still- this is my thought on how maybe it could be approached. It's ok if the action is kind of "driftey", I much prefer that to jerky.

Of course feel free to ignore that thought and just tell me the proper way to do

Here's my current code for reference- nearly verbatim from the instructible version just changed pins & delay time. Thanks for any help!

Your joy stick seems to working perfectly. A joystick has to have a dead spot when centered.


Have a look at the Sweep example in the IDE. That shows a technique for moving a servo 1 step at a time which might help you get started.

Or have a look at the VarSpeedServo.h library which allows you to set the speed of servo moves.


Paul- I wasn't suggesting the joystick was faulty- just that tolerances and precision could be better, and I think it plays into the control issue. Much sloppier than, for example a radio control stick.

Steve- thanks, I'll look into it! I'm a bit surprised there isn't more code already addressing this specifically as it seems like anyone using a servo will need to deal with this somehow.

Steve- thanks, I'll look into it! I'm a bit surprised there isn't more code already addressing this specifically as it seems like anyone using a servo will need to deal with this somehow.

I don't think so. Most people who use servos are managing steering, control surfaces etc and are happy for them to go where they are commanded at speed. If the commands are jerky so will be the movements but that's not a problem. No need to artificially slow them down.


Further to previous advice. When you implement the code to move the servo step by step consider using the writeMicroseconds() function which allows for more steps between positions than the write() function

Thanks again- it will surely take some time to figure out the right way to use this advice re: code/syntax. I definitely have a lot of experimenting to do, but I appreciate y'all steering me in the right direction.

In principle this does not sound difficult to achieve but easy problems have been known to turn out to be hard.

The pot will start in a known position, probably the centre of its travel so in setup() you read the pot position and move the servo to the corresponding position at full speed. Each time through loop() you read the pot position and if it has changed significantly you set a boolean to true which flags the fact that the servo should move and save the target servo position based on the current pot position.

Later in loop(), if the servo is flagged as currently moving you derive the direction of movement based on the current servo position and the target servo position. If the servo is at the target position or not significantly far away then you set the boolean to false. Otherwise you move the servo one step towards the target position and save the new position as the current position.

Now for a crucial part of the code. Do not move the servo again unless a period of time has elapsed but use millis() to determine that the period has elapsed. Do not use delay() as it will block the running of the program.

If you are not familiar with the use of millis() for timing then read Using millis() for timing. A beginners guide, Several things at the same time and look at the BlinkWithoutDelay example in the IDE.