Smooth movement with servos

One of the main problems of servos is that they move quite fast, as it can be seen in the video we included in Adding movement: servos .
With the setup I had imagined this was a problem. The camera has some non negligible weight and if we put something over the servo all of this can become unstable. See, for example:

Más pruebas #frikeando #voz #motores #raspi #c3po

A post shared by Fernando Tricas García (@ftricas) on

The solution for this problem is quite simple: when we want to move to a certain position, we can reach it by means of a set of small steps. We can indicate a set of succesive positions for the servo, each one a bit more close to the final destination. In this way, even with fast movements, the camera is more or less stable.

The code could be similar to the one we can see here:

def move(self, servo, pos, posIni=MIN, inc=10):

	servoGPIO=18
	servoGPIO=17
	posFin=posIni + (MAX-MIN)*pos
	steps=abs(posFin - posIni) / inc

	print "Pos ini", posIni
	print "Pos fin", posFin
	print "Steps", steps
	print int(steps)

	if pos < 0:
		pos = -pos
		sign = -1
	else:
		sign = 1

	for i in range(int(steps)):
		servo.set_servo(servoGPIO,posIni+10*i*sign)
		time.sleep(VEL)

	print "Pos ini", posIni
	print "Pos fin", posFin
	print "Steps", steps
	print int(steps)

	servo.stop_servo(servoGPIO)

That is, if we start at position (posIni) and we want to move a certain percentage of the available range (a real number between 0 and 1) we can compute the final position if we know the total range (MAX – MIN):


posFin=posIni + (MAX-MIN)*pos

And then, we can compute the needed steps to reach this destination; if we use increments of 10 (inc=10):


steps=abs(posFin - posIni) / inc

We are using the absolute value because the movement can be forward and backward (depending on the starting point for the movement). This is solved by means fo this conditional:


if pos < 0:
...

Finally, we use a for loop to reach the destination:

for i in range(int(steps)):
	servo.set_servo(servoGPIO,posIni+10*i*sign)
	time.sleep(VEL)

The result can be seen in the following video:

Montamos la cámara en el motor que se mueve más despacio #raspi

A post shared by Fernando Tricas García (@ftricas) on

There we can observe a forward and backward movements (to recover the initial position) with an improvised model.
The speed can be controlled with the time between steps (VEL value).

Maybe we should have chosen other type of motor, but we could solve the problem with this approach.

Adding movement: servos

Once we have a camera (or two) attached to our raspi helps us to discover one of the annoying limitations they have: they cannot move!
Fortunately, there are plenty of options for doing this. I decided to buy a couple of servos.

Motor #raspi

A post shared by Fernando Tricas García (@ftricas) on

They are cheap, small and noisy.

There are lots of pages explaining the theory behind their inner working so we only will remind here just a couple of things: they have some rotation constraints (the ones I bought can just move 180 degrees) and the way to control them is by sending some pulses whose duration determines the angle (for interested people, you can have a look at How do servos work? -in English- or at Trabajar con Servos -in Spanish-).

From our program our mission will be to find the way to send the adequate pulses to the selected pin where we have connected the servo (remember: physical world-computer connection).

There are lots of examples in the net.

For example, the programs : servo, servo2, servoYT, and servoYT2 are based on what we can see in the video Servo control using Raspberry pi (and also in this one Servo Control with the Raspberry Pi).

As usual, we are commenting on the main steps here, following the third program.

First the python modules that we need:

import RPi.GPIO as GPIO
import time

The first one is used for sending instructions through the pins to our raspi. The second one is for managing time related data.

Now, some setup: we will make reference to the pins by their number and we configure the 11 pin as output.

GPIO.setmode(GPIO.BOARD)

GPIO.setup(11,GPIO.OUT)

Now, we are going to define the controller with a frequency of 50Hz and we’ll start it in the central position:

p = GPIO.PWM(11,50)

p.start(7.5)

Finally, a bit more of code changing the position each second:

try:
    while True:
        print "Uno"
        p.ChangeDutyCycle(7.5)
        time.sleep(1)
        print "Dos"
        p.ChangeDutyCycle(12.5)
        time.sleep(1)
        print "Tres"
        p.ChangeDutyCycle(2.5)
        time.sleep(1)

That is, it starts at the central position and moves to both extremes. From the center it goes to one side, then to the contrary one and finally it returns to the initial position. You can see this movements in the following video:


By the end of the video you can see that we can control more than one servo (with the only limitation of the number of available pins). The code for this can be seen at:
servoYT2).
We have added pin number 12 and we use two controllers (p1 and p2). Then, we just send instructions to each one in sequence. You can have a look at this mini-video:

Dos motores #raspi

A post shared by Fernando Tricas García (@ftricas) on

We will see soon how to manage all the parts we have commented until now in order to finish the project.

This post has been posted originally in Spanish at: Añadiendo movimiento: servos.