MaixPy #4: Maixduino Pan-Tilt Servo Control | PWM MicroPython

Tilting is a cinematographic technique in which the camera stays in a fixed position but rotates up and down in a vertical plane. Tilting the camera results in a motion similar to that of someone raising or lowering their head to look up or down. [1]

In cinematography and photography, Panning means swivelling a still or video camera horizontally from a fixed position. This motion is similar to the motion of a person when they turn their head on their neck from left to right. [2]

Together, they form the pan-tilt set that can be used in various applications. One of them is face-tracking, which I am going to explore later in this series.

In this quick tutorial, I am going to control two servo motors in the pan-tilt configuration using the MaixPy IDE.

What Will We Need

 

Maixduino Pan Tilt Setup

Introduction

I bought this cheap Pan Tilt kit from Aliexpress and it is cool. It has some minor imperfections, and the fitting of the servos isn’t perfect, but with a bit of elbow grease, it all fits “perfectly”. I don’t know if I will be able to support the Maixduino, but for now I will be optimistic. I may have to make some calculations to verify the maximum load (weight?) that the servos can support.

In this configuration, we have to limit the motion of the servos if we don’t want the upper one to tilt and collide with the lower one. To achieve this effect, I limited the rotation to 90º (140-50), starting with 50º and ending with 140º.

Pan-Tilt Configuration Code

Most of the code has already been explained in another tutorial. If you want to understand the functions better, just click here (MaixPy #2: Maixduino Pulse Width Modulation (PWM)). The code bits that were added were as follows:

Created a new timer on a different channel to be used with the second servo (Tilt)

tim2 = Timer(Timer.TIMER0, Timer.CHANNEL1, mode=Timer.MODE_PWM)

Created a new servo object and assigned it to the PIN3 of the Maixduino

S2 = PWM(tim2, freq=50, duty=3, pin=board_info.PIN3)

Assigned to the new servo object, the duty cycle formula for the SG90 in the Servo function

S2.duty(((angle*9.45)/180)+2.95)

Created a for loop that makes the servos move in one direction with a 1º increment

for i in range (50,140,1)
  Servo (S1,i)
  Servo (S2,i)
Created a for loop that makes the servos move in the other direction with a -1º increment 
for i in range (50,140,-1)
  Servo (S1,i)
  Servo (S2,i)

And finally, printed the values on the serial terminal, in degrees, for us to see

Print ('Degrees:', i)

For loop in Python (Extra)

  • To loop through a set of code a specified number of times, we can use the range() function.
  • The range() function defaults to increment the sequence by 1, however it is possible to specify the increment value by adding a third parameter: range(Start, Stop, 3 (increment)):
# Numbers from 10 to 15
start = 10
stop = 50
step = 5 for i in range(10, 50, 5):
  print(i, end=' ')
#Output 10 15 20 25 30 35 40 45

 

Circuit

Considerations about the circuit:

  • Use an external power supply to power the servos; the Maixduino works at 3.3V and has limited current output
  • The ground wires have to be all connected (Maixduino+Power supply)
  • Pin2: Pan servo
  • Pin3: Tilt servo

Final Code

This is the final code. It can also be downloaded at the end of the post (Materials section). It works reasonably well, but there is still a problem when we power up the servos. They go very fast to the zero position, and I haven’t figured out yet how to solve it.

'''
Experiment Name: Pan Tilt Servo Control
Version: v1.0
Date: 2022.03
Author: 01Studio [www.01Studio.org]
Changed by: TiagoTech [www.tiagotech.com]
Description: Control two servos to rotate to different angles in a range
'''

from  machine  import  Timer , PWM
from board import board_info
from fpioa_manager import fm
import  time

#PWM is configured through the timer and connected to the IO21 pin (Pin2 Maixduino Board)
tim  =  Timer ( Timer . TIMER0 , Timer . CHANNEL0 , mode = Timer . MODE_PWM )
tim2  =  Timer ( Timer . TIMER0 , Timer . CHANNEL1 , mode = Timer . MODE_PWM )
S1 = PWM(tim, freq=50, duty=3, pin=board_info.PIN2)
S2 = PWM(tim2, freq=50, duty=3, pin=board_info.PIN3)

def  Servo ( servo , angle ):
    S1.duty(((angle*9.45)/180)+2.95)
    S2.duty(((angle*9.45)/180)+2.95)
    time.sleep(0.03)
    #time.sleep(0.2)
while True:
    for i in range (50,140,1):
        Servo ( S1 , i )
        Servo ( S2 , i )
        print('Degrees:', i)
    for i in range (140,50,-1):
        Servo ( S1 , i )
        Servo ( S2 , i )
        print('Degrees:', i)


 

Maixduino Experiment Materials

References

[1] https://en.wikipedia.org/wiki/Tilt_(camera)

[2] https://en.wikipedia.org/wiki/Panning_(camera)

[3] https://wiki.sipeed.com/soft/maixpy/en/

[4] https://www.w3schools.com/python/python_for_loops.asp

[5] https://pynative.com/python-range-function/