Making smooth servo movements on model railway

God morning! As a member of the Swedish non-profit model railway association "TågCentralen" I am now taking my first step into the Arduino world, trying to make grossing gates close/open. Have just been programming PHP/HTML before.

I have read and used this excellent Several things... guide and getting the main concepts of moving a servo from one position if a signal is given (and not bouncing).

My project I am using millis to set the speed (millis between each step) and degree per step. I use som if-queries to control if the gate shall be open or closed or is moving. However I do not get the smoothness I am looking for, and the reason I did post my issue here is because maybe it is not related to programming but to hardware and other, so this is my setup:

  • Arduino Nano, bought in oktober 2018.
  • USB-power supply from computer (while developing)
  • External power supply Mean Well LRS-50-5, grounds connected with above components.
  • 1 x Servo SG90.
  • Some small leds and resistors

This is the smoothness I would like: https://youtu.be/yHkUpmoC-9s?t=30

This is how it looks when I run the "Several things..." code. Link to movie on Dropbox

This is how it looks with my modified code. The modification is some if-queries and more. The timings are unchanged. No "delay()". Link to Dropbox-movie (modified code)

So my idea was that the if-queries are slowing it down? Maybe it is a obvius problem for an experienced programmer?

(If needed of course I provide the code here and change it to another forum section.)

Thanks in advance for any ideas and thoughts! :)

I can't see your code. Have I missed something obvious?

I cannot see you code, but are you using servo.write()? If so, consider using servo.writeMicroseconds() It gives finer granularity.

Please post your videos on YouTube so we don't have to download them.

I did download the first video but I can't see anything moving in it.

...R

Instead of controlling the output speed that way, have you tried lowering the voltage to the servo.

You do not say what the voltage is but I would imagine the servo should operate in a certain range, the lower end may just be enough. The load appears to be very small so it just might do the trick.

There are other options such as hacking the servo to allow a lower voltage to just the motor, or making your own servo (using the small internal circuit board) with a small dc motor and a worm drive gearbox and a position feedback pot on the rail gate mechanism,. Advantage here is the worm drive is very high torque and gear reduction.

Oh, another idea. Work on your physical configuration so that the movement of the gate uses (nearly) full travel of the servo. What is the range, open to close, of the signals that you are sending to the servo now? 90 degrees? If you change the physical range of movement so that you use closer to 180 degrees (or whatever the actual range of your servo is) then it will have more 'steps' to go though and each of those steps will be smaller.

But I would start with using writeMicroseconds(), since this gives a about 100o steps rather than about 180 steps when using servo.write().

For most realistic gate movement use a DC motor with gearbox and limit switches. That's all contained in the servo, what remains is to disconnect the motor control from the pot and let the Arduino handle the direction, speed and end of the move.

Thank you ALL for your answers! =)

As I said I am happy to provide the code (I could not insert the code because I exceeded 9000 characters).
Please see attached link.

However, when I today rewrote the code I was moving some functions (if-questions) from the out-commented function “void servo_closeGate()” to “void servoSweep()”. Then I put all code of “servo_closeGate()” within comments.
Then the gate it started to move smoother. And I just do not understand why…

Regarding my dropbox-movies I thought, when you click on the link, an online movie viewer shows up.

gates_2019_01_28.zip (13.3 KB)

I see that the servo control is based on servo.write() That has a maximum of 180 steps for a full sweep. Consider using servo.writeMicroseconds() for about 1000 steps. Finer granularity. Smother movement.

If commenting out one of your routines makes things run smoother, I wonder if the loop is taking a relatively long time to complete.

vinceherman: I see that the servo control is based on servo.write() That has a maximum of 180 steps for a full sweep. Consider using servo.writeMicroseconds() for about 1000 steps. Finer granularity. Smother movement.

I will try it out later, thanks! :)

vinceherman: If commenting out one of your routines makes things run smoother, I wonder if the loop is taking a relatively long time to complete.

What is "long time" in arduino world? I guess every function is taking up time. If you look at my code is it very long?

Thanks! :)

TagCentralen: What is "long time" in arduino world?

It is an an ambiguous description which why I called it 'relatively'. :) But it can be tested for.

Write a simpler version of the sketch that does much less. Like just moves the servo. Or just tests for a button push and then moves the servo. None of the other overhead. Can you make the servo move smoothly? If so, add back in some of the other functionality and test again. Is the servo still smooth or is it starting to misbehave.

This can be used to indicate possible causes of the bad behavior, possibly from a task that takes too long to complete or has some hardware conflict like timers. Then you (and we) can start looking for a way around that problem. Maybe you can offload the servo control to another device. Maybe you can offload the long task to another device. Maybe the other task can be optimized to not take so long.

In Reply #7 there is a 13k ZIP file. That implies a huge program. And I don't like downloading strange ZIP files.

I could make a servo move slowly in about 20 lines of code - see the demo Several Things at a Time

It is much easier to solve programming problems if different activities are developed in their own short special purpose functions. When the function is tested and works then just incorporate it into a bigger project.

...R Planning and Implementing a Program